[gnome-builder] Preferences: navigate to next GtkEntry with single tab/arrow



commit ae543d5a87d02e64f75528ca751f0dfb3f3d08a3
Author: kritarth <kritarth 3010 gmail com>
Date:   Fri Dec 23 07:22:22 2016 +0530

    Preferences: navigate to next GtkEntry with single tab/arrow
    
    Earlier, on TAB/arrow the focus was shifted from GtkEntry to next
    GtkListBoxRow. This required one more tab/arrow key press to focus
    the required GtkEntry. Continued work on an implementation by
    Sébastien Lafargue (https://paste.fedoraproject.org/506997/).
    Implemented single tab_backward to navigate to previous GtkEntry.
    This was achieved with the help of 'focus' signal.
    If (GtkEntry is focused and direction=TAB_BACKWARD) then
            shift focus to GtkListBoxRow of that GtkEntry
    
    https://bugzilla.gnome.org/show_bug.cgi?id=764219

 libide/preferences/ide-preferences-entry.c         |   10 ++++
 libide/preferences/ide-preferences-entry.h         |    1 +
 libide/preferences/ide-preferences-group-private.h |    3 +
 libide/preferences/ide-preferences-group.c         |   56 ++++++++++++++++++++
 4 files changed, 70 insertions(+), 0 deletions(-)
---
diff --git a/libide/preferences/ide-preferences-entry.c b/libide/preferences/ide-preferences-entry.c
index d69199a..8a588a9 100644
--- a/libide/preferences/ide-preferences-entry.c
+++ b/libide/preferences/ide-preferences-entry.c
@@ -214,3 +214,13 @@ ide_preferences_entry_get_title_widget (IdePreferencesEntry *self)
 
   return GTK_WIDGET (priv->title);
 }
+
+GtkWidget *
+ide_preferences_entry_get_entry_widget (IdePreferencesEntry *self)
+{
+  IdePreferencesEntryPrivate *priv = ide_preferences_entry_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_PREFERENCES_ENTRY (self), NULL);
+
+  return GTK_WIDGET (priv->entry);
+}
diff --git a/libide/preferences/ide-preferences-entry.h b/libide/preferences/ide-preferences-entry.h
index a11cbd8..9596590 100644
--- a/libide/preferences/ide-preferences-entry.h
+++ b/libide/preferences/ide-preferences-entry.h
@@ -34,6 +34,7 @@ struct _IdePreferencesEntryClass
   IdePreferencesBinClass parent_class;
 };
 
+GtkWidget *ide_preferences_entry_get_entry_widget (IdePreferencesEntry *self);
 GtkWidget *ide_preferences_entry_get_title_widget (IdePreferencesEntry *self);
 
 G_END_DECLS
diff --git a/libide/preferences/ide-preferences-group-private.h 
b/libide/preferences/ide-preferences-group-private.h
index 2502c2a..5ad496c 100644
--- a/libide/preferences/ide-preferences-group-private.h
+++ b/libide/preferences/ide-preferences-group-private.h
@@ -37,6 +37,9 @@ struct _IdePreferencesGroup
   GtkFrame   *list_box_frame;
 
   GPtrArray  *widgets;
+
+  GtkListBoxRow *last_focused;
+  guint          last_focused_tab_backward : 1;
 };
 
 void  _ide_preferences_group_set_map  (IdePreferencesGroup *self,
diff --git a/libide/preferences/ide-preferences-group.c b/libide/preferences/ide-preferences-group.c
index 2ab71c6..d48878a 100644
--- a/libide/preferences/ide-preferences-group.c
+++ b/libide/preferences/ide-preferences-group.c
@@ -18,6 +18,7 @@
 
 #include "ide-preferences-bin.h"
 #include "ide-preferences-bin-private.h"
+#include "ide-preferences-entry.h"
 #include "ide-preferences-group.h"
 #include "ide-preferences-group-private.h"
 
@@ -274,6 +275,51 @@ ide_preferences_group_init (IdePreferencesGroup *self)
                            G_CONNECT_SWAPPED);
 }
 
+static gboolean
+ide_preferences_group_row_focus (IdePreferencesGroup *self,
+                                 GtkDirectionType     dir,
+                                 GtkListBoxRow       *row)
+{
+  GtkWidget *child;
+  GtkWidget *entry;
+
+  self->last_focused_tab_backward = (dir == GTK_DIR_TAB_BACKWARD);
+
+  child = gtk_bin_get_child (GTK_BIN (row));
+
+  if (IDE_IS_PREFERENCES_ENTRY (child))
+    {
+      entry = ide_preferences_entry_get_entry_widget ( IDE_PREFERENCES_ENTRY (child));
+      if (GTK_IS_ENTRY (entry) &&
+          gtk_widget_is_focus (entry) &&
+          dir == GTK_DIR_TAB_BACKWARD)
+        gtk_widget_grab_focus (GTK_WIDGET (row));
+    }
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static void
+ide_preferences_group_row_grab_focus (IdePreferencesGroup *self,
+                                      GtkListBoxRow       *row)
+{
+  GtkWidget *child;
+  GtkListBoxRow *last_focused;
+
+  last_focused = self->last_focused;
+  child = gtk_bin_get_child (GTK_BIN (row));
+  if (IDE_IS_PREFERENCES_ENTRY (child))
+    {
+      self->last_focused = row;
+      if (row != last_focused || !self->last_focused_tab_backward)
+        gtk_widget_activate (child);
+
+      return;
+    }
+
+  self->last_focused = NULL;
+}
+
 void
 ide_preferences_group_add (IdePreferencesGroup *self,
                            GtkWidget           *widget)
@@ -304,6 +350,16 @@ ide_preferences_group_add (IdePreferencesGroup *self,
                             NULL);
 
       gtk_container_add (GTK_CONTAINER (self->list_box), row);
+      g_signal_connect_object (row,
+                               "focus",
+                               G_CALLBACK (ide_preferences_group_row_focus),
+                               self,
+                               G_CONNECT_SWAPPED);
+      g_signal_connect_object (row,
+                               "grab-focus",
+                               G_CALLBACK (ide_preferences_group_row_grab_focus),
+                               self,
+                               G_CONNECT_AFTER | G_CONNECT_SWAPPED);
     }
   else
     {


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