[gnome-builder/editor-layout] tabs: more wip on tabs.
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/editor-layout] tabs: more wip on tabs.
- Date: Wed, 26 Nov 2014 03:48:30 +0000 (UTC)
commit bf835348fd9332c98fe0b50a250b68fa217461a1
Author: Christian Hergert <christian hergert me>
Date: Tue Nov 25 18:01:57 2014 -0800
tabs: more wip on tabs.
src/resources/keybindings/default.ini | 8 ++
src/tabs/gb-tab-grid.c | 156 ++++++++++++++++++++++++++++++++-
src/tabs/gb-tab-stack.c | 44 ++++++++--
src/tabs/gb-tab-stack.h | 1 +
4 files changed, 202 insertions(+), 7 deletions(-)
---
diff --git a/src/resources/keybindings/default.ini b/src/resources/keybindings/default.ini
index f3faae5..65fb4ef 100644
--- a/src/resources/keybindings/default.ini
+++ b/src/resources/keybindings/default.ini
@@ -30,3 +30,11 @@ save-as = <Control><Shift>S
toggle-preview = <Control><Alt>P
scroll-up = <Control>Y
scroll-down = <Control>E
+
+[tabs]
+next = <Control>J
+previous = <Control>K
+left = <Control>H
+right = <Control>L
+move-left = <Control><Shift>H
+move-right = <Control><Shift>L
diff --git a/src/tabs/gb-tab-grid.c b/src/tabs/gb-tab-grid.c
index 720225a..bea0605 100644
--- a/src/tabs/gb-tab-grid.c
+++ b/src/tabs/gb-tab-grid.c
@@ -27,7 +27,10 @@
struct _GbTabGridPrivate
{
- GtkWidget *top_hpaned;
+ GSimpleActionGroup *actions;
+
+ GtkWidget *top_hpaned;
+ GbTabStack *last_focused_stack;
};
G_DEFINE_TYPE_WITH_PRIVATE (GbTabGrid, gb_tab_grid, GTK_TYPE_BIN)
@@ -35,6 +38,40 @@ G_DEFINE_TYPE_WITH_PRIVATE (GbTabGrid, gb_tab_grid, GTK_TYPE_BIN)
static GtkWidget *
gb_tab_grid_get_first_stack (GbTabGrid*);
+static GbTabStack *
+gb_tab_grid_get_last_focused (GbTabGrid *grid)
+{
+ g_return_val_if_fail (GB_IS_TAB_GRID (grid), NULL);
+
+ return grid->priv->last_focused_stack;
+}
+
+static void
+gb_tab_grid_set_last_focused (GbTabGrid *grid,
+ GbTabStack *stack)
+{
+ GbTabGridPrivate *priv;
+
+ g_return_if_fail (GB_IS_TAB_GRID (grid));
+ g_return_if_fail (!stack || GB_TAB_STACK (stack));
+
+ priv = grid->priv;
+
+ if (priv->last_focused_stack)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (priv->last_focused_stack),
+ (gpointer *)&priv->last_focused_stack);
+ priv->last_focused_stack = NULL;
+ }
+
+ if (stack)
+ {
+ priv->last_focused_stack = stack;
+ g_object_add_weak_pointer (G_OBJECT (stack),
+ (gpointer *)&priv->last_focused_stack);
+ }
+}
+
GtkWidget *
gb_tab_grid_new (void)
{
@@ -387,6 +424,109 @@ gb_tab_grid_focus_previous_view (GbTabGrid *self,
EXIT;
}
+static void
+on_next_tab (GSimpleAction *action,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ GbTabGrid *self = user_data;
+ GbTabStack *last_focused_stack = NULL;
+
+ ENTRY;
+
+ g_return_if_fail (GB_IS_TAB_GRID (self));
+
+ last_focused_stack = gb_tab_grid_get_last_focused (self);
+ if (last_focused_stack)
+ if (!gb_tab_stack_focus_next (last_focused_stack))
+ gb_tab_stack_focus_first (last_focused_stack);
+
+ EXIT;
+}
+
+static void
+on_previous_tab (GSimpleAction *action,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ GbTabGrid *self = user_data;
+ GbTabStack *last_focused_stack = NULL;
+
+ ENTRY;
+
+ g_return_if_fail (GB_IS_TAB_GRID (self));
+
+ last_focused_stack = gb_tab_grid_get_last_focused (self);
+ if (last_focused_stack)
+ if (!gb_tab_stack_focus_previous (last_focused_stack))
+ gb_tab_stack_focus_last (last_focused_stack);
+
+ EXIT;
+}
+
+static void
+gb_tab_grid_on_set_focus (GbTabGrid *grid,
+ GtkWidget *widget,
+ GtkWindow *window)
+{
+ g_return_if_fail (GB_IS_TAB_GRID (grid));
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ if (widget)
+ {
+ while (widget && !GB_IS_TAB_STACK (widget))
+ widget = gtk_widget_get_parent (widget);
+
+ if (GB_IS_TAB_STACK (widget))
+ gb_tab_grid_set_last_focused (grid, GB_TAB_STACK (widget));
+ }
+}
+
+static void
+gb_tab_grid_realize (GtkWidget *widget)
+{
+ GtkWidget *toplevel;
+ GbTabGrid *grid = (GbTabGrid *)widget;
+
+ g_return_if_fail (GB_IS_TAB_GRID (grid));
+
+ GTK_WIDGET_CLASS (gb_tab_grid_parent_class)->realize (widget);
+
+ toplevel = gtk_widget_get_toplevel (widget);
+
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ /*
+ * WORKAROUND:
+ *
+ * We need to register our actions with the toplevel or they wont be
+ * taken into account when activating accelerators. See bugzilla bug
+ * 740682 for a patch to Gtk+.
+ */
+ gtk_widget_insert_action_group (toplevel, "tabs",
+ G_ACTION_GROUP (grid->priv->actions));
+
+ /*
+ * Track focus so we know where we are moving to/from in the stack.
+ */
+ g_signal_connect_object (toplevel,
+ "set-focus",
+ G_CALLBACK (gb_tab_grid_on_set_focus),
+ widget,
+ G_CONNECT_SWAPPED);
+ }
+}
+
+static void
+gb_tab_grid_finalize (GObject *object)
+{
+ GbTabGridPrivate *priv = GB_TAB_GRID (object)->priv;
+
+ g_clear_object (&priv->actions);
+
+ G_OBJECT_CLASS (gb_tab_grid_parent_class)->finalize (object);
+}
+
/**
* gb_tab_grid_class_init:
* @klass: (in): A #GbTabGridClass.
@@ -396,8 +536,14 @@ gb_tab_grid_focus_previous_view (GbTabGrid *self,
static void
gb_tab_grid_class_init (GbTabGridClass *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 = gb_tab_grid_finalize;
+
+ widget_class->realize = gb_tab_grid_realize;
+
container_class->add = gb_tab_grid_add;
}
@@ -410,11 +556,19 @@ gb_tab_grid_class_init (GbTabGridClass *klass)
static void
gb_tab_grid_init (GbTabGrid *self)
{
+ static const GActionEntry entries[] = {
+ { "next", on_next_tab },
+ { "previous", on_previous_tab },
+ };
GtkWidget *paned;
GtkWidget *stack;
self->priv = gb_tab_grid_get_instance_private (self);
+ self->priv->actions = g_simple_action_group_new ();
+ g_action_map_add_action_entries (G_ACTION_MAP (self->priv->actions),
+ entries, G_N_ELEMENTS (entries), self);
+
self->priv->top_hpaned =
g_object_new (GTK_TYPE_PANED,
"orientation", GTK_ORIENTATION_HORIZONTAL,
diff --git a/src/tabs/gb-tab-stack.c b/src/tabs/gb-tab-stack.c
index 3ccc553..fc47544 100644
--- a/src/tabs/gb-tab-stack.c
+++ b/src/tabs/gb-tab-stack.c
@@ -16,8 +16,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define G_LOG_DOMAIN "tab-stack"
+
#include <glib/gi18n.h>
+#include "gb-log.h"
#include "gb-tab-stack.h"
struct _GbTabStackPrivate
@@ -163,16 +166,18 @@ gb_tab_stack_focus_next (GbTabStack *stack)
GtkTreeIter iter;
gboolean ret = FALSE;
+ ENTRY;
+
g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
if (!(child = gtk_stack_get_visible_child (stack->priv->stack)))
- return FALSE;
+ RETURN (FALSE);
if (gb_tab_stack_get_tab_iter (stack, GB_TAB (child), &iter) &&
gtk_tree_model_iter_next (GTK_TREE_MODEL (stack->priv->store), &iter))
ret = gb_tab_stack_focus_iter (stack, &iter);
- return ret;
+ RETURN (ret);
}
gboolean
@@ -182,16 +187,18 @@ gb_tab_stack_focus_previous (GbTabStack *stack)
GtkTreeIter iter;
gboolean ret = FALSE;
+ ENTRY;
+
g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
if (!(child = gtk_stack_get_visible_child (stack->priv->stack)))
- return FALSE;
+ RETURN (FALSE);
if (gb_tab_stack_get_tab_iter (stack, GB_TAB (child), &iter) &&
gtk_tree_model_iter_previous (GTK_TREE_MODEL (stack->priv->store), &iter))
ret = gb_tab_stack_focus_iter (stack, &iter);
- return ret;
+ RETURN (ret);
}
gboolean
@@ -199,13 +206,38 @@ gb_tab_stack_focus_first (GbTabStack *stack)
{
GtkTreeIter iter;
+ ENTRY;
+
g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (stack->priv->store),
&iter))
- return gb_tab_stack_focus_iter (stack, &iter);
+ RETURN (gb_tab_stack_focus_iter (stack, &iter));
- return FALSE;
+ RETURN (FALSE);
+}
+
+gboolean
+gb_tab_stack_focus_last (GbTabStack *stack)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ guint n_children;
+
+ ENTRY;
+
+ g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
+
+ model = GTK_TREE_MODEL (stack->priv->store);
+ n_children = gtk_tree_model_iter_n_children (model, NULL);
+
+ if (n_children != 0)
+ {
+ if (gtk_tree_model_iter_nth_child (model, &iter, NULL, n_children-1))
+ RETURN (gb_tab_stack_focus_iter (stack, &iter));
+ }
+
+ RETURN (FALSE);
}
gboolean
diff --git a/src/tabs/gb-tab-stack.h b/src/tabs/gb-tab-stack.h
index 6d13fa5..1779dbf 100644
--- a/src/tabs/gb-tab-stack.h
+++ b/src/tabs/gb-tab-stack.h
@@ -58,6 +58,7 @@ void gb_tab_stack_remove_tab (GbTabStack *stack,
GbTab *tab);
guint gb_tab_stack_get_n_tabs (GbTabStack *stack);
gboolean gb_tab_stack_focus_first (GbTabStack *stack);
+gboolean gb_tab_stack_focus_last (GbTabStack *stack);
gboolean gb_tab_stack_focus_next (GbTabStack *stack);
gboolean gb_tab_stack_focus_previous (GbTabStack *stack);
gboolean gb_tab_stack_focus_tab (GbTabStack *stack,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]