diff options
-rw-r--r-- | docs/reference/gtk/gtk3-sections.txt | 33 | ||||
-rw-r--r-- | docs/reference/gtk/gtk3.types | 3 | ||||
-rw-r--r-- | gtk/Makefile.am | 5 | ||||
-rw-r--r-- | gtk/gtk.h | 1 | ||||
-rw-r--r-- | gtk/gtk.symbols | 6 | ||||
-rw-r--r-- | gtk/gtkfontbutton.c | 17 | ||||
-rw-r--r-- | gtk/gtkfontchooser.c | 1197 | ||||
-rw-r--r-- | gtk/gtkfontchooser.h | 122 | ||||
-rw-r--r-- | gtk/gtkfontchooserdialog.c | 190 | ||||
-rw-r--r-- | gtk/gtkfontchooserdialog.h | 9 | ||||
-rw-r--r-- | gtk/gtkfontchooserprivate.h | 35 | ||||
-rw-r--r-- | gtk/gtkfontchooserutils.c | 186 | ||||
-rw-r--r-- | gtk/gtkfontchooserutils.h | 53 | ||||
-rw-r--r-- | gtk/gtkfontchooserwidget.c | 1198 | ||||
-rw-r--r-- | gtk/gtkfontchooserwidget.h | 71 | ||||
-rw-r--r-- | tests/testfontchooser.c | 2 |
16 files changed, 1778 insertions, 1350 deletions
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt index 63b0941276..6507540af5 100644 --- a/docs/reference/gtk/gtk3-sections.txt +++ b/docs/reference/gtk/gtk3-sections.txt @@ -1480,7 +1480,6 @@ gtk_font_selection_dialog_get_type <FILE>gtkfontchooser</FILE> <TITLE>GtkFontChooser</TITLE> GtkFontChooser -gtk_font_chooser_new gtk_font_chooser_get_family gtk_font_chooser_get_face gtk_font_chooser_get_size @@ -1494,17 +1493,32 @@ GtkFontFilterFunc gtk_font_chooser_set_filter_func <SUBSECTION Standard> -GtkFontChooserClass +GtkFontChooserIface GTK_TYPE_FONT_CHOOSER GTK_FONT_CHOOSER -GTK_FONT_CHOOSER_CLASS +GTK_FONT_CHOOSER_IFACE GTK_IS_FONT_CHOOSER -GTK_IS_FONT_CHOOSER_CLASS -GTK_FONT_CHOOSER_GET_CLASS +GTK_IS_FONT_CHOOSER_IFACE +GTK_FONT_CHOOSER_GET_IFACE +</SECTION> + +<SECTION> +<FILE>gtkfontchooserwidget</FILE> +<TITLE>GtkFontChooserWidget</TITLE> +GtkFontChooserWidget + +<SUBSECTION Standard> +GtkFontChooserWidgetClass +GTK_TYPE_FONT_CHOOSER_WIDGET +GTK_FONT_CHOOSER_WIDGET +GTK_FONT_CHOOSER_WIDGET_CLASS +GTK_IS_FONT_CHOOSER_WIDGET +GTK_IS_FONT_CHOOSER_WIDGET_CLASS +GTK_FONT_CHOOSER_WIDGET_GET_CLASS <SUBSECTION Private> -GtkFontChooserPrivate -gtk_font_chooser_get_type +GtkFontChooserWidgetPrivate +gtk_font_chooser_widget_get_type </SECTION> <SECTION> @@ -1512,11 +1526,6 @@ gtk_font_chooser_get_type <TITLE>GtkFontChooserDialog</TITLE> GtkFontChooserDialog gtk_font_chooser_dialog_new -gtk_font_chooser_dialog_get_font_chooser -gtk_font_chooser_dialog_get_font_name -gtk_font_chooser_dialog_set_font_name -gtk_font_chooser_dialog_get_preview_text -gtk_font_chooser_dialog_set_preview_text <SUBSECTION Standard> GtkFontChooserDialogClass diff --git a/docs/reference/gtk/gtk3.types b/docs/reference/gtk/gtk3.types index d0190b7057..1c14c49824 100644 --- a/docs/reference/gtk/gtk3.types +++ b/docs/reference/gtk/gtk3.types @@ -66,6 +66,9 @@ gtk_file_chooser_widget_get_type gtk_file_filter_get_type gtk_fixed_get_type gtk_font_button_get_type +gtk_font_chooser_get_type +gtk_font_chooser_dialog_get_type +gtk_font_chooser_widget_get_type gtk_font_selection_dialog_get_type gtk_font_selection_get_type gtk_frame_get_type diff --git a/gtk/Makefile.am b/gtk/Makefile.am index a49803305a..8a11903b2d 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -221,6 +221,7 @@ gtk_public_h_sources = \ gtkfontsel.h \ gtkfontchooser.h \ gtkfontchooserdialog.h \ + gtkfontchooserwidget.h \ gtkframe.h \ gtkgradient.h \ gtkgrid.h \ @@ -408,6 +409,8 @@ gtk_private_h_sources = \ gtkfilechooserutils.h \ gtkfilesystem.h \ gtkfilesystemmodel.h \ + gtkfontchooserprivate.h \ + gtkfontchooserutils.h \ gtkiconcache.h \ gtkimageprivate.h \ gtkimcontextsimpleseqs.h \ @@ -555,6 +558,8 @@ gtk_base_c_sources = \ gtkfontsel.c \ gtkfontchooser.c \ gtkfontchooserdialog.c \ + gtkfontchooserutils.c \ + gtkfontchooserwidget.c \ gtkframe.c \ gtkgradient.c \ gtkgrid.c \ @@ -104,6 +104,7 @@ #include <gtk/gtkfontsel.h> #include <gtk/gtkfontchooser.h> #include <gtk/gtkfontchooserdialog.h> +#include <gtk/gtkfontchooserwidget.h> #include <gtk/gtkframe.h> #include <gtk/gtkgradient.h> #include <gtk/gtkgrid.h> diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 3624280116..0be971c562 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -1047,9 +1047,6 @@ gtk_font_button_set_show_style gtk_font_button_set_title gtk_font_button_set_use_font gtk_font_button_set_use_size -gtk_font_chooser_dialog_get_font_chooser -gtk_font_chooser_dialog_get_font_name -gtk_font_chooser_dialog_get_preview_text gtk_font_chooser_dialog_get_type gtk_font_chooser_dialog_new gtk_font_chooser_dialog_set_font_name @@ -1061,11 +1058,12 @@ gtk_font_chooser_get_preview_text gtk_font_chooser_get_show_preview_entry gtk_font_chooser_get_size gtk_font_chooser_get_type -gtk_font_chooser_new gtk_font_chooser_set_filter_func gtk_font_chooser_set_font_name gtk_font_chooser_set_preview_text gtk_font_chooser_set_show_preview_entry +gtk_font_chooser_widget_get_type +gtk_font_chooser_widget_new gtk_font_selection_dialog_get_cancel_button gtk_font_selection_dialog_get_font_name gtk_font_selection_dialog_get_font_selection diff --git a/gtk/gtkfontbutton.c b/gtk/gtkfontbutton.c index 0d195d397f..67a9ef3363 100644 --- a/gtk/gtkfontbutton.c +++ b/gtk/gtkfontbutton.c @@ -33,6 +33,7 @@ #include "gtkmain.h" #include "gtkbox.h" #include "gtklabel.h" +#include "gtkfontchooser.h" #include "gtkfontchooserdialog.h" #include "gtkimage.h" #include "gtkmarshalers.h" @@ -689,8 +690,8 @@ gtk_font_button_set_font_name (GtkFontButton *font_button, gtk_font_button_update_font_info (font_button); if (font_button->priv->font_dialog) - result = gtk_font_chooser_dialog_set_font_name (GTK_FONT_CHOOSER_DIALOG (font_button->priv->font_dialog), - font_button->priv->fontname); + result = gtk_font_chooser_set_font_name (GTK_FONT_CHOOSER (font_button->priv->font_dialog), + font_button->priv->fontname); else result = FALSE; @@ -702,8 +703,8 @@ gtk_font_button_set_font_name (GtkFontButton *font_button, static void gtk_font_button_clicked (GtkButton *button) { - GtkFontChooserDialog *font_dialog; - GtkFontButton *font_button = GTK_FONT_BUTTON (button); + GtkFontChooser *font_dialog; + GtkFontButton *font_button = GTK_FONT_BUTTON (button); if (!font_button->priv->font_dialog) { @@ -714,7 +715,7 @@ gtk_font_button_clicked (GtkButton *button) font_button->priv->font_dialog = gtk_font_chooser_dialog_new (font_button->priv->title, NULL); - font_dialog = GTK_FONT_CHOOSER_DIALOG (font_button->priv->font_dialog); + font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog); if (gtk_widget_is_toplevel (parent) && GTK_IS_WINDOW (parent)) { @@ -734,8 +735,8 @@ gtk_font_button_clicked (GtkButton *button) if (!gtk_widget_get_visible (font_button->priv->font_dialog)) { - font_dialog = GTK_FONT_CHOOSER_DIALOG (font_button->priv->font_dialog); - gtk_font_chooser_dialog_set_font_name (font_dialog, font_button->priv->fontname); + font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog); + gtk_font_chooser_set_font_name (font_dialog, font_button->priv->fontname); } gtk_window_present (GTK_WINDOW (font_button->priv->font_dialog)); @@ -754,7 +755,7 @@ response_cb (GtkDialog *dialog, return; g_free (font_button->priv->fontname); - font_button->priv->fontname = gtk_font_chooser_dialog_get_font_name (GTK_FONT_CHOOSER_DIALOG (font_button->priv->font_dialog)); + font_button->priv->fontname = gtk_font_chooser_get_font_name (GTK_FONT_CHOOSER (font_button->priv->font_dialog)); /* Set label font */ gtk_font_button_update_font_info (font_button); diff --git a/gtk/gtkfontchooser.c b/gtk/gtkfontchooser.c index 1d48016a38..66944dc1a3 100644 --- a/gtk/gtkfontchooser.c +++ b/gtk/gtkfontchooser.c @@ -1,4 +1,7 @@ /* GTK - The GIMP Toolkit + * gtkfontchooser.c - Abstract interface for font file selectors GUIs + * + * Copyright (C) 2006, Emmanuele Bassi * Copyright (C) 2011 Alberto Ruiz <aruiz@gnome.org> * * This library is free software; you can redistribute it and/or @@ -19,189 +22,66 @@ #include "config.h" -#include <stdlib.h> -#include <glib/gprintf.h> -#include <string.h> - -#include <atk/atk.h> - #include "gtkfontchooser.h" -#include "gtkcellrenderertext.h" -#include "gtkentry.h" -#include "gtkframe.h" -#include "gtkbbox.h" -#include "gtkbox.h" -#include "gtklabel.h" -#include "gtkliststore.h" -#include "gtkstock.h" -#include "gtktextview.h" -#include "gtktreeselection.h" -#include "gtktreeview.h" -#include "gtkscrolledwindow.h" +#include "gtkfontchooserprivate.h" #include "gtkintl.h" -#include "gtkaccessible.h" -#include "gtkbuildable.h" +#include "gtktypebuiltins.h" #include "gtkprivate.h" -#include "gtkscale.h" -#include "gtkspinbutton.h" -#include "gtknotebook.h" -#include "gtkwidget.h" -#include "gtkgrid.h" /** * SECTION:gtkfontchooser - * @Short_description: A widget for selecting fonts + * @Short_description: Interface implemented by widgets displaying fonts * @Title: GtkFontChooser - * @See_also: #GtkFontChooserDialog - * - * The #GtkFontChooser widget lists the available fonts, styles and sizes, - * allowing the user to select a font. - * It is used in the #GtkFontChooserDialog widget to provide a dialog box for - * selecting fonts. - * - * To set the font which is initially selected, use - * gtk_font_chooser_set_font_name(). + * @See_also: #GtkFontChooserDialog, #GtkFontChooserWidget, #GtkFontButton * - * To get the selected font use gtk_font_chooser_get_font_name(). - * - * To change the text which is shown in the preview area, use - * gtk_font_chooser_set_preview_text(). + * #GtkFontChooser is an interface that can be implemented by widgets + * displaying the list of fonts. In GTK+, the main objects + * that implement this interface are #GtkFontChooserWidget, + * #GtkFontChooserDialog and #GtkFontButton. * * Since: 3.2 */ - -struct _GtkFontChooserPrivate +enum { - GtkWidget *search_entry; - GtkWidget *family_face_list; - GtkWidget *list_scrolled_window; - GtkWidget *empty_list; - GtkWidget *list_notebook; - GtkListStore *model; - GtkTreeModel *filter_model; - - GtkWidget *preview; - gchar *preview_text; - gboolean show_preview_entry; - - GtkWidget *size_spin; - GtkWidget *size_slider; - - gchar *fontname; - gint size; - PangoFontFace *face; - PangoFontFamily *family; - - gulong cursor_changed_handler; - - GtkFontFilterFunc filter_func; - gpointer filter_data; - GDestroyNotify filter_data_destroy; -}; - -#define DEFAULT_FONT_NAME "Sans 10" -#define MAX_FONT_SIZE 999 - -/* This is the initial fixed height and the top padding of the preview entry */ -#define PREVIEW_HEIGHT 72 -#define PREVIEW_TOP_PADDING 6 - -/* These are the sizes of the font, style & size lists. */ -#define FONT_LIST_HEIGHT 136 -#define FONT_LIST_WIDTH 190 -#define FONT_STYLE_LIST_WIDTH 170 -#define FONT_SIZE_LIST_WIDTH 60 - -#define ROW_FORMAT_STRING "<span weight=\"bold\" size=\"small\">%s</span>\n<span size=\"x-large\" font_desc=\"%s\">%s</span>" - -#define NO_FONT_MATCHED_SEARCH N_("No fonts matched your search. You can revise your search and try again.") - -/* These are what we use as the standard font sizes, for the size list. - */ -static const gint font_sizes[] = { - 6, 8, 9, 10, 11, 12, 13, 14, 16, 20, 24, 36, 48, 72 -}; - -enum { - PROP_0, - PROP_FONT_NAME, - PROP_PREVIEW_TEXT, - PROP_SHOW_PREVIEW_ENTRY -}; - - -enum { - FAMILY_COLUMN, - FACE_COLUMN, - PREVIEW_TEXT_COLUMN, - PREVIEW_TITLE_COLUMN -}; - -enum { SIGNAL_FONT_ACTIVATED, - N_SIGNALS + LAST_SIGNAL }; -static guint signals[N_SIGNALS] = { 0, }; - -static void gtk_font_chooser_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_font_chooser_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gtk_font_chooser_finalize (GObject *object); -static void gtk_font_chooser_dispose (GObject *object); +static guint chooser_signals[LAST_SIGNAL]; -static void gtk_font_chooser_screen_changed (GtkWidget *widget, - GdkScreen *previous_screen); -static void gtk_font_chooser_style_updated (GtkWidget *widget); - -static void gtk_font_chooser_bootstrap_fontlist (GtkFontChooser *fontchooser); - -static gboolean gtk_font_chooser_select_font_name (GtkFontChooser *fontchooser); +#define DEFAULT_FONT_NAME "Sans 10" +#define MAX_FONT_SIZE 999 -G_DEFINE_TYPE (GtkFontChooser, gtk_font_chooser, GTK_TYPE_BOX) +typedef GtkFontChooserIface GtkFontChooserInterface; +G_DEFINE_INTERFACE (GtkFontChooser, gtk_font_chooser, G_TYPE_OBJECT); static void -gtk_font_chooser_class_init (GtkFontChooserClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - widget_class->screen_changed = gtk_font_chooser_screen_changed; - widget_class->style_updated = gtk_font_chooser_style_updated; - - gobject_class->dispose = gtk_font_chooser_dispose; - gobject_class->finalize = gtk_font_chooser_finalize; - gobject_class->set_property = gtk_font_chooser_set_property; - gobject_class->get_property = gtk_font_chooser_get_property; - - g_object_class_install_property (gobject_class, - PROP_FONT_NAME, - g_param_spec_string ("font-name", - P_("Font name"), - P_("The string that represents this font"), - DEFAULT_FONT_NAME, - GTK_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - PROP_PREVIEW_TEXT, - g_param_spec_string ("preview-text", - P_("Preview text"), - P_("The text to display in order to demonstrate the selected font"), - pango_language_get_sample_string (NULL), - GTK_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, - PROP_SHOW_PREVIEW_ENTRY, - g_param_spec_boolean ("show-preview-entry", - P_("Show preview text entry"), - P_("Whether the preview text entry is shown or not"), - TRUE, - GTK_PARAM_READWRITE)); +gtk_font_chooser_default_init (GtkFontChooserInterface *iface) +{ + g_object_interface_install_property + (iface, + g_param_spec_string ("font-name", + P_("Font name"), + P_("The string that represents this font"), + DEFAULT_FONT_NAME, + GTK_PARAM_READWRITE)); + + g_object_interface_install_property + (iface, + g_param_spec_string ("preview-text", + P_("Preview text"), + P_("The text to display in order to demonstrate the selected font"), + pango_language_get_sample_string (NULL), + GTK_PARAM_READWRITE)); + + g_object_interface_install_property + (iface, + g_param_spec_boolean ("show-preview-entry", + P_("Show preview text entry"), + P_("Whether the preview text entry is shown or not"), + TRUE, + GTK_PARAM_READWRITE)); /** * GtkFontChooserWidget::font-activated: @@ -212,803 +92,16 @@ gtk_font_chooser_class_init (GtkFontChooserClass *klass) * This usually happens when the user double clicks an item, * or an item is selected and the user presses one of the keys * Space, Shift+Space, Return or Enter. - */ - signals[SIGNAL_FONT_ACTIVATED] = + */ + chooser_signals[SIGNAL_FONT_ACTIVATED] = g_signal_new ("font-activated", GTK_TYPE_FONT_CHOOSER, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkFontChooserClass, font_activated), + G_STRUCT_OFFSET (GtkFontChooserIface, font_activated), NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING); - - g_type_class_add_private (klass, sizeof (GtkFontChooserPrivate)); -} - -static void -gtk_font_chooser_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkFontChooser *fontchooser; - - fontchooser = GTK_FONT_CHOOSER (object); - - switch (prop_id) - { - case PROP_FONT_NAME: - gtk_font_chooser_set_font_name (fontchooser, g_value_get_string (value)); - break; - case PROP_PREVIEW_TEXT: - gtk_font_chooser_set_preview_text (fontchooser, g_value_get_string (value)); - break; - case PROP_SHOW_PREVIEW_ENTRY: - gtk_font_chooser_set_show_preview_entry (fontchooser, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_font_chooser_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtkFontChooser *fontchooser; - - fontchooser = GTK_FONT_CHOOSER (object); - - switch (prop_id) - { - case PROP_FONT_NAME: - g_value_take_string (value, gtk_font_chooser_get_font_name (fontchooser)); - break; - case PROP_PREVIEW_TEXT: - g_value_set_string (value, gtk_font_chooser_get_preview_text (fontchooser)); - break; - case PROP_SHOW_PREVIEW_ENTRY: - g_value_set_boolean (value, gtk_font_chooser_get_show_preview_entry (fontchooser)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -text_changed_cb (GtkEntry *entry, - GParamSpec *pspec, - GtkFontChooser *fc) -{ - GtkFontChooserPrivate *priv = fc->priv; - const gchar *text; - - text = gtk_entry_get_text (entry); - - if (text == NULL || text[0] == '\0') - { - GIcon *icon; - - icon = g_themed_icon_new_with_default_fallbacks ("edit-find-symbolic"); - g_object_set (G_OBJECT (priv->search_entry), - "secondary-icon-gicon", icon, - "secondary-icon-activatable", FALSE, - "secondary-icon-sensitive", FALSE, - NULL); - g_object_unref (icon); - } - else - { - if (!gtk_entry_get_icon_activatable (GTK_ENTRY (priv->search_entry), GTK_ENTRY_ICON_SECONDARY)) - { - GIcon *icon; - - icon = g_themed_icon_new_with_default_fallbacks ("edit-clear-symbolic"); - g_object_set (G_OBJECT (priv->search_entry), - "secondary-icon-gicon", icon, - "secondary-icon-activatable", TRUE, - "secondary-icon-sensitive", TRUE, - NULL); - g_object_unref (icon); - } - } - - gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model)); -} - -static void -icon_press_cb (GtkEntry *entry, - GtkEntryIconPosition pos, - GdkEvent *event, - gpointer user_data) -{ - gtk_entry_set_text (entry, ""); -} - -static void -slider_change_cb (GtkAdjustment *adjustment, - gpointer user_data) -{ - GtkFontChooser *fc = (GtkFontChooser*)user_data; - GtkFontChooserPrivate *priv = fc->priv; - GtkAdjustment *spin_adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON (priv->size_spin)); - gdouble slider_value = gtk_adjustment_get_value (adjustment); - gdouble spin_value = gtk_adjustment_get_value (spin_adj); - - if (slider_value != spin_value) - gtk_adjustment_set_value (spin_adj, - gtk_adjustment_get_value (adjustment)); -} - -static void -spin_change_cb (GtkAdjustment *adjustment, - gpointer user_data) -{ - PangoFontDescription *desc; - GtkFontChooser *fontchooser = (GtkFontChooser*)user_data; - GtkFontChooserPrivate *priv = fontchooser->priv; - GtkAdjustment *slider_adj = gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)); - - gdouble size = gtk_adjustment_get_value (adjustment); - priv->size = ((gint)size) * PANGO_SCALE; - - desc = pango_context_get_font_description (gtk_widget_get_pango_context (priv->preview)); - pango_font_description_set_size (desc, priv->size); - gtk_widget_override_font (priv->preview, desc); - - g_object_notify (G_OBJECT (fontchooser), "font-name"); - - /* If the new value is lower than the lower bound of the slider, we set - * the slider adjustment to the lower bound value if it is not already set - */ - if (size < gtk_adjustment_get_lower (slider_adj) && - gtk_adjustment_get_value (slider_adj) != gtk_adjustment_get_lower (slider_adj)) - gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_lower (slider_adj)); - - /* If the new value is upper than the upper bound of the slider, we set - * the slider adjustment to the upper bound value if it is not already set - */ - else if (size > gtk_adjustment_get_upper (slider_adj) && - gtk_adjustment_get_value (slider_adj) != gtk_adjustment_get_upper (slider_adj)) - gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_upper (slider_adj)); - - /* If the new value is not already set on the slider we set it */ - else if (size != gtk_adjustment_get_value (slider_adj)) - gtk_adjustment_set_value (slider_adj, size); - - gtk_widget_queue_draw (priv->preview); -} - -static void -set_range_marks (GtkFontChooserPrivate *priv, - GtkWidget *size_slider, - gint *sizes, - gint length) -{ - GtkAdjustment *adj; - gint i; - gdouble value; - - if (length < 2) - { - sizes = (gint*)font_sizes; - length = G_N_ELEMENTS (font_sizes); - } - - gtk_scale_clear_marks (GTK_SCALE (size_slider)); - - adj = gtk_range_get_adjustment(GTK_RANGE (size_slider)); - - gtk_adjustment_set_lower (adj, (gdouble) sizes[0]); - gtk_adjustment_set_upper (adj, (gdouble) sizes[length-1]); - - value = gtk_adjustment_get_value (adj); - if (value > (gdouble) sizes[length-1]) - gtk_adjustment_set_value (adj, (gdouble) sizes[length-1]); - else if (value < (gdouble) sizes[0]) - gtk_adjustment_set_value (adj, (gdouble) sizes[0]); - - for (i = 0; i < length; i++) - gtk_scale_add_mark (GTK_SCALE (size_slider), - (gdouble) sizes[i], - GTK_POS_BOTTOM, NULL); -} - -static void -row_activated_cb (GtkTreeView *view, - GtkTreePath *path, - GtkTreeViewColumn *column, - gpointer user_data) -{ - GtkFontChooser *self = user_data; - gchar *fontname; - - fontname = gtk_font_chooser_get_font_name (self); - - g_signal_emit (self, signals[SIGNAL_FONT_ACTIVATED], 0, fontname); - g_free (fontname); -} - -static void -cursor_changed_cb (GtkTreeView *treeview, - gpointer user_data) -{ - GtkFontChooser *fontchooser = (GtkFontChooser*)user_data; - GtkFontChooserPrivate *priv = fontchooser->priv; - - PangoFontFamily *family; - PangoFontFace *face; - PangoFontDescription *desc; - - gint *sizes; - gint i, n_sizes; - - GtkTreeIter iter; - GtkTreePath *path = gtk_tree_path_new (); - - gtk_tree_view_get_cursor (treeview, &path, NULL); - - if (!path) - return; - - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->filter_model), &iter, path)) - { - gtk_tree_path_free (path); - return; - } - - - gtk_tree_model_get (GTK_TREE_MODEL (priv->filter_model), &iter, - FACE_COLUMN, &face, - FAMILY_COLUMN, &family, - -1); - - gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.5, 0.5); - - gtk_tree_path_free (path); - path = NULL; - - if (face == NULL || family == NULL) - { - if (face) - g_object_unref (face); - if (family) - g_object_unref (family); - - return; - } - - desc = pango_font_face_describe (face); - pango_font_description_set_size (desc, priv->size); - gtk_widget_override_font (priv->preview, desc); - - pango_font_face_list_sizes (face, &sizes, &n_sizes); - /* It seems not many fonts actually have a sane set of sizes */ - for (i = 0; i < n_sizes; i++) - sizes[i] = sizes[i] / PANGO_SCALE; - - set_range_marks (priv, priv->size_slider, sizes, n_sizes); - - if (priv->family) - g_object_unref (priv->family); - priv->family = family; - - if (priv->face) - g_object_unref (priv->face); - priv->face = face; - - pango_font_description_free (desc); - - g_object_notify (G_OBJECT (fontchooser), "font-name"); -} - -static gboolean -zoom_preview_cb (GtkWidget *scrolled_window, - GdkEventScroll *event, - gpointer user_data) -{ - GtkFontChooser *fc = (GtkFontChooser*)user_data; - GtkFontChooserPrivate *priv = fc->priv; - - GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)); - - if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT) - gtk_adjustment_set_value (adj, - gtk_adjustment_get_value (adj) + - gtk_adjustment_get_step_increment (adj)); - else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT) - gtk_adjustment_set_value (adj, - gtk_adjustment_get_value (adj) - - gtk_adjustment_get_step_increment (adj)); - return TRUE; -} - -static void -row_inserted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data) -{ - GtkFontChooser *fontchooser = (GtkFontChooser*)user_data; - GtkFontChooserPrivate *priv = fontchooser->priv; - - gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->list_notebook), 0); -} - -static void -row_deleted_cb (GtkTreeModel *model, - GtkTreePath *path, - gpointer user_data) -{ - GtkFontChooser *fontchooser = (GtkFontChooser*)user_data; - GtkFontChooserPrivate *priv = fontchooser->priv; - - if (gtk_tree_model_iter_n_children (model, NULL) == 0) - gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->list_notebook), 1); -} - -static void -gtk_font_chooser_init (GtkFontChooser *fontchooser) -{ - GIcon *icon; - GtkFontChooserPrivate *priv; - PangoFontDescription *font_desc; - GtkWidget *scrolled_win; - GtkWidget *grid; - - fontchooser->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontchooser, - GTK_TYPE_FONT_CHOOSER, - GtkFontChooserPrivate); - - priv = fontchooser->priv; - - /* Default preview string */ - priv->preview_text = g_strdup (pango_language_get_sample_string (NULL)); - priv->show_preview_entry = TRUE; - - /* Getting the default size */ - font_desc = pango_context_get_font_description (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser))); - priv->size = pango_font_description_get_size (font_desc); - priv->face = NULL; - priv->family = NULL; - - gtk_widget_push_composite_child (); - - /* Creating fundamental widgets for the private struct */ - priv->search_entry = gtk_entry_new (); - priv->family_face_list = gtk_tree_view_new (); - priv->preview = gtk_entry_new (); - priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, - (gdouble) font_sizes[0], - (gdouble) font_sizes[G_N_ELEMENTS (font_sizes) - 1], - 1.0); - - priv->size_spin = gtk_spin_button_new_with_range (0.0, (gdouble)(G_MAXINT / PANGO_SCALE), 1.0); - - /** Bootstrapping widget layout **/ - gtk_box_set_spacing (GTK_BOX (fontchooser), 6); - - /* Main font family/face view */ - priv->list_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - scrolled_win = priv->list_scrolled_window; - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), - GTK_SHADOW_ETCHED_IN); - gtk_widget_set_size_request (scrolled_win, 400, 300); - gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_face_list); - - /* Text to display when list is empty */ - priv->empty_list = gtk_label_new (_(NO_FONT_MATCHED_SEARCH)); - gtk_widget_set_margin_top (priv->empty_list, 12); - gtk_widget_set_margin_left (priv->empty_list, 12); - gtk_widget_set_margin_right (priv->empty_list, 12); - gtk_widget_set_margin_bottom (priv->empty_list, 12); - gtk_widget_set_halign (priv->empty_list, GTK_ALIGN_CENTER); - gtk_widget_set_valign (priv->empty_list, GTK_ALIGN_START); - - priv->list_notebook = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->list_notebook), FALSE); - gtk_notebook_append_page (GTK_NOTEBOOK (priv->list_notebook), scrolled_win, NULL); - gtk_notebook_append_page (GTK_NOTEBOOK (priv->list_notebook), priv->empty_list, NULL); - - /* Basic layout */ - grid = gtk_grid_new (); - - gtk_grid_set_column_spacing (GTK_GRID (grid), 6); - gtk_grid_set_row_spacing (GTK_GRID (grid), 6); - - gtk_grid_attach (GTK_GRID (grid), priv->search_entry, 0, 0, 2, 1); - gtk_grid_attach (GTK_GRID (grid), priv->list_notebook, 0, 1, 2, 1); - gtk_grid_attach (GTK_GRID (grid), priv->preview, 0, 2, 2, 1); - - gtk_grid_attach (GTK_GRID (grid), priv->size_slider, 0, 3, 1, 1); - gtk_grid_attach (GTK_GRID (grid), priv->size_spin, 1, 3, 1, 1); - - gtk_widget_set_hexpand (GTK_WIDGET (scrolled_win), TRUE); - gtk_widget_set_vexpand (GTK_WIDGET (scrolled_win), TRUE); - gtk_widget_set_hexpand (GTK_WIDGET (priv->search_entry), TRUE); - - gtk_widget_set_hexpand (GTK_WIDGET (priv->size_slider), TRUE); - gtk_widget_set_hexpand (GTK_WIDGET (priv->size_spin), FALSE); - - gtk_box_pack_start (GTK_BOX (fontchooser), grid, TRUE, TRUE, 0); - - /* Setting the adjustment values for the size slider */ - gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)), - (gdouble)(priv->size / PANGO_SCALE)); - gtk_adjustment_set_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)), - (gdouble)(priv->size / PANGO_SCALE)); - - gtk_widget_show_all (GTK_WIDGET (fontchooser)); - gtk_widget_hide (GTK_WIDGET (fontchooser)); - - /* Treeview column and model bootstrapping */ - gtk_font_chooser_bootstrap_fontlist (fontchooser); - - /* Set default preview text */ - gtk_entry_set_text (GTK_ENTRY (priv->preview), - pango_language_get_sample_string (NULL)); - - /* Set search icon and place holder text */ - icon = g_themed_icon_new_with_default_fallbacks ("edit-find-symbolic"); - g_object_set (G_OBJECT (priv->search_entry), - "secondary-icon-gicon", icon, - "secondary-icon-activatable", FALSE, - "secondary-icon-sensitive", FALSE, - NULL); - g_object_unref (icon); - - gtk_entry_set_placeholder_text (GTK_ENTRY (priv->search_entry), _("Search font name")); - - /** Callback connections **/ - g_signal_connect (priv->search_entry, "notify::text", - G_CALLBACK (text_changed_cb), fontchooser); - g_signal_connect (priv->search_entry, - "icon-press", G_CALLBACK (icon_press_cb), NULL); - - g_signal_connect (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)), - "value-changed", G_CALLBACK (slider_change_cb), fontchooser); - g_signal_connect (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)), - "value-changed", G_CALLBACK (spin_change_cb), fontchooser); - - priv->cursor_changed_handler = - g_signal_connect (priv->family_face_list, "cursor-changed", - G_CALLBACK (cursor_changed_cb), fontchooser); - - g_signal_connect (priv->family_face_list, "row-activated", - G_CALLBACK (row_activated_cb), fontchooser); - - /* Zoom on preview scroll */ - g_signal_connect (priv->preview, "scroll-event", - G_CALLBACK (zoom_preview_cb), fontchooser); - - g_signal_connect (priv->size_slider, "scroll-event", - G_CALLBACK (zoom_preview_cb), fontchooser); - - set_range_marks (priv, priv->size_slider, (gint*)font_sizes, G_N_ELEMENTS (font_sizes)); - - /* Font list empty hides the scrolledwindow */ - g_signal_connect (G_OBJECT (priv->filter_model), "row-deleted", - G_CALLBACK (row_deleted_cb), fontchooser); - g_signal_connect (G_OBJECT (priv->filter_model), "row-inserted", - G_CALLBACK (row_inserted_cb), fontchooser); - - /* Set default focus */ - gtk_widget_pop_composite_child (); -} - -/** - * gtk_font_chooser_new: - * - * Creates a new #GtkFontChooser. - * - * Return value: a new #GtkFontChooser - * - * Since: 3.2 - */ -GtkWidget * -gtk_font_chooser_new (void) -{ - GtkFontChooser *fontchooser; - - fontchooser = g_object_new (GTK_TYPE_FONT_CHOOSER, NULL); - - return GTK_WIDGET (fontchooser); -} - -static int -cmp_families (const void *a, - const void *b) -{ - const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a); - const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b); - - return g_utf8_collate (a_name, b_name); -} - -static void -populate_list (GtkFontChooser *fontchooser, - GtkTreeView *treeview, - GtkListStore *model) -{ - GtkFontChooserPrivate *priv = fontchooser->priv; - GtkStyleContext *style_context; - PangoFontDescription *default_font; - PangoFontDescription *selected_font; - - gint match; - GtkTreeIter match_row; - GtkTreePath *path; - - gint n_families, i; - PangoFontFamily **families; - gchar *tmp; - gchar *family_and_face; - - if (!gtk_widget_has_screen (GTK_WIDGET (fontchooser))) - return; - - pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (treeview)), - &families, - &n_families); - - qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families); - - style_context = gtk_widget_get_style_context (GTK_WIDGET (treeview)); - default_font = (PangoFontDescription*) gtk_style_context_get_font (style_context, - GTK_STATE_NORMAL); - - if (priv->face) - selected_font = pango_font_face_describe (priv->face); - else - selected_font = NULL; - - gtk_list_store_clear (model); - - match = 0; - - /* Iterate over families and faces */ - for (i = 0; i < n_families; i++) - { - GtkTreeIter iter; - PangoFontFace **faces; - int j, n_faces; - const gchar *fam_name = pango_font_family_get_name (families[i]); - - pango_font_family_list_faces (families[i], &faces, &n_faces); - - for (j = 0; j < n_faces; j++) - { - PangoFontDescription *pango_desc; - const gchar *face_name; - gchar *font_desc; - - if (priv->filter_func != NULL && - !priv->filter_func (families[i], faces[j], priv->filter_data)) - continue; - - pango_desc = pango_font_face_describe (faces[j]); - face_name = pango_font_face_get_face_name (faces[j]); - font_desc = pango_font_description_to_string (pango_desc); - - family_and_face = g_strconcat (fam_name, " ", face_name, NULL); - tmp = g_markup_printf_escaped (ROW_FORMAT_STRING, - family_and_face, - font_desc, - fontchooser->priv->preview_text); - - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, - FAMILY_COLUMN, families[i], - FACE_COLUMN, faces[j], - PREVIEW_TITLE_COLUMN, family_and_face, - PREVIEW_TEXT_COLUMN, tmp, - -1); - - /* Select the current font, - * the default font/face from the theme, - * or the first font - */ - if (match < 3 && - selected_font != NULL && - pango_font_description_equal (selected_font, pango_desc)) - { - match_row = iter; - match = 3; - } - if (match < 2 && - strcmp (fam_name, pango_font_description_get_family (default_font)) == 0) - { - match_row = iter; - match = 2; - } - if (match < 1) - { - match_row = iter; - match = 1; - } - - pango_font_description_free (pango_desc); - g_free (font_desc); - g_free (family_and_face); - g_free (tmp); - } - - g_free (faces); - } - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &match_row); - if (path) - { - gtk_tree_view_set_cursor (treeview, path, NULL, FALSE); - gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.5, 0.5); - gtk_tree_path_free (path); - } - - if (selected_font) - pango_font_description_free (selected_font); - - g_free (families); -} - -static gboolean -visible_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - gboolean result = TRUE; - GtkFontChooserPrivate *priv = (GtkFontChooserPrivate*)user_data; - - const gchar *search_text = (const gchar*)gtk_entry_get_text (GTK_ENTRY (priv->search_entry)); - gchar *font_name; - gchar *term; - gchar **split_terms; - gint n_terms = 0; - - /* If there's no filter string we show the item */ - if (strlen (search_text) == 0) - return TRUE; - - gtk_tree_model_get (model, iter, - PREVIEW_TITLE_COLUMN, &font_name, - -1); - - if (font_name == NULL) - return FALSE; - - split_terms = g_strsplit (search_text, " ", 0); - term = split_terms[0]; - - while (term && result) - { - gchar* font_name_casefold = g_utf8_casefold (font_name, -1); - gchar* term_casefold = g_utf8_casefold (term, -1); - - if (g_strrstr (font_name_casefold, term_casefold)) - result = result && TRUE; - else - result = FALSE; - - n_terms++; - term = split_terms[n_terms]; - - g_free (term_casefold); - g_free (font_name_casefold); - } - - g_free (font_name); - g_strfreev (split_terms); - - return result; -} - -static void -gtk_font_chooser_bootstrap_fontlist (GtkFontChooser *fontchooser) -{ - GtkFontChooserPrivate *priv = fontchooser->priv; - GtkTreeView *treeview = GTK_TREE_VIEW (priv->family_face_list); - GtkCellRenderer *cell; - GtkTreeViewColumn *col; - - priv->model = gtk_list_store_new (4, - PANGO_TYPE_FONT_FAMILY, - PANGO_TYPE_FONT_FACE, - G_TYPE_STRING, - G_TYPE_STRING); - - priv->filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (priv->model), NULL); - g_object_unref (priv->model); - - gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->filter_model), - visible_func, (gpointer)priv, NULL); - - gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (priv->filter_model)); - g_object_unref (priv->filter_model); - - gtk_tree_view_set_rules_hint (treeview, TRUE); - gtk_tree_view_set_headers_visible (treeview, FALSE); - - cell = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes ("Family", - cell, - "markup", PREVIEW_TEXT_COLUMN, - NULL); - - g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - - gtk_tree_view_append_column (treeview, col); - - populate_list (fontchooser, treeview, priv->model); -} - -static void -gtk_font_chooser_dispose (GObject *object) -{ - GtkFontChooser *fontchooser = GTK_FONT_CHOOSER (object); - GtkFontChooserPrivate *priv = fontchooser->priv; - - if (priv->cursor_changed_handler != 0) - { - g_signal_handler_disconnect (priv->family_face_list, - priv->cursor_changed_handler); - priv->cursor_changed_handler = 0; - } - - G_OBJECT_CLASS (gtk_font_chooser_parent_class)->dispose (object); -} - -static void -gtk_font_chooser_finalize (GObject *object) -{ - GtkFontChooser *fontchooser = GTK_FONT_CHOOSER (object); - GtkFontChooserPrivate *priv = fontchooser->priv; - - if (priv->fontname) - g_free (priv->fontname); - - if (priv->family) - g_object_unref (priv->family); - - if (priv->face) - g_object_unref (priv->face); - - if (priv->filter_data_destroy) - priv->filter_data_destroy (priv->filter_data); - - G_OBJECT_CLASS (gtk_font_chooser_parent_class)->finalize (object); -} - -static void -gtk_font_chooser_screen_changed (GtkWidget *widget, - GdkScreen *previous_screen) -{ - GtkFontChooser *fontchooser = GTK_FONT_CHOOSER (widget); - GtkFontChooserPrivate *priv = fontchooser->priv; - - populate_list (fontchooser, - GTK_TREE_VIEW (priv->family_face_list), - priv->model); - - if (priv->fontname) - gtk_font_chooser_select_font_name (fontchooser); -} - -static void -gtk_font_chooser_style_updated (GtkWidget *widget) -{ - GtkFontChooser *fontchooser = GTK_FONT_CHOOSER (widget); - - GTK_WIDGET_CLASS (gtk_font_chooser_parent_class)->style_updated (widget); - - populate_list (fontchooser, - GTK_TREE_VIEW (fontchooser->priv->family_face_list), - fontchooser->priv->model); } /** @@ -1029,7 +122,7 @@ gtk_font_chooser_get_family (GtkFontChooser *fontchooser) { g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL); - return fontchooser->priv->family; + return GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_family (fontchooser); } /** @@ -1050,7 +143,7 @@ gtk_font_chooser_get_face (GtkFontChooser *fontchooser) { g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL); - return fontchooser->priv->face; + return GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_face (fontchooser); } /** @@ -1069,7 +162,7 @@ gtk_font_chooser_get_size (GtkFontChooser *fontchooser) { g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), -1); - return fontchooser->priv->size; + return GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_size (fontchooser); } /** @@ -1096,21 +189,9 @@ gtk_font_chooser_get_size (GtkFontChooser *fontchooser) gchar * gtk_font_chooser_get_font_name (GtkFontChooser *fontchooser) { - gchar *font_name; - gchar *font_desc_name; - PangoFontDescription *desc; - - if (!fontchooser->priv->face) - return NULL; - - desc = pango_font_face_describe (fontchooser->priv->face); - font_desc_name = pango_font_description_to_string (desc); - pango_font_description_free (desc); - - font_name = g_strdup_printf ("%s %d", font_desc_name, fontchooser->priv->size / PANGO_SCALE); - g_free (font_desc_name); + g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL); - return font_name; + return GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_name (fontchooser); } /** @@ -1130,112 +211,11 @@ gboolean gtk_font_chooser_set_font_name (GtkFontChooser *fontchooser, const gchar *fontname) { - GtkFontChooserPrivate *priv = fontchooser->priv; - gboolean found = FALSE; - g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), FALSE); g_return_val_if_fail (fontname != NULL, FALSE); - if (priv->fontname) - g_free (priv->fontname); - priv->fontname = g_strdup (fontname); - - if (gtk_widget_has_screen (GTK_WIDGET (fontchooser))) - found = gtk_font_chooser_select_font_name (fontchooser); - - g_object_notify (G_OBJECT (fontchooser), "font-name"); - - return found; -} - -static gboolean -gtk_font_chooser_select_font_name (GtkFontChooser *fontchooser) -{ - GtkFontChooserPrivate *priv = fontchooser->priv; - GtkTreeIter iter; - gboolean valid; - gchar *family_name; - PangoFontDescription *desc; - gboolean found = FALSE; - - desc = pango_font_description_from_string (priv->fontname); - family_name = (gchar*)pango_font_description_get_family (desc); - - g_free (priv->fontname); - priv->fontname = NULL; - - if (!family_name) - { - pango_font_description_free (desc); - return FALSE; - } - - /* We make sure the filter is clear */ - gtk_entry_set_text (GTK_ENTRY (priv->search_entry), ""); - - /* We find the matching family/face */ - for (valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->filter_model), &iter); - valid; - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->filter_model), &iter)) - { - PangoFontFace *face; - PangoFontDescription *tmp_desc; - - gtk_tree_model_get (GTK_TREE_MODEL (priv->filter_model), &iter, - FACE_COLUMN, &face, - -1); - - tmp_desc = pango_font_face_describe (face); - if (pango_font_description_get_size_is_absolute (desc)) - pango_font_description_set_absolute_size (tmp_desc, - pango_font_description_get_size (desc)); - else - pango_font_description_set_size (tmp_desc, - pango_font_description_get_size (desc)); - - if (pango_font_description_equal (desc, tmp_desc)) - { - GtkTreePath *path; - gint size = pango_font_description_get_size (desc); - - if (size) - { - if (pango_font_description_get_size_is_absolute (desc)) - size = size * PANGO_SCALE; - gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->size_spin), - size / PANGO_SCALE); - } - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter_model), &iter); - - if (path) - { - gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->family_face_list), - path, - NULL, - FALSE); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->family_face_list), - path, - NULL, - FALSE, - 0.5, - 0.5); - gtk_tree_path_free (path); - } - - found = TRUE; - } - - g_object_unref (face); - pango_font_description_free (tmp_desc); - - if (found) - break; - } - - pango_font_description_free (desc); - - return found; + return GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->set_font_name (fontchooser, + fontname); } /** @@ -1244,20 +224,22 @@ gtk_font_chooser_select_font_name (GtkFontChooser *fontchooser) * * Gets the text displayed in the preview area. * - * Return value: (transfer none): the text displayed in the - * preview area. This string is owned by the widget and - * should not be modified or freed + * Return value: (transfer full): the text displayed in the + * preview area * * Since: 3.2 */ -const gchar* +gchar * gtk_font_chooser_get_preview_text (GtkFontChooser *fontchooser) { + char *text; + g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL); - return (const gchar*)fontchooser->priv->preview_text; -} + g_object_get (fontchooser, "preview-text", &text, NULL); + return text; +} /** * gtk_font_chooser_set_preview_text: @@ -1276,16 +258,7 @@ gtk_font_chooser_set_preview_text (GtkFontChooser *fontchooser, g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser)); g_return_if_fail (text != NULL); - g_free (fontchooser->priv->preview_text); - fontchooser->priv->preview_text = g_strdup (text); - - populate_list (fontchooser, - GTK_TREE_VIEW (fontchooser->priv->family_face_list), - fontchooser->priv->model); - - gtk_entry_set_text (GTK_ENTRY (fontchooser->priv->preview), text); - - g_object_notify (G_OBJECT (fontchooser), "preview-text"); + g_object_set (fontchooser, "preview-text", text, NULL); } /** @@ -1302,9 +275,13 @@ gtk_font_chooser_set_preview_text (GtkFontChooser *fontchooser, gboolean gtk_font_chooser_get_show_preview_entry (GtkFontChooser *fontchooser) { + gboolean show; + g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), FALSE); - return fontchooser->priv->show_preview_entry; + g_object_get (fontchooser, "show-preview-entry", &show, NULL); + + return show; } /** @@ -1320,28 +297,17 @@ void gtk_font_chooser_set_show_preview_entry (GtkFontChooser *fontchooser, gboolean show_preview_entry) { - GtkFontChooserPrivate *priv = fontchooser->priv; - g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser)); - if (priv->show_preview_entry != show_preview_entry) - { - fontchooser->priv->show_preview_entry = show_preview_entry; - - if (show_preview_entry) - gtk_widget_show (fontchooser->priv->preview); - else - gtk_widget_hide (fontchooser->priv->preview); - - g_object_notify (G_OBJECT (fontchooser), "show-preview-entry"); - } + show_preview_entry = show_preview_entry != FALSE; + g_object_set (fontchooser, "show-preview-entry", show_preview_entry, NULL); } /** * gtk_font_chooser_set_filter_func: * @fontchooser: a #GtkFontChooser * @filter: (allow-none): a #GtkFontFilterFunc, or %NULL - * @data: data to pass to @filter + * @user_data: data to pass to @filter * @destroy: function to call to free @data when it is no longer needed * * Adds a filter function that decides which fonts to display @@ -1352,21 +318,22 @@ gtk_font_chooser_set_show_preview_entry (GtkFontChooser *fontchooser, void gtk_font_chooser_set_filter_func (GtkFontChooser *fontchooser, GtkFontFilterFunc filter, - gpointer data, + gpointer user_data, GDestroyNotify destroy) { - GtkFontChooserPrivate *priv = fontchooser->priv; - g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser)); - if (priv->filter_data_destroy) - priv->filter_data_destroy (priv->filter_data); + GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->set_filter_func (fontchooser, + filter, + user_data, + destroy); +} - priv->filter_func = filter; - priv->filter_data = data; - priv->filter_data_destroy = destroy; +void +_gtk_font_chooser_font_activated (GtkFontChooser *chooser, + const gchar *fontname) +{ + g_return_if_fail (GTK_IS_FONT_CHOOSER (chooser)); - populate_list (fontchooser, - GTK_TREE_VIEW (priv->family_face_list), - priv->model); + g_signal_emit (chooser, chooser_signals[SIGNAL_FONT_ACTIVATED], 0, fontname); } diff --git a/gtk/gtkfontchooser.h b/gtk/gtkfontchooser.h index 4dd390780b..f7df871966 100644 --- a/gtk/gtkfontchooser.h +++ b/gtk/gtkfontchooser.h @@ -1,5 +1,8 @@ /* GTK - The GIMP Toolkit - * Copyright (C) 2011 Alberto Ruiz <aruiz@gnome.org> + * gtkfontchooser.h - Abstract interface for font file selectors GUIs + * + * Copyright (C) 2006, Emmanuele Bassi + * 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 @@ -8,7 +11,7 @@ * * 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 + * 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 @@ -24,71 +27,15 @@ #ifndef __GTK_FONT_CHOOSER_H__ #define __GTK_FONT_CHOOSER_H__ -#include <gtk/gtkbox.h> +#include <gtk/gtkwidget.h> G_BEGIN_DECLS -#define GTK_TYPE_FONT_CHOOSER (gtk_font_chooser_get_type ()) -#define GTK_FONT_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FONT_CHOOSER, GtkFontChooser)) -#define GTK_FONT_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FONT_CHOOSER, GtkFontChooserClass)) -#define GTK_IS_FONT_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FONT_CHOOSER)) -#define GTK_IS_FONT_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FONT_CHOOSER)) -#define GTK_FONT_CHOOSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FONT_CHOOSER, GtkFontChooserClass)) - -typedef struct _GtkFontChooser GtkFontChooser; -typedef struct _GtkFontChooserPrivate GtkFontChooserPrivate; -typedef struct _GtkFontChooserClass GtkFontChooserClass; - -struct _GtkFontChooser -{ - GtkBox parent_instance; - - /*< private >*/ - GtkFontChooserPrivate *priv; -}; - -struct _GtkFontChooserClass -{ - GtkBoxClass parent_class; - - void (* font_activated) (GtkFontChooser *chooser, - const gchar *fontname); - - /* Padding for future expansion */ - void (*_gtk_reserved1) (void); - void (*_gtk_reserved2) (void); - void (*_gtk_reserved3) (void); - void (*_gtk_reserved4) (void); -}; - -/***************************************************************************** - * GtkFontChooser functions. - * see the comments in the GtkFontChooserDialog functions. - *****************************************************************************/ - -GType gtk_font_chooser_get_type (void) G_GNUC_CONST; -GtkWidget* gtk_font_chooser_new (void); -PangoFontFamily* - gtk_font_chooser_get_family (GtkFontChooser *fontchooser); -PangoFontFace* - gtk_font_chooser_get_face (GtkFontChooser *fontchooser); -gint gtk_font_chooser_get_size (GtkFontChooser *fontchooser); -gchar* gtk_font_chooser_get_font_name (GtkFontChooser *fontchooser); - -gboolean gtk_font_chooser_set_font_name (GtkFontChooser *fontchooser, - const gchar *fontname); -const gchar* gtk_font_chooser_get_preview_text (GtkFontChooser *fontchooser); -void gtk_font_chooser_set_preview_text (GtkFontChooser *fontchooser, - const gchar *text); -gboolean gtk_font_chooser_get_show_preview_entry (GtkFontChooser *fontchooser); -void gtk_font_chooser_set_show_preview_entry (GtkFontChooser *fontchooser, - gboolean show_preview_entry); - /** * GtkFontFilterFunc: * @family: a #PangoFontFamily * @face: a #PangoFontFace belonging to @family - * @data (closure): user data passed to gtk_font_chooser_set_filter_func() + * @data: (closure): user data passed to gtk_font_chooser_set_filter_func() * * The type of function that is used for deciding what fonts get * shown in a #GtkFontChooser. See gtk_font_chooser_set_filter_func(). @@ -99,10 +46,57 @@ typedef gboolean (*GtkFontFilterFunc) (const PangoFontFamily *family, const PangoFontFace *face, gpointer data); -void gtk_font_chooser_set_filter_func (GtkFontChooser *fontchooser, - GtkFontFilterFunc filter, - gpointer data, - GDestroyNotify destroy); +#define GTK_TYPE_FONT_CHOOSER (gtk_font_chooser_get_type ()) +#define GTK_FONT_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FONT_CHOOSER, GtkFontChooser)) +#define GTK_IS_FONT_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FONT_CHOOSER)) +#define GTK_FONT_CHOOSER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_FONT_CHOOSER, GtkFontChooserIface)) + +typedef struct _GtkFontChooser GtkFontChooser; /* dummy */ +typedef struct _GtkFontChooserIface GtkFontChooserIface; + +struct _GtkFontChooserIface +{ + GTypeInterface base_iface; + + /* Methods */ + gchar * (* get_font_name) (GtkFontChooser *chooser); + gboolean (* set_font_name) (GtkFontChooser *chooser, + const gchar *fontname); + PangoFontFamily * (* get_font_family) (GtkFontChooser *chooser); + PangoFontFace * (* get_font_face) (GtkFontChooser *chooser); + gint (* get_font_size) (GtkFontChooser *chooser); + void (* set_filter_func) (GtkFontChooser *chooser, + GtkFontFilterFunc filter, + gpointer data, + GDestroyNotify destroy); + + /* Signals */ + void (* font_activated) (GtkFontChooser *chooser, + const gchar *fontname); + + /* Paddig */ + gpointer padding[12]; +}; + +GType gtk_font_chooser_get_type (void) G_GNUC_CONST; + +PangoFontFamily *gtk_font_chooser_get_family (GtkFontChooser *fontchooser); +PangoFontFace *gtk_font_chooser_get_face (GtkFontChooser *fontchooser); +gint gtk_font_chooser_get_size (GtkFontChooser *fontchooser); +gchar* gtk_font_chooser_get_font_name (GtkFontChooser *fontchooser); + +gboolean gtk_font_chooser_set_font_name (GtkFontChooser *fontchooser, + const gchar *font_name); +gchar* gtk_font_chooser_get_preview_text (GtkFontChooser *fontchooser); +void gtk_font_chooser_set_preview_text (GtkFontChooser *fontchooser, + const gchar *text); +gboolean gtk_font_chooser_get_show_preview_entry (GtkFontChooser *fontchooser); +void gtk_font_chooser_set_show_preview_entry (GtkFontChooser *fontchooser, + gboolean show_preview_entry); +void gtk_font_chooser_set_filter_func (GtkFontChooser *fontchooser, + GtkFontFilterFunc filter, + gpointer user_data, + GDestroyNotify destroy); G_END_DECLS diff --git a/gtk/gtkfontchooserdialog.c b/gtk/gtkfontchooserdialog.c index 2fac04ce10..69e32c01d9 100644 --- a/gtk/gtkfontchooserdialog.c +++ b/gtk/gtkfontchooserdialog.c @@ -27,6 +27,9 @@ #include "gtkfontchooserdialog.h" #include "gtkfontchooser.h" +#include "gtkfontchooserwidget.h" +#include "gtkfontchooserutils.h" +#include "gtkbox.h" #include "gtkstock.h" #include "gtkintl.h" #include "gtkaccessible.h" @@ -50,19 +53,11 @@ struct _GtkFontChooserDialogPrivate * * The #GtkFontChooserDialog widget is a dialog box for selecting a font. * - * To set the font which is initially selected, use - * gtk_font_chooser_dialog_set_font_name(). - * - * To get the selected font use gtk_font_chooser_dialog_get_font_name(). - * - * To change the text which is shown in the preview area, use - * gtk_font_chooser_dialog_set_preview_text(). - * +* * <refsect2 id="GtkFontChooserDialog-BUILDER-UI"> * <title>GtkFontChooserDialog as GtkBuildable</title> * The GtkFontChooserDialog implementation of the GtkBuildable interface - * exposes the embedded #GtkFontChooser as internal child with the - * name "font_chooser". It also exposes the buttons with the names + * exposes the buttons with the names * "select_button" and "cancel_button. * </refsect2> * @@ -75,14 +70,57 @@ static GObject *gtk_font_chooser_dialog_buildable_get_internal_child (GtkBuildab const gchar *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)) + 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); + GtkFontChooserDialogPrivate *priv = dialog->priv; + + switch (prop_id) + { + default: + g_object_set_property (G_OBJECT (priv->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); + GtkFontChooserDialogPrivate *priv = dialog->priv; + + switch (prop_id) + { + default: + g_object_get_property (G_OBJECT (priv->fontchooser), pspec->name, value); + break; + } +} + +static void gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass) { + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = gtk_font_chooser_dialog_get_property; + gobject_class->set_property = gtk_font_chooser_dialog_set_property; + + _gtk_font_chooser_install_properties (gobject_class); + g_type_class_add_private (klass, sizeof (GtkFontChooserDialogPrivate)); } @@ -121,7 +159,7 @@ gtk_font_chooser_dialog_init (GtkFontChooserDialog *fontchooserdiag) gtk_window_set_resizable (GTK_WINDOW (fontchooserdiag), TRUE); /* Create the content area */ - priv->fontchooser = gtk_font_chooser_new (); + priv->fontchooser = gtk_font_chooser_widget_new (); gtk_container_set_border_width (GTK_CONTAINER (priv->fontchooser), 5); gtk_widget_show (priv->fontchooser); gtk_box_pack_start (GTK_BOX (content_area), @@ -147,6 +185,9 @@ gtk_font_chooser_dialog_init (GtkFontChooserDialog *fontchooserdiag) gtk_window_set_title (GTK_WINDOW (fontchooserdiag), _("Font Selection")); gtk_widget_pop_composite_child (); + + _gtk_font_chooser_set_delegate (GTK_FONT_CHOOSER (fontchooserdiag), + GTK_FONT_CHOOSER (priv->fontchooser)); } /** gtk_font_chooser_dialog_new: @@ -173,24 +214,6 @@ gtk_font_chooser_dialog_new (const gchar *title, return GTK_WIDGET (dialog); } -/** - * gtk_font_chooser_dialog_get_font_chooser: - * @fcd: a #GtkFontChooserDialog - * - * Retrieves the #GtkFontChooser widget embedded in the dialog. - * - * Returns: (transfer none): the embedded #GtkFontChooser - * - * Since: 3.2 - */ -GtkWidget* -gtk_font_chooser_dialog_get_font_chooser (GtkFontChooserDialog *fcd) -{ - g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fcd), NULL); - - return fcd->priv->fontchooser; -} - static void gtk_font_chooser_dialog_buildable_interface_init (GtkBuildableIface *iface) { @@ -211,113 +234,6 @@ gtk_font_chooser_dialog_buildable_get_internal_child (GtkBuildable *buildable, return G_OBJECT (priv->select_button); else if (g_strcmp0 (childname, "cancel_button") == 0) return G_OBJECT (priv->cancel_button); - else if (g_strcmp0 (childname, "font_chooser") == 0) - return G_OBJECT (priv->fontchooser); return parent_buildable_iface->get_internal_child (buildable, builder, childname); } - -/** - * gtk_font_chooser_dialog_get_font_name: - * @fcd: a #GtkFontChooserDialog - * - * Gets the currently-selected font name. - * - * Note that this can be a different string than what you set with - * gtk_font_chooser_dialog_set_font_name(), as the font chooser widget - * may normalize font names and thus return a string with a different - * structure. For example, "Helvetica Italic Bold 12" could be normalized - * to "Helvetica Bold Italic 12". - * - * Use pango_font_description_equal() if you want to compare two - * font descriptions. - * - * Return value: A string with the name of the current font, or %NULL - * if no font is selected. You must free this string with g_free(). - * - * Since: 3.2 - */ -gchar* -gtk_font_chooser_dialog_get_font_name (GtkFontChooserDialog *fcd) -{ - GtkFontChooserDialogPrivate *priv; - - g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fcd), NULL); - - priv = fcd->priv; - - return gtk_font_chooser_get_font_name (GTK_FONT_CHOOSER (priv->fontchooser)); -} - -/** - * gtk_font_chooser_dialog_set_font_name: - * @fcd: a #GtkFontChooserDialog - * @fontname: a font name like "Helvetica 12" or "Times Bold 18" - * - * Sets the currently selected font. - * - * Return value: %TRUE if the font selected in @fcd is now the - * @fontname specified, %FALSE otherwise. - * - * Since: 3.2 - */ -gboolean -gtk_font_chooser_dialog_set_font_name (GtkFontChooserDialog *fcd, - const gchar *fontname) -{ - GtkFontChooserDialogPrivate *priv; - - g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fcd), FALSE); - g_return_val_if_fail (fontname, FALSE); - - priv = fcd->priv; - - return gtk_font_chooser_set_font_name (GTK_FONT_CHOOSER (priv->fontchooser), fontname); -} - -/** - * gtk_font_chooser_dialog_get_preview_text: - * @fcd: a #GtkFontChooserDialog - * - * Gets the text displayed in the preview area. - * - * Return value: the text displayed in the preview area. - * This string is owned by the widget and should not be - * modified or freed - * - * Since: 3.2 - */ -const gchar* -gtk_font_chooser_dialog_get_preview_text (GtkFontChooserDialog *fcd) -{ - GtkFontChooserDialogPrivate *priv; - - g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fcd), NULL); - - priv = fcd->priv; - - return gtk_font_chooser_get_preview_text (GTK_FONT_CHOOSER (priv->fontchooser)); -} - -/** - * gtk_font_chooser_dialog_set_preview_text: - * @fcd: a #GtkFontChooserDialog - * @text: the text to display in the preview area - * - * Sets the text displayed in the preview area. - * - * Since: 3.2 - */ -void -gtk_font_chooser_dialog_set_preview_text (GtkFontChooserDialog *fcd, - const gchar *text) -{ - GtkFontChooserDialogPrivate *priv; - - g_return_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fcd)); - g_return_if_fail (text != NULL); - - priv = fcd->priv; - - gtk_font_chooser_set_preview_text (GTK_FONT_CHOOSER (priv->fontchooser), text); -} diff --git a/gtk/gtkfontchooserdialog.h b/gtk/gtkfontchooserdialog.h index 48c879c98d..b0b68671b5 100644 --- a/gtk/gtkfontchooserdialog.h +++ b/gtk/gtkfontchooserdialog.h @@ -62,15 +62,6 @@ GType gtk_font_chooser_dialog_get_type (void) G_GNUC_CONST; GtkWidget* gtk_font_chooser_dialog_new (const gchar *title, GtkWindow *window); -GtkWidget* gtk_font_chooser_dialog_get_font_chooser (GtkFontChooserDialog *fcd); -gchar* gtk_font_chooser_dialog_get_font_name (GtkFontChooserDialog *fcd); -gboolean gtk_font_chooser_dialog_set_font_name (GtkFontChooserDialog *fcd, - const gchar *fontname); -const gchar* - gtk_font_chooser_dialog_get_preview_text (GtkFontChooserDialog *fcd); -void gtk_font_chooser_dialog_set_preview_text (GtkFontChooserDialog *fcd, - const gchar *text); - G_END_DECLS #endif /* __GTK_FONT_CHOOSER_DIALOG_H__ */ diff --git a/gtk/gtkfontchooserprivate.h b/gtk/gtkfontchooserprivate.h new file mode 100644 index 0000000000..8a8ac3514c --- /dev/null +++ b/gtk/gtkfontchooserprivate.h @@ -0,0 +1,35 @@ +/* gtkfontprivatechooser.h - Interface definitions for font selectors UI + * + * Copyright (C) 2006 Emmanuele Bassi + * + * All rights reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GTK_FONT_CHOOSER_PRIVATE_H__ +#define __GTK_FONT_CHOOSER_PRIVATE_H__ + +#include "gtkfontchooser.h" + +G_BEGIN_DECLS + +void _gtk_font_chooser_font_activated (GtkFontChooser *chooser, + const gchar *fontname); + +G_END_DECLS + +#endif /* ! __GTK_FONT_CHOOSER_PRIVATE_H__ */ diff --git a/gtk/gtkfontchooserutils.c b/gtk/gtkfontchooserutils.c new file mode 100644 index 0000000000..4dbec90922 --- /dev/null +++ b/gtk/gtkfontchooserutils.c @@ -0,0 +1,186 @@ +/* gtkfontchooserutils.h - Private utility functions for implementing a + * GtkFontChooser interface + * + * Copyright (C) 2006 Emmanuele Bassi + * + * All rights reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Based on gtkfilechooserutils.c: + * Copyright (C) 2003 Red Hat, Inc. + */ + +#include "config.h" + +#include "gtkfontchooserutils.h" + +static GtkFontChooser * +get_delegate (GtkFontChooser *receiver) +{ + return g_object_get_qdata (G_OBJECT (receiver), + GTK_FONT_CHOOSER_DELEGATE_QUARK); +} + +static gchar * +delegate_get_font_name (GtkFontChooser *chooser) +{ + return gtk_font_chooser_get_font_name (get_delegate (chooser)); +} + +static gboolean +delegate_set_font_name (GtkFontChooser *chooser, + const gchar *fontname) +{ + return gtk_font_chooser_set_font_name (get_delegate (chooser), fontname); +} + +static PangoFontFamily * +delegate_get_font_family (GtkFontChooser *chooser) +{ + return gtk_font_chooser_get_family (get_delegate (chooser)); +} + +static PangoFontFace * +delegate_get_font_face (GtkFontChooser *chooser) +{ + return gtk_font_chooser_get_face (get_delegate (chooser)); +} + +static int +delegate_get_font_size (GtkFontChooser *chooser) +{ + return gtk_font_chooser_get_size (get_delegate (chooser)); +} + +static void +delegate_set_filter_func (GtkFontChooser *chooser, + GtkFontFilterFunc filter_func, + gpointer filter_data, + GDestroyNotify data_destroy) +{ + gtk_font_chooser_set_filter_func (get_delegate (chooser), + filter_func, + filter_data, + data_destroy); +} + +static void +delegate_notify (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + gpointer iface; + + iface = g_type_interface_peek (g_type_class_peek (G_OBJECT_TYPE (object)), + GTK_TYPE_FONT_CHOOSER); + if (g_object_interface_find_property (iface, pspec->name)) + g_object_notify_by_pspec (user_data, pspec); +} + +static void +delegate_font_activated (GtkFontChooser *receiver, + const gchar *fontname, + GtkFontChooser *delegate) +{ + _gtk_font_chooser_font_activated (delegate, fontname); +} + +GQuark +_gtk_font_chooser_delegate_get_quark (void) +{ + static GQuark quark = 0; + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("gtk-font-chooser-delegate"); + + return quark; +} + +/** + * _gtk_font_chooser_install_properties: + * @klass: the class structure for a type deriving from #GObject + * + * Installs the necessary properties for a class implementing + * #GtkFontChooser. A #GtkParamSpecOverride property is installed + * for each property, using the values from the #GtkFontChooserProp + * enumeration. The caller must make sure itself that the enumeration + * values don't collide with some other property values they + * are using. + */ +void +_gtk_font_chooser_install_properties (GObjectClass *klass) +{ + g_object_class_override_property (klass, + GTK_FONT_CHOOSER_PROP_FONT_NAME, + "font-name"); + g_object_class_override_property (klass, + GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT, + "preview-text"); + g_object_class_override_property (klass, + GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY, + "show-preview-entry"); +} + +/** + * _gtk_font_chooser_delegate_iface_init: + * @iface: a #GtkFontChooserIface + * + * An interface-initialization function for use in cases where + * an object is simply delegating the methods, signals of + * the #GtkFontChooser interface to another object. + * _gtk_font_chooser_set_delegate() must be called on each + * instance of the object so that the delegate object can + * be found. + */ +void +_gtk_font_chooser_delegate_iface_init (GtkFontChooserIface *iface) +{ + iface->get_font_name = delegate_get_font_name; + iface->set_font_name = delegate_set_font_name; + iface->get_font_family = delegate_get_font_family; + iface->get_font_face = delegate_get_font_face; + iface->get_font_size = delegate_get_font_size; + iface->set_filter_func = delegate_set_filter_func; +} + +/** + * _gtk_font_chooser_set_delegate: + * @receiver: a #GObject implementing #GtkFontChooser + * @delegate: another #GObject implementing #GtkFontChooser + * + * Establishes that calls on @receiver for #GtkFontChooser + * methods should be delegated to @delegate, and that + * #GtkFontChooser signals emitted on @delegate should be + * forwarded to @receiver. Must be used in conjunction with + * _gtk_font_chooser_delegate_iface_init(). + */ +void +_gtk_font_chooser_set_delegate (GtkFontChooser *receiver, + GtkFontChooser *delegate) +{ + g_return_if_fail (GTK_IS_FONT_CHOOSER (receiver)); + g_return_if_fail (GTK_IS_FONT_CHOOSER (delegate)); + + g_object_set_qdata (G_OBJECT (receiver), + GTK_FONT_CHOOSER_DELEGATE_QUARK, + delegate); + + g_signal_connect (delegate, "notify", + G_CALLBACK (delegate_notify), receiver); + g_signal_connect (delegate, "font-activated", + G_CALLBACK (delegate_font_activated), receiver); +} diff --git a/gtk/gtkfontchooserutils.h b/gtk/gtkfontchooserutils.h new file mode 100644 index 0000000000..54511582e3 --- /dev/null +++ b/gtk/gtkfontchooserutils.h @@ -0,0 +1,53 @@ +/* gtkfontchooserutils.h - Private utility functions for implementing a + * GtkFontChooser interface + * + * Copyright (C) 2006 Emmanuele Bassi + * + * All rights reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Based on gtkfilechooserutils.h: + * Copyright (C) 2003 Red Hat, Inc. + */ + +#ifndef __GTK_FONT_CHOOSER_UTILS_H__ +#define __GTK_FONT_CHOOSER_UTILS_H__ + +#include "gtkfontchooserprivate.h" + +G_BEGIN_DECLS + +#define GTK_FONT_CHOOSER_DELEGATE_QUARK (_gtk_font_chooser_delegate_get_quark ()) + +typedef enum { + GTK_FONT_CHOOSER_PROP_FIRST = 0x4000, + GTK_FONT_CHOOSER_PROP_FONT_NAME, + GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT, + GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY, + GTK_FONT_CHOOSER_PROP_LAST +} GtkFontChooserProp; + +void _gtk_font_chooser_install_properties (GObjectClass *klass); +void _gtk_font_chooser_delegate_iface_init (GtkFontChooserIface *iface); +void _gtk_font_chooser_set_delegate (GtkFontChooser *receiver, + GtkFontChooser *delegate); + +GQuark _gtk_font_chooser_delegate_get_quark (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GTK_FONT_CHOOSER_UTILS_H__ */ diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c new file mode 100644 index 0000000000..6d669bdd4c --- /dev/null +++ b/gtk/gtkfontchooserwidget.c @@ -0,0 +1,1198 @@ +/* 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include <stdlib.h> +#include <glib/gprintf.h> +#include <string.h> + +#include <atk/atk.h> + +#include "gtkfontchooserwidget.h" +#include "gtkfontchooser.h" +#include "gtkfontchooserutils.h" +#include "gtkcellrenderertext.h" +#include "gtkentry.h" +#include "gtkframe.h" +#include "gtkbbox.h" +#include "gtkbox.h" +#include "gtklabel.h" +#include "gtkliststore.h" +#include "gtkstock.h" +#include "gtktextview.h" +#include "gtktreeselection.h" +#include "gtktreeview.h" +#include "gtkscrolledwindow.h" +#include "gtkintl.h" +#include "gtkaccessible.h" +#include "gtkbuildable.h" +#include "gtkprivate.h" +#include "gtkscale.h" +#include "gtkspinbutton.h" +#include "gtknotebook.h" +#include "gtkwidget.h" +#include "gtkgrid.h" + +/** + * SECTION:gtkfontchooser + * @Short_description: A widget for selecting fonts + * @Title: GtkFontChooserWidget + * @See_also: #GtkFontChooserWidgetDialog + * + * The #GtkFontChooserWidget widget lists the available fonts, styles and sizes, + * allowing the user to select a font. + * It is used in the #GtkFontChooserWidgetDialog widget to provide a dialog box for + * selecting fonts. + * + * To set the font which is initially selected, use + * gtk_font_chooser_widget_set_font_name(). + * + * To get the selected font use gtk_font_chooser_widget_get_font_name(). + * + * To change the text which is shown in the preview area, use + * gtk_font_chooser_widget_set_preview_text(). + * + * Since: 3.2 + */ + + +struct _GtkFontChooserWidgetPrivate +{ + GtkWidget *search_entry; + GtkWidget *family_face_list; + GtkWidget *list_scrolled_window; + GtkWidget *empty_list; + GtkWidget *list_notebook; + GtkListStore *model; + GtkTreeModel *filter_model; + + GtkWidget *preview; + gchar *preview_text; + gboolean show_preview_entry; + + GtkWidget *size_spin; + GtkWidget *size_slider; + + gchar *fontname; + gint size; + PangoFontFace *face; + PangoFontFamily *family; + + gulong cursor_changed_handler; + + GtkFontFilterFunc filter_func; + gpointer filter_data; + GDestroyNotify filter_data_destroy; +}; + +/* This is the initial fixed height and the top padding of the preview entry */ +#define PREVIEW_HEIGHT 72 +#define PREVIEW_TOP_PADDING 6 + +/* These are the sizes of the font, style & size lists. */ +#define FONT_LIST_HEIGHT 136 +#define FONT_LIST_WIDTH 190 +#define FONT_STYLE_LIST_WIDTH 170 +#define FONT_SIZE_LIST_WIDTH 60 + +#define ROW_FORMAT_STRING "<span weight=\"bold\" size=\"small\">%s</span>\n<span size=\"x-large\" font_desc=\"%s\">%s</span>" + +#define NO_FONT_MATCHED_SEARCH "No fonts matched your search. You can revise your search and try again." + +/* These are what we use as the standard font sizes, for the size list. + */ +static const gint font_sizes[] = { + 6, 8, 9, 10, 11, 12, 13, 14, 16, 20, 24, 36, 48, 72 +}; + +enum { + FAMILY_COLUMN, + FACE_COLUMN, + PREVIEW_TEXT_COLUMN, + PREVIEW_TITLE_COLUMN +}; + +static void gtk_font_chooser_widget_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_font_chooser_widget_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gtk_font_chooser_widget_finalize (GObject *object); +static void gtk_font_chooser_widget_dispose (GObject *object); + +static void gtk_font_chooser_widget_screen_changed (GtkWidget *widget, + GdkScreen *previous_screen); +static void gtk_font_chooser_widget_style_updated (GtkWidget *widget); + +static void gtk_font_chooser_widget_bootstrap_fontlist (GtkFontChooserWidget *fontchooser); + +static gboolean gtk_font_chooser_widget_select_font_name (GtkFontChooserWidget *fontchooser); + +static gchar *gtk_font_chooser_widget_get_font_name (GtkFontChooser *chooser); +static gboolean gtk_font_chooser_widget_set_font_name (GtkFontChooser *chooser, + const gchar *fontname); + +static const gchar *gtk_font_chooser_widget_get_preview_text (GtkFontChooserWidget *fontchooser); +static void gtk_font_chooser_widget_set_preview_text (GtkFontChooserWidget *fontchooser, + const gchar *text); + +static gboolean gtk_font_chooser_widget_get_show_preview_entry (GtkFontChooserWidget *fontchooser); +static void gtk_font_chooser_widget_set_show_preview_entry (GtkFontChooserWidget *fontchooser, + gboolean show_preview_entry); + +static void gtk_font_chooser_widget_iface_init (GtkFontChooserIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GtkFontChooserWidget, gtk_font_chooser_widget, GTK_TYPE_BOX, + G_IMPLEMENT_INTERFACE (GTK_TYPE_FONT_CHOOSER, + gtk_font_chooser_widget_iface_init)) + +static void +gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + widget_class->screen_changed = gtk_font_chooser_widget_screen_changed; + widget_class->style_updated = gtk_font_chooser_widget_style_updated; + + gobject_class->dispose = gtk_font_chooser_widget_dispose; + gobject_class->finalize = gtk_font_chooser_widget_finalize; + gobject_class->set_property = gtk_font_chooser_widget_set_property; + gobject_class->get_property = gtk_font_chooser_widget_get_property; + + _gtk_font_chooser_install_properties (gobject_class); + + g_type_class_add_private (klass, sizeof (GtkFontChooserWidgetPrivate)); +} + +static void +gtk_font_chooser_widget_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (object); + + switch (prop_id) + { + case GTK_FONT_CHOOSER_PROP_FONT_NAME: + gtk_font_chooser_widget_set_font_name (GTK_FONT_CHOOSER (fontchooser), g_value_get_string (value)); + break; + case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT: + gtk_font_chooser_widget_set_preview_text (fontchooser, g_value_get_string (value)); + break; + case GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY: + gtk_font_chooser_widget_set_show_preview_entry (fontchooser, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gtk_font_chooser_widget_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (object); + + switch (prop_id) + { + case GTK_FONT_CHOOSER_PROP_FONT_NAME: + g_value_take_string (value, gtk_font_chooser_widget_get_font_name (GTK_FONT_CHOOSER (fontchooser))); + break; + case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT: + g_value_set_string (value, gtk_font_chooser_widget_get_preview_text (fontchooser)); + break; + case GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY: + g_value_set_boolean (value, gtk_font_chooser_widget_get_show_preview_entry (fontchooser)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +text_changed_cb (GtkEntry *entry, + GParamSpec *pspec, + GtkFontChooserWidget *fc) +{ + GtkFontChooserWidgetPrivate *priv = fc->priv; + const gchar *text; + + text = gtk_entry_get_text (entry); + + if (text == NULL || text[0] == '\0') + { + GIcon *icon; + + icon = g_themed_icon_new_with_default_fallbacks ("edit-find-symbolic"); + g_object_set (G_OBJECT (priv->search_entry), + "secondary-icon-gicon", icon, + "secondary-icon-activatable", FALSE, + "secondary-icon-sensitive", FALSE, + NULL); + g_object_unref (icon); + } + else + { + if (!gtk_entry_get_icon_activatable (GTK_ENTRY (priv->search_entry), GTK_ENTRY_ICON_SECONDARY)) + { + GIcon *icon; + + icon = g_themed_icon_new_with_default_fallbacks ("edit-clear-symbolic"); + g_object_set (G_OBJECT (priv->search_entry), + "secondary-icon-gicon", icon, + "secondary-icon-activatable", TRUE, + "secondary-icon-sensitive", TRUE, + NULL); + g_object_unref (icon); + } + } + + gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model)); +} + +static void +icon_press_cb (GtkEntry *entry, + GtkEntryIconPosition pos, + GdkEvent *event, + gpointer user_data) +{ + gtk_entry_set_text (entry, ""); +} + +static void +slider_change_cb (GtkAdjustment *adjustment, + gpointer user_data) +{ + GtkFontChooserWidget *fc = (GtkFontChooserWidget*)user_data; + GtkFontChooserWidgetPrivate *priv = fc->priv; + GtkAdjustment *spin_adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON (priv->size_spin)); + gdouble slider_value = gtk_adjustment_get_value (adjustment); + gdouble spin_value = gtk_adjustment_get_value (spin_adj); + + if (slider_value != spin_value) + gtk_adjustment_set_value (spin_adj, + gtk_adjustment_get_value (adjustment)); +} + +static void +spin_change_cb (GtkAdjustment *adjustment, + gpointer user_data) +{ + PangoFontDescription *desc; + GtkFontChooserWidget *fontchooser = (GtkFontChooserWidget*)user_data; + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + GtkAdjustment *slider_adj = gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)); + + gdouble size = gtk_adjustment_get_value (adjustment); + priv->size = ((gint)size) * PANGO_SCALE; + + desc = pango_context_get_font_description (gtk_widget_get_pango_context (priv->preview)); + pango_font_description_set_size (desc, priv->size); + gtk_widget_override_font (priv->preview, desc); + + g_object_notify (G_OBJECT (fontchooser), "font-name"); + + /* If the new value is lower than the lower bound of the slider, we set + * the slider adjustment to the lower bound value if it is not already set + */ + if (size < gtk_adjustment_get_lower (slider_adj) && + gtk_adjustment_get_value (slider_adj) != gtk_adjustment_get_lower (slider_adj)) + gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_lower (slider_adj)); + + /* If the new value is upper than the upper bound of the slider, we set + * the slider adjustment to the upper bound value if it is not already set + */ + else if (size > gtk_adjustment_get_upper (slider_adj) && + gtk_adjustment_get_value (slider_adj) != gtk_adjustment_get_upper (slider_adj)) + gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_upper (slider_adj)); + + /* If the new value is not already set on the slider we set it */ + else if (size != gtk_adjustment_get_value (slider_adj)) + gtk_adjustment_set_value (slider_adj, size); + + gtk_widget_queue_draw (priv->preview); +} + +static void +set_range_marks (GtkFontChooserWidgetPrivate *priv, + GtkWidget *size_slider, + gint *sizes, + gint length) +{ + GtkAdjustment *adj; + gint i; + gdouble value; + + if (length < 2) + { + sizes = (gint*)font_sizes; + length = G_N_ELEMENTS (font_sizes); + } + + gtk_scale_clear_marks (GTK_SCALE (size_slider)); + + adj = gtk_range_get_adjustment(GTK_RANGE (size_slider)); + + gtk_adjustment_set_lower (adj, (gdouble) sizes[0]); + gtk_adjustment_set_upper (adj, (gdouble) sizes[length-1]); + + value = gtk_adjustment_get_value (adj); + if (value > (gdouble) sizes[length-1]) + gtk_adjustment_set_value (adj, (gdouble) sizes[length-1]); + else if (value < (gdouble) sizes[0]) + gtk_adjustment_set_value (adj, (gdouble) sizes[0]); + + for (i = 0; i < length; i++) + gtk_scale_add_mark (GTK_SCALE (size_slider), + (gdouble) sizes[i], + GTK_POS_BOTTOM, NULL); +} + +static void +row_activated_cb (GtkTreeView *view, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer user_data) +{ + GtkFontChooser *chooser = user_data; + gchar *fontname; + + fontname = gtk_font_chooser_widget_get_font_name (chooser); + _gtk_font_chooser_font_activated (chooser, fontname); + g_free (fontname); +} + +static void +cursor_changed_cb (GtkTreeView *treeview, + gpointer user_data) +{ + GtkFontChooserWidget *fontchooser = (GtkFontChooserWidget*)user_data; + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + + PangoFontFamily *family; + PangoFontFace *face; + PangoFontDescription *desc; + + gint *sizes; + gint i, n_sizes; + + GtkTreeIter iter; + GtkTreePath *path = gtk_tree_path_new (); + + gtk_tree_view_get_cursor (treeview, &path, NULL); + + if (!path) + return; + + if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->filter_model), &iter, path)) + { + gtk_tree_path_free (path); + return; + } + + + gtk_tree_model_get (GTK_TREE_MODEL (priv->filter_model), &iter, + FACE_COLUMN, &face, + FAMILY_COLUMN, &family, + -1); + + gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.5, 0.5); + + gtk_tree_path_free (path); + path = NULL; + + if (face == NULL || family == NULL) + { + if (face) + g_object_unref (face); + if (family) + g_object_unref (family); + + return; + } + + desc = pango_font_face_describe (face); + pango_font_description_set_size (desc, priv->size); + gtk_widget_override_font (priv->preview, desc); + + pango_font_face_list_sizes (face, &sizes, &n_sizes); + /* It seems not many fonts actually have a sane set of sizes */ + for (i = 0; i < n_sizes; i++) + sizes[i] = sizes[i] / PANGO_SCALE; + + set_range_marks (priv, priv->size_slider, sizes, n_sizes); + + if (priv->family) + g_object_unref (priv->family); + priv->family = family; + + if (priv->face) + g_object_unref (priv->face); + priv->face = face; + + pango_font_description_free (desc); + + g_object_notify (G_OBJECT (fontchooser), "font-name"); +} + +static gboolean +zoom_preview_cb (GtkWidget *scrolled_window, + GdkEventScroll *event, + gpointer user_data) +{ + GtkFontChooserWidget *fc = (GtkFontChooserWidget*)user_data; + GtkFontChooserWidgetPrivate *priv = fc->priv; + + GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)); + + if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT) + gtk_adjustment_set_value (adj, + gtk_adjustment_get_value (adj) + + gtk_adjustment_get_step_increment (adj)); + else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT) + gtk_adjustment_set_value (adj, + gtk_adjustment_get_value (adj) - + gtk_adjustment_get_step_increment (adj)); + return TRUE; +} + +static void +row_inserted_cb (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer user_data) +{ + GtkFontChooserWidget *fontchooser = (GtkFontChooserWidget*)user_data; + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + + gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->list_notebook), 0); +} + +static void +row_deleted_cb (GtkTreeModel *model, + GtkTreePath *path, + gpointer user_data) +{ + GtkFontChooserWidget *fontchooser = (GtkFontChooserWidget*)user_data; + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + + if (gtk_tree_model_iter_n_children (model, NULL) == 0) + gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->list_notebook), 1); +} + +static void +gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser) +{ + GIcon *icon; + GtkFontChooserWidgetPrivate *priv; + PangoFontDescription *font_desc; + GtkWidget *scrolled_win; + GtkWidget *grid; + + fontchooser->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontchooser, + GTK_TYPE_FONT_CHOOSER_WIDGET, + GtkFontChooserWidgetPrivate); + + priv = fontchooser->priv; + + /* Default preview string */ + priv->preview_text = g_strdup (pango_language_get_sample_string (NULL)); + priv->show_preview_entry = TRUE; + + /* Getting the default size */ + font_desc = pango_context_get_font_description (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser))); + priv->size = pango_font_description_get_size (font_desc); + priv->face = NULL; + priv->family = NULL; + + gtk_widget_push_composite_child (); + + /* Creating fundamental widgets for the private struct */ + priv->search_entry = gtk_entry_new (); + priv->family_face_list = gtk_tree_view_new (); + priv->preview = gtk_entry_new (); + priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, + (gdouble) font_sizes[0], + (gdouble) font_sizes[G_N_ELEMENTS (font_sizes) - 1], + 1.0); + + priv->size_spin = gtk_spin_button_new_with_range (0.0, (gdouble)(G_MAXINT / PANGO_SCALE), 1.0); + + /** Bootstrapping widget layout **/ + gtk_box_set_spacing (GTK_BOX (fontchooser), 6); + + /* Main font family/face view */ + priv->list_scrolled_window = gtk_scrolled_window_new (NULL, NULL); + scrolled_win = priv->list_scrolled_window; + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_SHADOW_ETCHED_IN); + gtk_widget_set_size_request (scrolled_win, 400, 300); + gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_face_list); + + /* Text to display when list is empty */ + priv->empty_list = gtk_label_new (_(NO_FONT_MATCHED_SEARCH)); + gtk_widget_set_margin_top (priv->empty_list, 12); + gtk_widget_set_margin_left (priv->empty_list, 12); + gtk_widget_set_margin_right (priv->empty_list, 12); + gtk_widget_set_margin_bottom (priv->empty_list, 12); + gtk_widget_set_halign (priv->empty_list, GTK_ALIGN_CENTER); + gtk_widget_set_valign (priv->empty_list, GTK_ALIGN_START); + + priv->list_notebook = gtk_notebook_new (); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->list_notebook), FALSE); + gtk_notebook_append_page (GTK_NOTEBOOK (priv->list_notebook), scrolled_win, NULL); + gtk_notebook_append_page (GTK_NOTEBOOK (priv->list_notebook), priv->empty_list, NULL); + + /* Basic layout */ + grid = gtk_grid_new (); + + gtk_grid_set_column_spacing (GTK_GRID (grid), 6); + gtk_grid_set_row_spacing (GTK_GRID (grid), 6); + + gtk_grid_attach (GTK_GRID (grid), priv->search_entry, 0, 0, 2, 1); + gtk_grid_attach (GTK_GRID (grid), priv->list_notebook, 0, 1, 2, 1); + gtk_grid_attach (GTK_GRID (grid), priv->preview, 0, 2, 2, 1); + + gtk_grid_attach (GTK_GRID (grid), priv->size_slider, 0, 3, 1, 1); + gtk_grid_attach (GTK_GRID (grid), priv->size_spin, 1, 3, 1, 1); + + gtk_widget_set_hexpand (GTK_WIDGET (scrolled_win), TRUE); + gtk_widget_set_vexpand (GTK_WIDGET (scrolled_win), TRUE); + gtk_widget_set_hexpand (GTK_WIDGET (priv->search_entry), TRUE); + + gtk_widget_set_hexpand (GTK_WIDGET (priv->size_slider), TRUE); + gtk_widget_set_hexpand (GTK_WIDGET (priv->size_spin), FALSE); + + gtk_box_pack_start (GTK_BOX (fontchooser), grid, TRUE, TRUE, 0); + + /* Setting the adjustment values for the size slider */ + gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)), + (gdouble)(priv->size / PANGO_SCALE)); + gtk_adjustment_set_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)), + (gdouble)(priv->size / PANGO_SCALE)); + + gtk_widget_show_all (GTK_WIDGET (fontchooser)); + gtk_widget_hide (GTK_WIDGET (fontchooser)); + + /* Treeview column and model bootstrapping */ + gtk_font_chooser_widget_bootstrap_fontlist (fontchooser); + + /* Set default preview text */ + gtk_entry_set_text (GTK_ENTRY (priv->preview), + pango_language_get_sample_string (NULL)); + + /* Set search icon and place holder text */ + icon = g_themed_icon_new_with_default_fallbacks ("edit-find-symbolic"); + g_object_set (G_OBJECT (priv->search_entry), + "secondary-icon-gicon", icon, + "secondary-icon-activatable", FALSE, + "secondary-icon-sensitive", FALSE, + NULL); + g_object_unref (icon); + + gtk_entry_set_placeholder_text (GTK_ENTRY (priv->search_entry), _("Search font name")); + + /** Callback connections **/ + g_signal_connect (priv->search_entry, "notify::text", + G_CALLBACK (text_changed_cb), fontchooser); + g_signal_connect (priv->search_entry, + "icon-press", G_CALLBACK (icon_press_cb), NULL); + + g_signal_connect (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)), + "value-changed", G_CALLBACK (slider_change_cb), fontchooser); + g_signal_connect (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)), + "value-changed", G_CALLBACK (spin_change_cb), fontchooser); + + priv->cursor_changed_handler = + g_signal_connect (priv->family_face_list, "cursor-changed", + G_CALLBACK (cursor_changed_cb), fontchooser); + + g_signal_connect (priv->family_face_list, "row-activated", + G_CALLBACK (row_activated_cb), fontchooser); + + /* Zoom on preview scroll */ + g_signal_connect (priv->preview, "scroll-event", + G_CALLBACK (zoom_preview_cb), fontchooser); + + g_signal_connect (priv->size_slider, "scroll-event", + G_CALLBACK (zoom_preview_cb), fontchooser); + + set_range_marks (priv, priv->size_slider, (gint*)font_sizes, G_N_ELEMENTS (font_sizes)); + + /* Font list empty hides the scrolledwindow */ + g_signal_connect (G_OBJECT (priv->filter_model), "row-deleted", + G_CALLBACK (row_deleted_cb), fontchooser); + g_signal_connect (G_OBJECT (priv->filter_model), "row-inserted", + G_CALLBACK (row_inserted_cb), fontchooser); + + /* Set default focus */ + gtk_widget_pop_composite_child (); +} + +/** + * gtk_font_chooser_widget_new: + * + * Creates a new #GtkFontChooserWidget. + * + * Return value: a new #GtkFontChooserWidget + * + * Since: 3.2 + */ +GtkWidget * +gtk_font_chooser_widget_new (void) +{ + return g_object_new (GTK_TYPE_FONT_CHOOSER_WIDGET, NULL); +} + +static int +cmp_families (const void *a, + const void *b) +{ + const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a); + const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b); + + return g_utf8_collate (a_name, b_name); +} + +static void +populate_list (GtkFontChooserWidget *fontchooser, + GtkTreeView *treeview, + GtkListStore *model) +{ + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + GtkStyleContext *style_context; + PangoFontDescription *default_font; + PangoFontDescription *selected_font; + + gint match; + GtkTreeIter match_row; + GtkTreePath *path; + + gint n_families, i; + PangoFontFamily **families; + gchar *tmp; + gchar *family_and_face; + + if (!gtk_widget_has_screen (GTK_WIDGET (fontchooser))) + return; + + pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (treeview)), + &families, + &n_families); + + qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families); + + style_context = gtk_widget_get_style_context (GTK_WIDGET (treeview)); + default_font = (PangoFontDescription*) gtk_style_context_get_font (style_context, + GTK_STATE_NORMAL); + + if (priv->face) + selected_font = pango_font_face_describe (priv->face); + else + selected_font = NULL; + + gtk_list_store_clear (model); + + match = 0; + + /* Iterate over families and faces */ + for (i = 0; i < n_families; i++) + { + GtkTreeIter iter; + PangoFontFace **faces; + int j, n_faces; + const gchar *fam_name = pango_font_family_get_name (families[i]); + + pango_font_family_list_faces (families[i], &faces, &n_faces); + + for (j = 0; j < n_faces; j++) + { + PangoFontDescription *pango_desc; + const gchar *face_name; + gchar *font_desc; + + if (priv->filter_func != NULL && + !priv->filter_func (families[i], faces[j], priv->filter_data)) + continue; + + pango_desc = pango_font_face_describe (faces[j]); + face_name = pango_font_face_get_face_name (faces[j]); + font_desc = pango_font_description_to_string (pango_desc); + + family_and_face = g_strconcat (fam_name, " ", face_name, NULL); + tmp = g_markup_printf_escaped (ROW_FORMAT_STRING, + family_and_face, + font_desc, + fontchooser->priv->preview_text); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + FAMILY_COLUMN, families[i], + FACE_COLUMN, faces[j], + PREVIEW_TITLE_COLUMN, family_and_face, + PREVIEW_TEXT_COLUMN, tmp, + -1); + + /* Select the current font, + * the default font/face from the theme, + * or the first font + */ + if (match < 3 && + selected_font != NULL && + pango_font_description_equal (selected_font, pango_desc)) + { + match_row = iter; + match = 3; + } + if (match < 2 && + strcmp (fam_name, pango_font_description_get_family (default_font)) == 0) + { + match_row = iter; + match = 2; + } + if (match < 1) + { + match_row = iter; + match = 1; + } + + pango_font_description_free (pango_desc); + g_free (family_and_face); + g_free (tmp); + g_free (font_desc); + } + + g_free (faces); + } + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &match_row); + if (path) + { + gtk_tree_view_set_cursor (treeview, path, NULL, FALSE); + gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.5, 0.5); + gtk_tree_path_free (path); + } + + if (selected_font) + pango_font_description_free (selected_font); + + g_free (families); +} + +static gboolean +visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data) +{ + gboolean result = TRUE; + GtkFontChooserWidgetPrivate *priv = (GtkFontChooserWidgetPrivate*)user_data; + + const gchar *search_text = (const gchar*)gtk_entry_get_text (GTK_ENTRY (priv->search_entry)); + gchar *font_name; + gchar *term; + gchar **split_terms; + gint n_terms = 0; + + /* If there's no filter string we show the item */ + if (strlen (search_text) == 0) + return TRUE; + + gtk_tree_model_get (model, iter, + PREVIEW_TITLE_COLUMN, &font_name, + -1); + + if (font_name == NULL) + return FALSE; + + split_terms = g_strsplit (search_text, " ", 0); + term = split_terms[0]; + + while (term && result) + { + gchar* font_name_casefold = g_utf8_casefold (font_name, -1); + gchar* term_casefold = g_utf8_casefold (term, -1); + + if (g_strrstr (font_name_casefold, term_casefold)) + result = result && TRUE; + else + result = FALSE; + + n_terms++; + term = split_terms[n_terms]; + + g_free (term_casefold); + g_free (font_name_casefold); + } + + g_free (font_name); + g_strfreev (split_terms); + + return result; +} + +static void +gtk_font_chooser_widget_bootstrap_fontlist (GtkFontChooserWidget *fontchooser) +{ + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + GtkTreeView *treeview = GTK_TREE_VIEW (priv->family_face_list); + GtkCellRenderer *cell; + GtkTreeViewColumn *col; + + priv->model = gtk_list_store_new (4, + PANGO_TYPE_FONT_FAMILY, + PANGO_TYPE_FONT_FACE, + G_TYPE_STRING, + G_TYPE_STRING); + + priv->filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (priv->model), NULL); + g_object_unref (priv->model); + + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->filter_model), + visible_func, (gpointer)priv, NULL); + + gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (priv->filter_model)); + g_object_unref (priv->filter_model); + + gtk_tree_view_set_rules_hint (treeview, TRUE); + gtk_tree_view_set_headers_visible (treeview, FALSE); + + cell = gtk_cell_renderer_text_new (); + col = gtk_tree_view_column_new_with_attributes ("Family", + cell, + "markup", PREVIEW_TEXT_COLUMN, + NULL); + + g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL); + + gtk_tree_view_append_column (treeview, col); + + populate_list (fontchooser, treeview, priv->model); +} + +static void +gtk_font_chooser_widget_dispose (GObject *object) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (object); + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + + if (priv->cursor_changed_handler != 0) + { + g_signal_handler_disconnect (priv->family_face_list, + priv->cursor_changed_handler); + priv->cursor_changed_handler = 0; + } + + G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->dispose (object); +} + +static void +gtk_font_chooser_widget_finalize (GObject *object) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (object); + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + + if (priv->fontname) + g_free (priv->fontname); + + if (priv->family) + g_object_unref (priv->family); + + if (priv->face) + g_object_unref (priv->face); + + if (priv->filter_data_destroy) + priv->filter_data_destroy (priv->filter_data); + + G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->finalize (object); +} + +static void +gtk_font_chooser_widget_screen_changed (GtkWidget *widget, + GdkScreen *previous_screen) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (widget); + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + + populate_list (fontchooser, + GTK_TREE_VIEW (priv->family_face_list), + priv->model); + + if (priv->fontname) + gtk_font_chooser_widget_select_font_name (fontchooser); +} + +static void +gtk_font_chooser_widget_style_updated (GtkWidget *widget) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (widget); + + GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->style_updated (widget); + + populate_list (fontchooser, + GTK_TREE_VIEW (fontchooser->priv->family_face_list), + fontchooser->priv->model); +} + +static PangoFontFamily * +gtk_font_chooser_widget_get_family (GtkFontChooser *chooser) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser); + + return fontchooser->priv->family; +} + +static PangoFontFace * +gtk_font_chooser_widget_get_face (GtkFontChooser *chooser) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser); + + return fontchooser->priv->face; +} + +static gint +gtk_font_chooser_widget_get_size (GtkFontChooser *chooser) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser); + + return fontchooser->priv->size; +} + +static gchar * +gtk_font_chooser_widget_get_font_name (GtkFontChooser *chooser) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser); + gchar *font_name; + gchar *font_desc_name; + PangoFontDescription *desc; + + if (!fontchooser->priv->face) + return NULL; + + desc = pango_font_face_describe (fontchooser->priv->face); + font_desc_name = pango_font_description_to_string (desc); + pango_font_description_free (desc); + + font_name = g_strdup_printf ("%s %d", font_desc_name, fontchooser->priv->size / PANGO_SCALE); + g_free (font_desc_name); + + return font_name; +} + +static gboolean +gtk_font_chooser_widget_set_font_name (GtkFontChooser *chooser, + const gchar *fontname) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser); + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + gboolean found = FALSE; + + if (priv->fontname) + g_free (priv->fontname); + priv->fontname = g_strdup (fontname); + + if (gtk_widget_has_screen (GTK_WIDGET (fontchooser))) + found = gtk_font_chooser_widget_select_font_name (fontchooser); + + g_object_notify (G_OBJECT (fontchooser), "font-name"); + + return found; +} + +static gboolean +gtk_font_chooser_widget_select_font_name (GtkFontChooserWidget *fontchooser) +{ + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + GtkTreeIter iter; + gboolean valid; + gchar *family_name; + PangoFontDescription *desc; + gboolean found = FALSE; + + desc = pango_font_description_from_string (priv->fontname); + family_name = (gchar*)pango_font_description_get_family (desc); + + g_free (priv->fontname); + priv->fontname = NULL; + + if (!family_name) + { + pango_font_description_free (desc); + return FALSE; + } + + /* We make sure the filter is clear */ + gtk_entry_set_text (GTK_ENTRY (priv->search_entry), ""); + + /* We find the matching family/face */ + for (valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->filter_model), &iter); + valid; + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->filter_model), &iter)) + { + PangoFontFace *face; + PangoFontDescription *tmp_desc; + + gtk_tree_model_get (GTK_TREE_MODEL (priv->filter_model), &iter, + FACE_COLUMN, &face, + -1); + + tmp_desc = pango_font_face_describe (face); + if (pango_font_description_get_size_is_absolute (desc)) + pango_font_description_set_absolute_size (tmp_desc, + pango_font_description_get_size (desc)); + else + pango_font_description_set_size (tmp_desc, + pango_font_description_get_size (desc)); + + if (pango_font_description_equal (desc, tmp_desc)) + { + GtkTreePath *path; + gint size = pango_font_description_get_size (desc); + + if (size) + { + if (pango_font_description_get_size_is_absolute (desc)) + size = size * PANGO_SCALE; + gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->size_spin), + size / PANGO_SCALE); + } + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter_model), &iter); + + if (path) + { + gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->family_face_list), + path, + NULL, + FALSE); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->family_face_list), + path, + NULL, + FALSE, + 0.5, + 0.5); + gtk_tree_path_free (path); + } + + found = TRUE; + } + + g_object_unref (face); + pango_font_description_free (tmp_desc); + + if (found) + break; + } + + pango_font_description_free (desc); + + return found; +} + +static const gchar* +gtk_font_chooser_widget_get_preview_text (GtkFontChooserWidget *fontchooser) +{ + return (const gchar*)fontchooser->priv->preview_text; +} + +static void +gtk_font_chooser_widget_set_preview_text (GtkFontChooserWidget *fontchooser, + const gchar *text) +{ + g_return_if_fail (text != NULL); + + g_free (fontchooser->priv->preview_text); + fontchooser->priv->preview_text = g_strdup (text); + + populate_list (fontchooser, + GTK_TREE_VIEW (fontchooser->priv->family_face_list), + fontchooser->priv->model); + + gtk_entry_set_text (GTK_ENTRY (fontchooser->priv->preview), text); + + g_object_notify (G_OBJECT (fontchooser), "preview-text"); +} + +static gboolean +gtk_font_chooser_widget_get_show_preview_entry (GtkFontChooserWidget *fontchooser) +{ + return fontchooser->priv->show_preview_entry; +} + +static void +gtk_font_chooser_widget_set_show_preview_entry (GtkFontChooserWidget *fontchooser, + gboolean show_preview_entry) +{ + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + + if (priv->show_preview_entry != show_preview_entry) + { + fontchooser->priv->show_preview_entry = show_preview_entry; + + if (show_preview_entry) + gtk_widget_show (fontchooser->priv->preview); + else + gtk_widget_hide (fontchooser->priv->preview); + + g_object_notify (G_OBJECT (fontchooser), "show-preview-entry"); + } +} + +static void +gtk_font_chooser_widget_set_filter_func (GtkFontChooser *chooser, + GtkFontFilterFunc filter, + gpointer data, + GDestroyNotify destroy) +{ + GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser); + GtkFontChooserWidgetPrivate *priv = fontchooser->priv; + + if (priv->filter_data_destroy) + priv->filter_data_destroy (priv->filter_data); + + priv->filter_func = filter; + priv->filter_data = data; + priv->filter_data_destroy = destroy; + + populate_list (fontchooser, + GTK_TREE_VIEW (priv->family_face_list), + priv->model); +} + +static void +gtk_font_chooser_widget_iface_init (GtkFontChooserIface *iface) +{ + iface->get_font_name = gtk_font_chooser_widget_get_font_name; + iface->set_font_name = gtk_font_chooser_widget_set_font_name; + iface->get_font_family = gtk_font_chooser_widget_get_family; + iface->get_font_face = gtk_font_chooser_widget_get_face; + iface->get_font_size = gtk_font_chooser_widget_get_size; + iface->set_filter_func = gtk_font_chooser_widget_set_filter_func; +} diff --git a/gtk/gtkfontchooserwidget.h b/gtk/gtkfontchooserwidget.h new file mode 100644 index 0000000000..9a3934f321 --- /dev/null +++ b/gtk/gtkfontchooserwidget.h @@ -0,0 +1,71 @@ +/* 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only <gtk/gtk.h> can be included directly." +#endif + +#ifndef __GTK_FONT_CHOOSER_WIDGET_H__ +#define __GTK_FONT_CHOOSER_WIDGET_H__ + +#include <gtk/gtkbox.h> + +G_BEGIN_DECLS + +#define GTK_TYPE_FONT_CHOOSER_WIDGET (gtk_font_chooser_widget_get_type ()) +#define GTK_FONT_CHOOSER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FONT_CHOOSER_WIDGET, GtkFontChooserWidget)) +#define GTK_FONT_CHOOSER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FONT_CHOOSER_WIDGET, GtkFontChooserWidgetClass)) +#define GTK_IS_FONT_CHOOSER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FONT_CHOOSER_WIDGET)) +#define GTK_IS_FONT_CHOOSER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FONT_CHOOSER_WIDGET)) +#define GTK_FONT_CHOOSER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FONT_CHOOSER_WIDGET, GtkFontChooserWidgetClass)) + +typedef struct _GtkFontChooserWidget GtkFontChooserWidget; +typedef struct _GtkFontChooserWidgetPrivate GtkFontChooserWidgetPrivate; +typedef struct _GtkFontChooserWidgetClass GtkFontChooserWidgetClass; + +struct _GtkFontChooserWidget +{ + GtkBox parent_instance; + + /*< private >*/ + GtkFontChooserWidgetPrivate *priv; +}; + +struct _GtkFontChooserWidgetClass +{ + GtkBoxClass parent_class; + + /* Padding for future expansion */ + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + void (*_gtk_reserved4) (void); + void (*_gtk_reserved5) (void); + void (*_gtk_reserved6) (void); + void (*_gtk_reserved7) (void); + void (*_gtk_reserved8) (void); +}; + +GType gtk_font_chooser_widget_get_type (void) G_GNUC_CONST; + +GtkWidget* gtk_font_chooser_widget_new (void); + +G_END_DECLS + +#endif /* __GTK_FONT_CHOOSER_WIDGET_H__ */ diff --git a/tests/testfontchooser.c b/tests/testfontchooser.c index 580c614ebc..e92815ce65 100644 --- a/tests/testfontchooser.c +++ b/tests/testfontchooser.c @@ -40,7 +40,7 @@ main (int argc, char *argv[]) gtk_init (NULL, NULL); - fontchooser = gtk_font_chooser_new (); + fontchooser = gtk_font_chooser_widget_new (); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (window, 600, 600); |