gtk2/gtk/gtkfontchooserdialog.c
Matthias Clasen ee75bae8f8 fontchooser: Make sure the tweak button is updated
This was showing up as tweak buttons being visible
when they should not. The code probably relied on
widgets being hidden by default (as they were in
GTK3).
2020-09-20 10:59:37 -04:00

323 lines
10 KiB
C

/* GTK - The GIMP Toolkit
* Copyright (C) 2011 Alberto Ruiz <aruiz@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <stdlib.h>
#include <glib/gprintf.h>
#include <string.h>
#include "gtkfontchooserdialog.h"
#include "gtkfontchooser.h"
#include "gtkfontchooserwidget.h"
#include "gtkfontchooserwidgetprivate.h"
#include "gtkfontchooserutils.h"
#include "gtkbox.h"
#include "gtkintl.h"
#include "gtkbuildable.h"
#include "gtkprivate.h"
#include "gtkwidget.h"
#include "gtksettings.h"
#include "gtkdialogprivate.h"
#include "gtktogglebutton.h"
#include "gtkheaderbar.h"
#include "gtkactionable.h"
#include "gtkeventcontrollerkey.h"
typedef struct _GtkFontChooserDialogClass GtkFontChooserDialogClass;
struct _GtkFontChooserDialog
{
GtkDialog parent_instance;
GtkWidget *fontchooser;
GtkWidget *select_button;
GtkWidget *cancel_button;
GtkWidget *tweak_button;
};
struct _GtkFontChooserDialogClass
{
GtkDialogClass parent_class;
};
/**
* SECTION:gtkfontchooserdialog
* @Short_description: A dialog for selecting fonts
* @Title: GtkFontChooserDialog
* @See_also: #GtkFontChooser, #GtkDialog
*
* The #GtkFontChooserDialog widget is a dialog for selecting a font.
* It implements the #GtkFontChooser interface.
*
* # GtkFontChooserDialog as GtkBuildable
*
* The GtkFontChooserDialog implementation of the #GtkBuildable
* interface exposes the buttons with the names “select_button”
* and “cancel_button”.
*/
static void gtk_font_chooser_dialog_buildable_interface_init (GtkBuildableIface *iface);
static GObject *gtk_font_chooser_dialog_buildable_get_internal_child (GtkBuildable *buildable,
GtkBuilder *builder,
const char *childname);
G_DEFINE_TYPE_WITH_CODE (GtkFontChooserDialog, gtk_font_chooser_dialog, GTK_TYPE_DIALOG,
G_IMPLEMENT_INTERFACE (GTK_TYPE_FONT_CHOOSER,
_gtk_font_chooser_delegate_iface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_font_chooser_dialog_buildable_interface_init))
static GtkBuildableIface *parent_buildable_iface;
static void
gtk_font_chooser_dialog_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkFontChooserDialog *dialog = GTK_FONT_CHOOSER_DIALOG (object);
switch (prop_id)
{
default:
g_object_set_property (G_OBJECT (dialog->fontchooser), pspec->name, value);
break;
}
}
static void
gtk_font_chooser_dialog_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkFontChooserDialog *dialog = GTK_FONT_CHOOSER_DIALOG (object);
switch (prop_id)
{
default:
g_object_get_property (G_OBJECT (dialog->fontchooser), pspec->name, value);
break;
}
}
static void
font_activated_cb (GtkFontChooser *fontchooser,
const char *fontname,
gpointer user_data)
{
GtkDialog *dialog = user_data;
gtk_dialog_response (dialog, GTK_RESPONSE_OK);
}
static gboolean
dialog_forward_key (GtkEventControllerKey *controller,
guint keyval,
guint keycode,
GdkModifierType modifiers,
GtkWidget *widget)
{
GtkFontChooserDialog *dialog = GTK_FONT_CHOOSER_DIALOG (widget);
return gtk_event_controller_key_forward (controller, dialog->fontchooser);
}
static void
update_tweak_button (GtkFontChooserDialog *dialog)
{
GtkFontChooserLevel level;
if (!dialog->tweak_button)
return;
g_object_get (dialog->fontchooser, "level", &level, NULL);
if ((level & (GTK_FONT_CHOOSER_LEVEL_FEATURES | GTK_FONT_CHOOSER_LEVEL_VARIATIONS)) != 0)
gtk_widget_show (dialog->tweak_button);
else
gtk_widget_hide (dialog->tweak_button);
}
static void
setup_tweak_button (GtkFontChooserDialog *dialog)
{
gboolean use_header;
if (dialog->tweak_button)
return;
g_object_get (dialog, "use-header-bar", &use_header, NULL);
if (use_header)
{
GtkWidget *button;
GtkWidget *header;
GActionGroup *actions;
actions = G_ACTION_GROUP (g_simple_action_group_new ());
g_action_map_add_action (G_ACTION_MAP (actions), gtk_font_chooser_widget_get_tweak_action (dialog->fontchooser));
gtk_widget_insert_action_group (GTK_WIDGET (dialog), "font", actions);
g_object_unref (actions);
button = gtk_toggle_button_new ();
gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "font.tweak");
gtk_widget_set_focus_on_click (button, FALSE);
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_button_set_icon_name (GTK_BUTTON (button), "emblem-system-symbolic");
header = gtk_dialog_get_header_bar (GTK_DIALOG (dialog));
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
dialog->tweak_button = button;
update_tweak_button (dialog);
}
}
static void
gtk_font_chooser_dialog_map (GtkWidget *widget)
{
GtkFontChooserDialog *dialog = GTK_FONT_CHOOSER_DIALOG (widget);
setup_tweak_button (dialog);
GTK_WIDGET_CLASS (gtk_font_chooser_dialog_parent_class)->map (widget);
}
static void
update_button (GtkFontChooserDialog *dialog)
{
PangoFontDescription *desc;
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (dialog->fontchooser));
gtk_widget_set_sensitive (dialog->select_button, desc != NULL);
if (desc)
pango_font_description_free (desc);
}
static void
gtk_font_chooser_dialog_dispose (GObject *object)
{
GtkFontChooserDialog *dialog = GTK_FONT_CHOOSER_DIALOG (object);
if (dialog->fontchooser)
{
g_signal_handlers_disconnect_by_func (dialog->fontchooser,
update_button,
dialog);
g_signal_handlers_disconnect_by_func (dialog->fontchooser,
update_tweak_button,
dialog);
}
g_clear_pointer (&dialog->select_button, gtk_widget_unparent);
g_clear_pointer (&dialog->cancel_button, gtk_widget_unparent);
g_clear_pointer (&dialog->tweak_button, gtk_widget_unparent);
g_clear_pointer (&dialog->fontchooser, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_font_chooser_dialog_parent_class)->dispose (object);
}
static void
gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gobject_class->dispose = gtk_font_chooser_dialog_dispose;
gobject_class->get_property = gtk_font_chooser_dialog_get_property;
gobject_class->set_property = gtk_font_chooser_dialog_set_property;
widget_class->map = gtk_font_chooser_dialog_map;
_gtk_font_chooser_install_properties (gobject_class);
/* Bind class to template
*/
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/libgtk/ui/gtkfontchooserdialog.ui");
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserDialog, fontchooser);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserDialog, select_button);
gtk_widget_class_bind_template_child (widget_class, GtkFontChooserDialog, cancel_button);
gtk_widget_class_bind_template_callback (widget_class, font_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, dialog_forward_key);
}
static void
gtk_font_chooser_dialog_init (GtkFontChooserDialog *dialog)
{
gtk_widget_init_template (GTK_WIDGET (dialog));
gtk_dialog_set_use_header_bar_from_setting (GTK_DIALOG (dialog));
_gtk_font_chooser_set_delegate (GTK_FONT_CHOOSER (dialog),
GTK_FONT_CHOOSER (dialog->fontchooser));
g_signal_connect_swapped (dialog->fontchooser, "notify::font-desc",
G_CALLBACK (update_button), dialog);
update_button (dialog);
g_signal_connect_swapped (dialog->fontchooser, "notify::level",
G_CALLBACK (update_tweak_button), dialog);
}
/**
* gtk_font_chooser_dialog_new:
* @title: (allow-none): Title of the dialog, or %NULL
* @parent: (allow-none): Transient parent of the dialog, or %NULL
*
* Creates a new #GtkFontChooserDialog.
*
* Returns: a new #GtkFontChooserDialog
*/
GtkWidget*
gtk_font_chooser_dialog_new (const char *title,
GtkWindow *parent)
{
GtkFontChooserDialog *dialog;
dialog = g_object_new (GTK_TYPE_FONT_CHOOSER_DIALOG,
"title", title,
"transient-for", parent,
NULL);
return GTK_WIDGET (dialog);
}
static void
gtk_font_chooser_dialog_buildable_interface_init (GtkBuildableIface *iface)
{
parent_buildable_iface = g_type_interface_peek_parent (iface);
iface->get_internal_child = gtk_font_chooser_dialog_buildable_get_internal_child;
}
static GObject *
gtk_font_chooser_dialog_buildable_get_internal_child (GtkBuildable *buildable,
GtkBuilder *builder,
const char *childname)
{
GtkFontChooserDialog *dialog = GTK_FONT_CHOOSER_DIALOG (buildable);
if (g_strcmp0 (childname, "select_button") == 0)
return G_OBJECT (dialog->select_button);
else if (g_strcmp0 (childname, "cancel_button") == 0)
return G_OBJECT (dialog->cancel_button);
return parent_buildable_iface->get_internal_child (buildable, builder, childname);
}