From 21391027c4a50afecdc8541bb5f30f3da38b335c Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Tue, 26 Mar 2013 18:50:01 +0900 Subject: [PATCH] GtkFontChooserWidget: Define children with a GtkBuilder template --- gtk/Makefile.am | 1 + gtk/gtk.gresource.xml | 1 + gtk/gtkfontchooserwidget.c | 249 +++++++++++------------------------- gtk/gtkfontchooserwidget.ui | 190 +++++++++++++++++++++++++++ gtk/tests/templates.c | 11 ++ 5 files changed, 278 insertions(+), 174 deletions(-) create mode 100644 gtk/gtkfontchooserwidget.ui diff --git a/gtk/Makefile.am b/gtk/Makefile.am index bb11536040..7e5b0d2264 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -1104,6 +1104,7 @@ COMPOSITE_TEMPLATES = \ gtkdialog.ui \ gtkfilechooserdefault.ui \ gtkfilechooserdialog.ui \ + gtkfontchooserwidget.ui \ gtkinfobar.ui \ gtklockbutton.ui \ gtkmessagedialog.ui \ diff --git a/gtk/gtk.gresource.xml b/gtk/gtk.gresource.xml index 87797919e1..9ca8d7a819 100644 --- a/gtk/gtk.gresource.xml +++ b/gtk/gtk.gresource.xml @@ -19,6 +19,7 @@ gtkdialog.ui gtkfilechooserdefault.ui gtkfilechooserdialog.ui + gtkfontchooserwidget.ui gtkinfobar.ui gtklockbutton.ui gtkmessagedialog.ui diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c index 7454a35186..28fcd44e6f 100644 --- a/gtk/gtkfontchooserwidget.c +++ b/gtk/gtkfontchooserwidget.c @@ -75,9 +75,9 @@ struct _GtkFontChooserWidgetPrivate { GtkWidget *search_entry; GtkWidget *family_face_list; + GtkTreeViewColumn *family_face_column; GtkCellRenderer *family_face_cell; GtkWidget *list_scrolled_window; - GtkWidget *empty_list; GtkWidget *list_notebook; GtkTreeModel *model; GtkTreeModel *filter_model; @@ -107,8 +107,7 @@ struct _GtkFontChooserWidgetPrivate #define FONT_STYLE_LIST_WIDTH 170 #define FONT_SIZE_LIST_WIDTH 60 -#define NO_FONT_MATCHED_SEARCH N_("No fonts matched your search. You can revise your search and try again.") - +/* Keep in line with GtkTreeStore defined in gtkfontchooserwidget.ui */ enum { FAMILY_COLUMN, FACE_COLUMN, @@ -129,8 +128,6 @@ static void gtk_font_chooser_widget_finalize (GObject *objec static void gtk_font_chooser_widget_screen_changed (GtkWidget *widget, GdkScreen *previous_screen); -static void gtk_font_chooser_widget_bootstrap_fontlist (GtkFontChooserWidget *fontchooser); - static gboolean gtk_font_chooser_widget_find_font (GtkFontChooserWidget *fontchooser, const PangoFontDescription *font_desc, GtkTreeIter *iter); @@ -156,29 +153,23 @@ static gboolean gtk_font_chooser_widget_get_show_preview_entry (GtkFontChooserWi static void gtk_font_chooser_widget_set_show_preview_entry (GtkFontChooserWidget *fontchooser, gboolean show_preview_entry); +static void gtk_font_chooser_widget_set_cell_size (GtkFontChooserWidget *fontchooser); +static void gtk_font_chooser_widget_load_fonts (GtkFontChooserWidget *fontchooser); +static gboolean visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data); +static void gtk_font_chooser_widget_cell_data_func (GtkTreeViewColumn *column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer user_data); + 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; - - 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, @@ -463,12 +454,54 @@ row_deleted_cb (GtkTreeModel *model, gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->list_notebook), 1); } +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; + + 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); + + /* Bind class to template + */ + gtk_widget_class_set_template_from_resource (widget_class, + "/org/gtk/libgtk/gtkfontchooserwidget.ui"); + + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, search_entry); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, family_face_list); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, family_face_column); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, family_face_cell); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, list_scrolled_window); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, list_notebook); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, model); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, filter_model); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, preview); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, size_spin); + gtk_widget_class_bind_child (widget_class, GtkFontChooserWidgetPrivate, size_slider); + + gtk_widget_class_bind_callback (widget_class, text_changed_cb); + gtk_widget_class_bind_callback (widget_class, cursor_changed_cb); + gtk_widget_class_bind_callback (widget_class, row_activated_cb); + gtk_widget_class_bind_callback (widget_class, gtk_font_chooser_widget_set_cell_size); + gtk_widget_class_bind_callback (widget_class, zoom_preview_cb); + gtk_widget_class_bind_callback (widget_class, row_deleted_cb); + gtk_widget_class_bind_callback (widget_class, row_inserted_cb); + gtk_widget_class_bind_callback (widget_class, row_deleted_cb); + gtk_widget_class_bind_callback (widget_class, size_change_cb); + + g_type_class_add_private (klass, sizeof (GtkFontChooserWidgetPrivate)); +} + static void gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser) { GtkFontChooserWidgetPrivate *priv; - GtkWidget *scrolled_win; - GtkWidget *grid; fontchooser->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontchooser, GTK_TYPE_FONT_CHOOSER_WIDGET, @@ -476,115 +509,36 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser) priv = fontchooser->priv; + gtk_widget_init_template (GTK_WIDGET (fontchooser)); + /* Default preview string */ priv->preview_text = g_strdup (pango_language_get_sample_string (NULL)); priv->show_preview_entry = TRUE; priv->font_desc = pango_font_description_new (); - gtk_widget_push_composite_child (); - - /* Creating fundamental widgets for the private struct */ - priv->search_entry = gtk_search_entry_new (); - priv->family_face_list = gtk_tree_view_new (); - gtk_tree_view_set_enable_search (GTK_TREE_VIEW (priv->family_face_list), FALSE); - priv->preview = gtk_entry_new (); - priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, - 0.0, - (gdouble)(G_MAXINT / PANGO_SCALE), - 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); - - 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)); - gtk_entry_set_placeholder_text (GTK_ENTRY (priv->search_entry), _("Search font name")); + /* Set the upper values of the spin/scale with G_MAXINT / PANGO_SCALE */ + gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->size_spin), + 0.0, (gdouble)(G_MAXINT / PANGO_SCALE)); + gtk_adjustment_set_upper (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)), + (gdouble)(G_MAXINT / PANGO_SCALE)); - /* Callback connections */ - g_signal_connect (priv->search_entry, "notify::text", - G_CALLBACK (text_changed_cb), fontchooser); + /* Setup treeview/model auxilary functions */ + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->filter_model), + visible_func, (gpointer)priv, NULL); - g_signal_connect (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)), - "value-changed", G_CALLBACK (size_change_cb), fontchooser); - g_signal_connect (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)), - "value-changed", G_CALLBACK (size_change_cb), fontchooser); + gtk_tree_view_column_set_cell_data_func (priv->family_face_column, + priv->family_face_cell, + gtk_font_chooser_widget_cell_data_func, + fontchooser, + NULL); - 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); - - /* 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 (); + /* Load data and set initial style dependant parameters */ + gtk_font_chooser_widget_load_fonts (fontchooser); + gtk_font_chooser_widget_set_cell_size (fontchooser); gtk_font_chooser_widget_take_font_desc (fontchooser, NULL); } @@ -851,59 +805,6 @@ gtk_font_chooser_widget_set_cell_size (GtkFontChooserWidget *fontchooser) gtk_cell_renderer_set_fixed_size (priv->family_face_cell, size.width, size.height); } -static void -gtk_font_chooser_widget_bootstrap_fontlist (GtkFontChooserWidget *fontchooser) -{ - GtkFontChooserWidgetPrivate *priv = fontchooser->priv; - GtkTreeView *treeview = GTK_TREE_VIEW (priv->family_face_list); - GtkTreeViewColumn *col; - - g_signal_connect_data (priv->family_face_list, - "style-updated", - G_CALLBACK (gtk_font_chooser_widget_set_cell_size), - fontchooser, - NULL, - G_CONNECT_AFTER | G_CONNECT_SWAPPED); - - priv->model = GTK_TREE_MODEL (gtk_list_store_new (4, - PANGO_TYPE_FONT_FAMILY, - PANGO_TYPE_FONT_FACE, - PANGO_TYPE_FONT_DESCRIPTION, - G_TYPE_STRING)); - - priv->filter_model = gtk_tree_model_filter_new (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, 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); - gtk_tree_view_set_fixed_height_mode (treeview, TRUE); - - priv->family_face_cell = gtk_cell_renderer_text_new (); - g_object_set (priv->family_face_cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - - col = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (col, _("Font Family")); - gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED); - gtk_tree_view_column_pack_start (col, priv->family_face_cell, TRUE); - gtk_tree_view_column_set_cell_data_func (col, - priv->family_face_cell, - gtk_font_chooser_widget_cell_data_func, - fontchooser, - NULL); - - gtk_tree_view_append_column (treeview, col); - - gtk_font_chooser_widget_load_fonts (fontchooser); - - gtk_font_chooser_widget_set_cell_size (fontchooser); -} - static void gtk_font_chooser_widget_finalize (GObject *object) { diff --git a/gtk/gtkfontchooserwidget.ui b/gtk/gtkfontchooserwidget.ui new file mode 100644 index 0000000000..dd61bc9801 --- /dev/null +++ b/gtk/gtkfontchooserwidget.ui @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + model + + + + + 100 + 1 + 10 + + + + 100 + 1 + 10 + + + + diff --git a/gtk/tests/templates.c b/gtk/tests/templates.c index 56704d269b..6c61bdacc2 100644 --- a/gtk/tests/templates.c +++ b/gtk/tests/templates.c @@ -224,6 +224,16 @@ test_file_chooser_dialog_basic (void) gtk_widget_destroy (widget); } +static void +test_font_chooser_widget_basic (void) +{ + GtkWidget *widget; + + widget = gtk_font_chooser_widget_new (); + g_assert (GTK_IS_FONT_CHOOSER_WIDGET (widget)); + gtk_widget_destroy (widget); +} + int main (int argc, char **argv) { @@ -250,6 +260,7 @@ main (int argc, char **argv) g_test_add_func ("/Template/GtkColorChooserDialog/Basic", test_color_chooser_dialog_basic); g_test_add_func ("/Template/GtkFileChooserWidget/Basic", test_file_chooser_widget_basic); g_test_add_func ("/Template/GtkFileChooserDialog/Basic", test_file_chooser_dialog_basic); + g_test_add_func ("/Template/GtkFontChooserWidget/Basic", test_font_chooser_widget_basic); return g_test_run(); }