[gtk+] shortcuts: Support direction-specific shortcuts



commit 9b041ae93060f22985ba2c100a1b97e50e615f48
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Nov 14 22:34:19 2015 -0500

    shortcuts: Support direction-specific shortcuts
    
    The prime example for direction-dependent shortcuts is using
    <Alt>Left or <Alt>Right to go back. Support this by adding a
    direction property to GtkShortcutsShortcut, and filtering by
    the current text direction.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=757888

 gtk/gtkshortcutsgroup.c    |   20 +++++++++++++--
 gtk/gtkshortcutssection.c  |   19 +++++++++++---
 gtk/gtkshortcutsshortcut.c |   57 +++++++++++++++++++++++++++++++++++++++++++-
 gtk/gtkshortcutswindow.c   |   28 +++++++++++++++++++--
 4 files changed, 113 insertions(+), 11 deletions(-)
---
diff --git a/gtk/gtkshortcutsgroup.c b/gtk/gtkshortcutsgroup.c
index 74adc6a..a90b30f 100644
--- a/gtk/gtkshortcutsgroup.c
+++ b/gtk/gtkshortcutsgroup.c
@@ -114,9 +114,13 @@ gtk_shortcuts_group_get_height (GtkShortcutsGroup *group)
   children = gtk_container_get_children (GTK_CONTAINER (group));
   for (l = children; l; l = l->next)
     {
-      if (GTK_IS_SHORTCUTS_SHORTCUT (l->data))
+      GtkWidget *child = l->data;
+
+      if (!gtk_widget_get_visible (child))
+        continue;
+      else if (GTK_IS_SHORTCUTS_SHORTCUT (child))
         height += 1;
-      else if (GTK_IS_SHORTCUTS_GESTURE (l->data))
+      else if (GTK_IS_SHORTCUTS_GESTURE (child))
         height += 2;
     }
   g_list_free (children);
@@ -165,6 +169,14 @@ gtk_shortcuts_group_get_property (GObject    *object,
 }
 
 static void
+gtk_shortcuts_group_direction_changed (GtkWidget        *widget,
+                                       GtkTextDirection  previous_dir)
+{
+  GTK_WIDGET_CLASS (gtk_shortcuts_group_parent_class)->direction_changed (widget, previous_dir);
+  g_object_notify (G_OBJECT (widget), "height");
+}
+
+static void
 gtk_shortcuts_group_set_property (GObject      *object,
                                   guint         prop_id,
                                   const GValue *value,
@@ -209,13 +221,15 @@ gtk_shortcuts_group_finalize (GObject *object)
 static void
 gtk_shortcuts_group_class_init (GtkShortcutsGroupClass *klass)
 {
-  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
 
   object_class->finalize = gtk_shortcuts_group_finalize;
   object_class->get_property = gtk_shortcuts_group_get_property;
   object_class->set_property = gtk_shortcuts_group_set_property;
 
+  widget_class->direction_changed = gtk_shortcuts_group_direction_changed;
   container_class->add = gtk_shortcuts_group_add;
 
   /**
diff --git a/gtk/gtkshortcutssection.c b/gtk/gtkshortcutssection.c
index 9d8de02..eb32ccb 100644
--- a/gtk/gtkshortcutssection.c
+++ b/gtk/gtkshortcutssection.c
@@ -557,12 +557,18 @@ gtk_shortcuts_section_reflow_groups (GtkShortcutsSection *self)
       if (n_rows == 0 || n_rows + height > self->max_height)
         {
           GtkWidget *column;
+          GtkSizeGroup *group;
 
           column = gtk_box_new (GTK_ORIENTATION_VERTICAL, 22);
           gtk_widget_show (column);
 
-          g_object_set_data_full (G_OBJECT (column), "accel-size-group", gtk_size_group_new 
(GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
-          g_object_set_data_full (G_OBJECT (column), "title-size-group", gtk_size_group_new 
(GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
+          group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+          gtk_size_group_set_ignore_hidden (group, TRUE);
+          g_object_set_data_full (G_OBJECT (column), "accel-size-group", group, g_object_unref);
+
+          group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+          gtk_size_group_set_ignore_hidden (group, TRUE);
+          g_object_set_data_full (G_OBJECT (column), "title-size-group", group, g_object_unref);
 
           if (n_columns % 2 == 0)
             {
@@ -598,14 +604,19 @@ gtk_shortcuts_section_reflow_groups (GtkShortcutsSection *self)
   if (n_columns % 2 == 1)
     {
       GtkWidget *column;
+      GtkSizeGroup *group;
       GList *content;
       guint n;
 
       column = gtk_box_new (GTK_ORIENTATION_VERTICAL, 22);
       gtk_widget_show (column);
 
-      g_object_set_data_full (G_OBJECT (column), "accel-size-group", gtk_size_group_new 
(GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
-      g_object_set_data_full (G_OBJECT (column), "title-size-group", gtk_size_group_new 
(GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
+      group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+      gtk_size_group_set_ignore_hidden (group, TRUE);
+      g_object_set_data_full (G_OBJECT (column), "accel-size-group", group, g_object_unref);
+      group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+      gtk_size_group_set_ignore_hidden (group, TRUE);
+      g_object_set_data_full (G_OBJECT (column), "title-size-group", group, g_object_unref);
 
       gtk_container_add (GTK_CONTAINER (current_page), column);
 
diff --git a/gtk/gtkshortcutsshortcut.c b/gtk/gtkshortcutsshortcut.c
index b4888a5..2885391 100644
--- a/gtk/gtkshortcutsshortcut.c
+++ b/gtk/gtkshortcutsshortcut.c
@@ -43,6 +43,8 @@ struct _GtkShortcutsShortcut
 
   GtkSizeGroup *accel_size_group;
   GtkSizeGroup *title_size_group;
+
+  GtkTextDirection direction;
 };
 
 struct _GtkShortcutsShortcutClass
@@ -58,6 +60,7 @@ enum {
   PROP_TITLE,
   PROP_ACCEL_SIZE_GROUP,
   PROP_TITLE_SIZE_GROUP,
+  PROP_DIRECTION,
   LAST_PROP
 };
 
@@ -105,12 +108,47 @@ gtk_shortcuts_shortcut_get_property (GObject    *object,
       g_value_set_string (value, gtk_shortcut_label_get_accelerator (self->accelerator));
       break;
 
+    case PROP_DIRECTION:
+      g_value_set_enum (value, self->direction);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
 }
 
 static void
+update_visible (GtkShortcutsShortcut *self)
+{
+  if (self->direction == GTK_TEXT_DIR_NONE ||
+      self->direction == gtk_widget_get_direction (GTK_WIDGET (self)))
+    gtk_widget_set_visible (GTK_WIDGET (self), TRUE);
+  else
+    gtk_widget_set_visible (GTK_WIDGET (self), FALSE);
+}
+
+static void
+gtk_shortcuts_shortcut_set_direction (GtkShortcutsShortcut *self,
+                                      GtkTextDirection      direction)
+{
+  if (self->direction == direction)
+    return;
+
+  self->direction = direction;
+
+  update_visible (self);
+}
+
+static void
+gtk_shortcuts_shortcut_direction_changed (GtkWidget        *widget,
+                                          GtkTextDirection  previous_dir)
+{
+  update_visible (GTK_SHORTCUTS_SHORTCUT (widget));
+
+  GTK_WIDGET_CLASS (gtk_shortcuts_shortcut_parent_class)->direction_changed (widget, previous_dir);
+}
+
+static void
 gtk_shortcuts_shortcut_set_property (GObject      *object,
                                      guint         prop_id,
                                      const GValue *value,
@@ -136,6 +174,10 @@ gtk_shortcuts_shortcut_set_property (GObject      *object,
       gtk_shortcuts_shortcut_set_title_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value)));
       break;
 
+    case PROP_DIRECTION:
+      gtk_shortcuts_shortcut_set_direction (self, g_value_get_enum (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -169,13 +211,16 @@ gtk_shortcuts_shortcut_child_type (GtkContainer *container)
 static void
 gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
 {
-  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
 
   object_class->finalize = gtk_shortcuts_shortcut_finalize;
   object_class->get_property = gtk_shortcuts_shortcut_get_property;
   object_class->set_property = gtk_shortcuts_shortcut_set_property;
 
+  widget_class->direction_changed = gtk_shortcuts_shortcut_direction_changed;
+
   container_class->add = gtk_shortcuts_shortcut_add;
   container_class->child_type = gtk_shortcuts_shortcut_child_type;
 
@@ -248,6 +293,14 @@ gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
                          GTK_TYPE_SIZE_GROUP,
                          (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
 
+  properties[PROP_DIRECTION] =
+    g_param_spec_enum ("direction",
+                       P_("Direction"),
+                       P_("Direction"),
+                       GTK_TYPE_TEXT_DIRECTION,
+                       GTK_TEXT_DIR_NONE,
+                       (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_properties (object_class, LAST_PROP, properties);
 }
 
@@ -257,6 +310,8 @@ gtk_shortcuts_shortcut_init (GtkShortcutsShortcut *self)
   gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL);
   gtk_box_set_spacing (GTK_BOX (self), 12);
 
+  self->direction = GTK_TEXT_DIR_NONE;
+
   self->accelerator = g_object_new (GTK_TYPE_SHORTCUT_LABEL,
                                     "visible", TRUE,
                                     NULL);
diff --git a/gtk/gtkshortcutswindow.c b/gtk/gtkshortcutswindow.c
index f94f700..721fc48 100644
--- a/gtk/gtkshortcutswindow.c
+++ b/gtk/gtkshortcutswindow.c
@@ -184,6 +184,7 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
   gchar *title = NULL;
   gchar *hash_key = NULL;
   GIcon *icon = NULL;
+  GtkTextDirection direction;
   gchar *str;
   gchar *keywords;
 
@@ -192,6 +193,7 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
       g_object_get (child,
                     "accelerator", &accelerator,
                     "title", &title,
+                    "direction", &direction,
                     NULL);
 
       hash_key = g_strdup_printf ("%s-%s", title, accelerator);
@@ -206,9 +208,9 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
       g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1));
 
       item = g_object_new (GTK_TYPE_SHORTCUTS_SHORTCUT,
-                           "visible", TRUE,
                            "accelerator", accelerator,
                            "title", title,
+                           "direction", direction,
                            "accel-size-group", priv->search_image_group,
                            "title-size-group", priv->search_text_group,
                            NULL);
@@ -244,7 +246,6 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
       g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1));
 
       item = g_object_new (GTK_TYPE_SHORTCUTS_GESTURE,
-                           "visible", TRUE,
                            "title", title,
                            "subtitle", subtitle,
                            "icon", icon,
@@ -379,6 +380,22 @@ gtk_shortcuts_window__list_box__row_activated (GtkShortcutsWindow *self,
   gtk_widget_hide (GTK_WIDGET (priv->popover));
 }
 
+static gboolean
+hidden_by_direction (GtkWidget *widget)
+{
+  if (GTK_IS_SHORTCUTS_SHORTCUT (widget))
+    {
+      GtkTextDirection dir;
+
+      g_object_get (widget, "direction", &dir, NULL);
+      if (dir != GTK_TEXT_DIR_NONE &&
+          dir != gtk_widget_get_direction (widget))
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
 static void
 gtk_shortcuts_window__entry__changed (GtkShortcutsWindow *self,
                                      GtkSearchEntry      *search_entry)
@@ -400,6 +417,7 @@ gtk_shortcuts_window__entry__changed (GtkShortcutsWindow *self,
         {
           gtk_stack_set_visible_child_name (priv->stack, priv->last_section_name);
           return;
+
         }
     }
 
@@ -423,7 +441,11 @@ gtk_shortcuts_window__entry__changed (GtkShortcutsWindow *self,
       const gchar *keywords = value;
       gboolean match;
 
-      match = strstr (keywords, downcase) != NULL;
+      if (hidden_by_direction (widget))
+        match = FALSE;
+      else
+        match = strstr (keywords, downcase) != NULL;
+
       gtk_widget_set_visible (widget, match);
       has_result |= match;
     }


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