[gnome-builder] layout: add helper to focus grid neighbors



commit f54f5ed2eea75f67fae3e9af36afb3bc302730e0
Author: Christian Hergert <chergert redhat com>
Date:   Thu Jul 20 17:51:00 2017 -0700

    layout: add helper to focus grid neighbors

 libide/layout/ide-layout-grid.c |  104 +++++++++++++++++++++++++++++++++++++++
 libide/layout/ide-layout-grid.h |    2 +
 2 files changed, 106 insertions(+), 0 deletions(-)
---
diff --git a/libide/layout/ide-layout-grid.c b/libide/layout/ide-layout-grid.c
index 719d531..4b7ce5c 100644
--- a/libide/layout/ide-layout-grid.c
+++ b/libide/layout/ide-layout-grid.c
@@ -958,3 +958,107 @@ ide_layout_grid_count_views (IdeLayoutGrid *self)
 
   return count;
 }
+
+/**
+ * ide_layout_grid_focus_neighbor:
+ * @self: An #IdeLayoutGrid
+ * @dir: the direction for the focus change
+ *
+ * Attempts to focus a neighbor #IdeLayoutView in the grid based on
+ * the direction requested.
+ *
+ * If an #IdeLayoutView was focused, it will be returned to the caller.
+ *
+ * Returns: (transfer none) (nullable): An #IdeLayoutView or %NULL
+ */
+IdeLayoutView *
+ide_layout_grid_focus_neighbor (IdeLayoutGrid    *self,
+                                GtkDirectionType  dir)
+{
+  IdeLayoutGridColumn *column;
+  IdeLayoutStack *stack;
+  IdeLayoutView *view = NULL;
+  guint stack_pos = 0;
+  guint column_pos = 0;
+  guint n_children;
+
+  g_return_val_if_fail (IDE_IS_LAYOUT_GRID (self), NULL);
+  g_return_val_if_fail (dir <= GTK_DIR_RIGHT, NULL);
+
+  /* Make sure we have a current view and stack */
+  if (NULL == (stack = ide_layout_grid_get_current_stack (self)) ||
+      NULL == (column = ide_layout_grid_get_current_column (self)))
+    return NULL;
+
+  gtk_container_child_get (GTK_CONTAINER (self), GTK_WIDGET (column),
+                           "index", &column_pos,
+                           NULL);
+
+  gtk_container_child_get (GTK_CONTAINER (column), GTK_WIDGET (stack),
+                           "index", &stack_pos,
+                           NULL);
+
+  switch (dir)
+    {
+    case GTK_DIR_DOWN:
+      n_children = dzl_multi_paned_get_n_children (DZL_MULTI_PANED (column));
+      if (n_children - stack_pos == 1)
+        return NULL;
+      stack = IDE_LAYOUT_STACK (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (column), stack_pos + 1));
+      view = ide_layout_stack_get_visible_child (stack);
+      break;
+
+    case GTK_DIR_RIGHT:
+      n_children = dzl_multi_paned_get_n_children (DZL_MULTI_PANED (self));
+      if (n_children - column_pos == 1)
+        return NULL;
+      column = IDE_LAYOUT_GRID_COLUMN (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (self), column_pos + 
1));
+      stack = IDE_LAYOUT_STACK (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (column), 0));
+      view = ide_layout_stack_get_visible_child (stack);
+      break;
+
+    case GTK_DIR_UP:
+      if (stack_pos == 0)
+        return NULL;
+      stack = IDE_LAYOUT_STACK (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (column), stack_pos - 1));
+      view = ide_layout_stack_get_visible_child (stack);
+      break;
+
+    case GTK_DIR_LEFT:
+      if (column_pos == 0)
+        return NULL;
+      column = IDE_LAYOUT_GRID_COLUMN (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (self), column_pos - 
1));
+      stack = IDE_LAYOUT_STACK (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (column), 0));
+      view = ide_layout_stack_get_visible_child (stack);
+      break;
+
+    case GTK_DIR_TAB_FORWARD:
+      if (!ide_layout_grid_focus_neighbor (self, GTK_DIR_DOWN) &&
+          !ide_layout_grid_focus_neighbor (self, GTK_DIR_RIGHT))
+        {
+          column = IDE_LAYOUT_GRID_COLUMN (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (self), 0));
+          stack = IDE_LAYOUT_STACK (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (column), 0));
+          view = ide_layout_stack_get_visible_child (stack);
+        }
+      break;
+
+    case GTK_DIR_TAB_BACKWARD:
+      if (!ide_layout_grid_focus_neighbor (self, GTK_DIR_UP) &&
+          !ide_layout_grid_focus_neighbor (self, GTK_DIR_LEFT))
+        {
+          n_children = dzl_multi_paned_get_n_children (DZL_MULTI_PANED (self));
+          column = IDE_LAYOUT_GRID_COLUMN (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (self), n_children 
- 1));
+          stack = IDE_LAYOUT_STACK (dzl_multi_paned_get_nth_child (DZL_MULTI_PANED (column), 0));
+          view = ide_layout_stack_get_visible_child (stack);
+        }
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+
+  if (view != NULL)
+    gtk_widget_child_focus (GTK_WIDGET (view), GTK_DIR_TAB_FORWARD);
+
+  return view;
+}
diff --git a/libide/layout/ide-layout-grid.h b/libide/layout/ide-layout-grid.h
index 9492a44..c61528f 100644
--- a/libide/layout/ide-layout-grid.h
+++ b/libide/layout/ide-layout-grid.h
@@ -49,6 +49,8 @@ struct _IdeLayoutGridClass
 GtkWidget           *ide_layout_grid_new                (void);
 IdeLayoutGridColumn *ide_layout_grid_get_nth_column     (IdeLayoutGrid       *self,
                                                          gint                 nth);
+IdeLayoutView       *ide_layout_grid_focus_neighbor     (IdeLayoutGrid       *self,
+                                                         GtkDirectionType     dir);
 IdeLayoutGridColumn *ide_layout_grid_get_current_column (IdeLayoutGrid       *self);
 void                 ide_layout_grid_set_current_column (IdeLayoutGrid       *self,
                                                          IdeLayoutGridColumn *column);


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