[gtk+/wip/matthiasc/font-variations: 56/58] font chooser: Redo the tweaks hookup



commit 5f854b29b67a228440548e07c6b039b99ca2ae43
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Dec 29 23:07:14 2017 -0500

    font chooser: Redo the tweaks hookup
    
    Make the font chooser widget export an action that the
    dialog can use for the button. This has some advantages:
    - we can export not just the toggle state, but also enabled
    - we can reuse the same enabled state to make the select
      button insensitive when no font is selected
    
    To determine whether a font is selected, listen to changes
    of the list selection. And ensure that the font chooser is
    in an initial state when mapped, even if we close the dialog
    from the tweak page.

 gtk/gtkfontchooserdialog.c        |   26 +++++----
 gtk/gtkfontchooserwidget.c        |  118 ++++++++++++++++++++++++++++++-------
 gtk/gtkfontchooserwidgetprivate.h |    3 +-
 gtk/ui/gtkfontchooserwidget.ui    |    1 +
 4 files changed, 114 insertions(+), 34 deletions(-)
---
diff --git a/gtk/gtkfontchooserdialog.c b/gtk/gtkfontchooserdialog.c
index c0637f5..ff60f52 100644
--- a/gtk/gtkfontchooserdialog.c
+++ b/gtk/gtkfontchooserdialog.c
@@ -38,6 +38,7 @@
 #include "gtkdialogprivate.h"
 #include "gtktogglebutton.h"
 #include "gtkheaderbar.h"
+#include "gtkactionable.h"
 
 struct _GtkFontChooserDialogPrivate
 {
@@ -140,13 +141,6 @@ gtk_font_chooser_dialog_key_press_event (GtkWidget   *dialog,
 }
 
 static void
-tweak_font (GtkFontChooserDialog *dialog)
-{
-  gtk_font_chooser_widget_tweak_font (dialog->priv->fontchooser,
-                                      gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON 
(dialog->priv->tweak_button)));
-}
-
-static void
 setup_tweak_button (GtkFontChooserDialog *dialog)
 {
   gboolean use_header;
@@ -159,17 +153,22 @@ setup_tweak_button (GtkFontChooserDialog *dialog)
     {
       GtkWidget *button;
       GtkWidget *header;
+      GSimpleActionGroup *actions;
+
+      actions = g_simple_action_group_new ();
+      g_action_map_add_action (G_ACTION_MAP (actions), gtk_font_chooser_widget_get_tweak_action 
(dialog->priv->fontchooser));
+      gtk_widget_insert_action_group (GTK_WIDGET (dialog), "font", actions);
+      g_object_unref (actions);
 
       button = gtk_toggle_button_new ();
+      gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "font.tweak");
       gtk_widget_set_focus_on_click (button, FALSE);
       gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
-      gtk_button_set_icon_name (button, "emblem-system-symbolic");
+      gtk_button_set_icon_name (GTK_BUTTON (button), "emblem-system-symbolic");
 
       header = gtk_dialog_get_header_bar (GTK_DIALOG (dialog));
       gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
 
-      g_signal_connect_swapped (button, "notify::active", G_CALLBACK (tweak_font), dialog);
-
       dialog->priv->tweak_button = button;
     }
 }
@@ -209,7 +208,6 @@ gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, select_button);
   gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, cancel_button);
   gtk_widget_class_bind_template_callback (widget_class, font_activated_cb);
-  gtk_widget_class_bind_template_callback (widget_class, tweak_font);
 }
 
 static void
@@ -225,6 +223,12 @@ gtk_font_chooser_dialog_init (GtkFontChooserDialog *fontchooserdiag)
 
   _gtk_font_chooser_set_delegate (GTK_FONT_CHOOSER (fontchooserdiag),
                                   GTK_FONT_CHOOSER (priv->fontchooser));
+
+  g_object_bind_property (gtk_font_chooser_widget_get_tweak_action (priv->fontchooser),
+                          "enabled",
+                          priv->select_button,
+                          "sensitive",
+                          G_BINDING_SYNC_CREATE);
 }
 
 /**
diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c
index 306d5da..838dcb3 100644
--- a/gtk/gtkfontchooserwidget.c
+++ b/gtk/gtkfontchooserwidget.c
@@ -168,6 +168,8 @@ struct _GtkFontChooserWidgetPrivate
   GtkFontChooserLevel level;
 
   GList *feature_items;
+
+  GAction *tweak_action;
 };
 
 /* Keep in line with GtkTreeStore defined in gtkfontchooserwidget.ui */
@@ -260,6 +262,8 @@ static void popover_notify (GObject              *object,
                             GtkFontChooserWidget *fontchooser);
 static void update_font_features (GtkFontChooserWidget *fontchooser);
 static void update_language (GtkFontChooserWidget *fontchooser);
+static void selection_changed (GtkTreeSelection *selection,
+                               GtkFontChooserWidget *fontchooser);
 
 static void gtk_font_chooser_widget_iface_init (GtkFontChooserIface *iface);
 
@@ -667,11 +671,28 @@ static void
 rows_changed_cb (GtkFontChooserWidget *fontchooser)
 {
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
+  const char *page;
 
   if (gtk_tree_model_iter_n_children (priv->filter_model, NULL) == 0)
-    gtk_stack_set_visible_child_name (GTK_STACK (priv->list_stack), "empty");
+    page = "empty";
   else
-    gtk_stack_set_visible_child_name (GTK_STACK (priv->list_stack), "list");
+    page = "list";
+
+  if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (priv->list_stack)), page) != 0)
+    gtk_stack_set_visible_child_name (GTK_STACK (priv->list_stack), page);
+}
+
+static void
+gtk_font_chooser_widget_map (GtkWidget *widget)
+{
+  GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (widget);
+  GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
+
+  gtk_entry_set_text (GTK_ENTRY (priv->search_entry), "");
+  gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "list");
+  g_simple_action_set_state (G_SIMPLE_ACTION (priv->tweak_action), g_variant_new_boolean (FALSE));
+
+  GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->map (widget);
 }
 
 static void
@@ -743,6 +764,7 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
   widget_class->measure = gtk_font_chooser_widget_measure;
   widget_class->size_allocate = gtk_font_chooser_widget_size_allocate;
   widget_class->snapshot = gtk_font_chooser_widget_snapshot;
+  widget_class->map = gtk_font_chooser_widget_map;
 
   gobject_class->finalize = gtk_font_chooser_widget_finalize;
   gobject_class->dispose = gtk_font_chooser_widget_dispose;
@@ -810,6 +832,7 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
   gtk_widget_class_bind_template_callback (widget_class, popover_notify);
   gtk_widget_class_bind_template_callback (widget_class, gtk_font_chooser_widget_refilter_font_list);
   gtk_widget_class_bind_template_callback (widget_class, update_language);
+  gtk_widget_class_bind_template_callback (widget_class, selection_changed);
 
   gtk_widget_class_set_css_name (widget_class, I_("fontchooser"));
 }
@@ -863,6 +886,29 @@ axis_free (gpointer v)
 }
 
 #endif
+
+static void
+change_tweak (GSimpleAction *action,
+              GVariant      *state,
+              gpointer       data)
+{
+  GtkFontChooserWidget *fontchooser = data;
+  gboolean tweak = g_variant_get_boolean (state);
+
+  if (tweak)
+    {
+      gtk_entry_grab_focus_without_selecting (GTK_ENTRY (fontchooser->priv->preview2));
+      gtk_stack_set_visible_child_name (GTK_STACK (fontchooser->priv->stack), "tweaks");
+    }
+  else
+    {
+      gtk_entry_grab_focus_without_selecting (GTK_ENTRY (fontchooser->priv->search_entry));
+      gtk_stack_set_visible_child_name (GTK_STACK (fontchooser->priv->stack), "list");
+    }
+
+  g_simple_action_set_state (action, state);
+}
+
 static void
 gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
 {
@@ -905,6 +951,9 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
                                            fontchooser,
                                            NULL);
 
+  priv->tweak_action = G_ACTION (g_simple_action_new_stateful ("tweak", NULL, g_variant_new_boolean 
(FALSE)));
+  g_signal_connect (priv->tweak_action, "change-state", G_CALLBACK (change_tweak), fontchooser);
+
   /* Load data and set initial style-dependent parameters */
   gtk_font_chooser_widget_load_fonts (fontchooser, TRUE);
   gtk_font_chooser_widget_populate_filters (fontchooser);
@@ -1793,6 +1842,8 @@ gtk_font_chooser_widget_finalize (GObject *object)
 
   g_list_free_full (priv->feature_items, g_free);
 
+  g_object_unref (priv->tweak_action);
+
   G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->finalize (object);
 }
 
@@ -1929,20 +1980,36 @@ static gint
 gtk_font_chooser_widget_get_size (GtkFontChooser *chooser)
 {
   GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser);
+  PangoFontDescription *desc = gtk_font_chooser_widget_get_font_desc (fontchooser);
+
+  if (desc)
+    return pango_font_description_get_size (desc);
 
-  return pango_font_description_get_size (fontchooser->priv->font_desc);
+  return -1;
 }
 
 static gchar *
 gtk_font_chooser_widget_get_font (GtkFontChooserWidget *fontchooser)
 {
-  return pango_font_description_to_string (fontchooser->priv->font_desc);
+  PangoFontDescription *desc = gtk_font_chooser_widget_get_font_desc (fontchooser);
+
+  if (desc)
+    return pango_font_description_to_string (desc);
+
+  return NULL;
 }
 
 static PangoFontDescription *
 gtk_font_chooser_widget_get_font_desc (GtkFontChooserWidget *fontchooser)
 {
-  return fontchooser->priv->font_desc;
+  GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
+  GtkTreeSelection *selection;
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_face_list));
+  if (gtk_tree_selection_count_selected_rows (selection) > 0)
+    return fontchooser->priv->font_desc;
+
+  return NULL;
 }
 
 static void
@@ -1956,12 +2023,32 @@ gtk_font_chooser_widget_set_font (GtkFontChooserWidget *fontchooser,
 }
 
 static void
+selection_changed (GtkTreeSelection     *selection,
+                   GtkFontChooserWidget *fontchooser)
+{
+  GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
+
+  g_object_notify (G_OBJECT (fontchooser), "font");
+  g_object_notify (G_OBJECT (fontchooser), "font-desc");
+
+  if (gtk_tree_selection_count_selected_rows (selection) > 0)
+    {
+      g_simple_action_set_enabled (G_SIMPLE_ACTION (priv->tweak_action), TRUE);
+    }
+  else
+    {
+      g_simple_action_set_state (G_SIMPLE_ACTION (priv->tweak_action), g_variant_new_boolean (FALSE));
+      g_simple_action_set_enabled (G_SIMPLE_ACTION (priv->tweak_action), FALSE);
+    }
+}
+
+static void
 gtk_font_chooser_widget_ensure_selection (GtkFontChooserWidget *fontchooser)
 {
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
   GtkTreeSelection *selection;
   GtkTreeIter filter_iter;
-  
+
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_face_list));
 
   if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (priv->model), &priv->font_iter) &&
@@ -2944,20 +3031,9 @@ gtk_font_chooser_widget_handle_event (GtkWidget   *widget,
   return gtk_search_entry_handle_event (GTK_SEARCH_ENTRY (priv->search_entry), event);
 }
 
-void
-gtk_font_chooser_widget_tweak_font (GtkWidget *widget,
-                                    gboolean   tweak)
+GAction *
+gtk_font_chooser_widget_get_tweak_action (GtkWidget *widget)
 {
-  GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (widget);
-
-  if (tweak)
-    {
-      gtk_entry_grab_focus_without_selecting (GTK_ENTRY (fontchooser->priv->preview2));
-      gtk_stack_set_visible_child_name (GTK_STACK (fontchooser->priv->stack), "tweaks");
-    }
-  else
-    {
-      gtk_entry_grab_focus_without_selecting (GTK_ENTRY (fontchooser->priv->search_entry));
-      gtk_stack_set_visible_child_name (GTK_STACK (fontchooser->priv->stack), "list");
-    }
+  return GTK_FONT_CHOOSER_WIDGET (widget)->priv->tweak_action;
 }
+
diff --git a/gtk/gtkfontchooserwidgetprivate.h b/gtk/gtkfontchooserwidgetprivate.h
index 19a8eda..5abdc5e 100644
--- a/gtk/gtkfontchooserwidgetprivate.h
+++ b/gtk/gtkfontchooserwidgetprivate.h
@@ -25,8 +25,7 @@ G_BEGIN_DECLS
 gboolean gtk_font_chooser_widget_handle_event (GtkWidget   *widget,
                                                GdkEventKey *event);
 
-void  gtk_font_chooser_widget_tweak_font (GtkWidget *fontchooser,
-                                          gboolean   tweak);
+GAction *gtk_font_chooser_widget_get_tweak_action (GtkWidget *fontchooser);
 
 G_END_DECLS
 
diff --git a/gtk/ui/gtkfontchooserwidget.ui b/gtk/ui/gtkfontchooserwidget.ui
index ea0acc6..70fa80f 100644
--- a/gtk/ui/gtkfontchooserwidget.ui
+++ b/gtk/ui/gtkfontchooserwidget.ui
@@ -96,6 +96,7 @@
                             <child internal-child="selection">
                               <object class="GtkTreeSelection" id="treeview-selection1">
                                 <property name="mode">browse</property>
+                                <signal name="changed" handler="selection_changed"/>
                               </object>
                             </child>
                             <child>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]