[gnome-builder/editor-layout] stack: do move buttons with custom callback



commit cbbd29d9398eddb8b78b0a430640a653c1d75add
Author: Christian Hergert <christian hergert me>
Date:   Wed Nov 26 02:09:15 2014 -0800

    stack: do move buttons with custom callback
    
    this allows us to make them insensitive unlike with the action which is
    global to all stacks.

 src/resources/ui/gb-tab-stack.ui |    4 +-
 src/tabs/gb-tab-grid.h           |    2 +
 src/tabs/gb-tab-stack.c          |  153 ++++++++++++++++++++++++++------------
 src/tabs/gb-tab-stack.h          |    8 +-
 4 files changed, 114 insertions(+), 53 deletions(-)
---
diff --git a/src/resources/ui/gb-tab-stack.ui b/src/resources/ui/gb-tab-stack.ui
index 631e011..ca72728 100644
--- a/src/resources/ui/gb-tab-stack.ui
+++ b/src/resources/ui/gb-tab-stack.ui
@@ -13,7 +13,7 @@
         <child>
           <object class="GtkButton" id="move_left">
             <property name="visible">true</property>
-            <property name="action_name">tabs.move-left</property>
+            <property name="sensitive">false</property>
             <property name="tooltip_text">Move tab to the left</property>
             <style>
               <class name="image-button"/>
@@ -30,7 +30,7 @@
         <child>
           <object class="GtkButton" id="move_right">
             <property name="visible">true</property>
-            <property name="action_name">tabs.move-right</property>
+            <property name="sensitive">false</property>
             <property name="tooltip_text">Move tab to the right</property>
             <style>
               <class name="image-button"/>
diff --git a/src/tabs/gb-tab-grid.h b/src/tabs/gb-tab-grid.h
index 0230b3e..3a1f8b7 100644
--- a/src/tabs/gb-tab-grid.h
+++ b/src/tabs/gb-tab-grid.h
@@ -55,6 +55,8 @@ GType      gb_tab_grid_get_type           (void) G_GNUC_CONST;
 GbTab     *gb_tab_grid_get_active         (GbTabGrid *grid);
 void       gb_tab_grid_focus_tab          (GbTabGrid *grid,
                                            GbTab     *tab);
+void       gb_tab_grid_move_tab_left      (GbTabGrid *grid,
+                                           GbTab     *tab);
 void       gb_tab_grid_move_tab_right     (GbTabGrid *grid,
                                            GbTab     *tab);
 void       gb_tab_grid_focus_next_tab     (GbTabGrid *grid,
diff --git a/src/tabs/gb-tab-stack.c b/src/tabs/gb-tab-stack.c
index 549176d..04825a4 100644
--- a/src/tabs/gb-tab-stack.c
+++ b/src/tabs/gb-tab-stack.c
@@ -20,6 +20,7 @@
 
 #include <glib/gi18n.h>
 
+#include "gb-tab-grid.h"
 #include "gb-log.h"
 #include "gb-tab-stack.h"
 
@@ -28,21 +29,20 @@ struct _GbTabStackPrivate
   GtkButton    *close;
   GtkComboBox  *combo;
   GtkStack     *controls;
+  GtkButton    *move_left;
+  GtkButton    *move_right;
   GtkStack     *stack;
   GtkListStore *store;
 };
 
-enum
-{
-  PROP_0,
-  LAST_PROP
-};
-
 G_DEFINE_TYPE_WITH_PRIVATE (GbTabStack, gb_tab_stack, GTK_TYPE_BOX)
 
-#if 0
-static GParamSpec *gParamSpecs [LAST_PROP];
-#endif
+enum {
+  CHANGED,
+  LAST_SIGNAL
+};
+
+static guint gSignals [LAST_SIGNAL];
 
 GtkWidget *
 gb_tab_stack_new (void)
@@ -95,9 +95,10 @@ gb_tab_stack_get_tab_iter (GbTabStack  *stack,
   g_return_val_if_fail (GB_IS_TAB_STACK (stack), FALSE);
   g_return_val_if_fail (iter, FALSE);
 
-  gtk_container_child_get (GTK_CONTAINER (stack->priv->stack), GTK_WIDGET (tab),
-                           "position", &position,
-                           NULL);
+  if (gtk_widget_get_parent (GTK_WIDGET (tab)) == GTK_WIDGET (stack->priv->stack))
+    gtk_container_child_get (GTK_CONTAINER (stack->priv->stack), GTK_WIDGET (tab),
+                             "position", &position,
+                             NULL);
 
   if (position != -1)
     {
@@ -193,6 +194,8 @@ gb_tab_stack_remove_tab (GbTabStack *stack,
       else
         gb_tab_stack_focus_iter (stack, &iter);
     }
+
+  g_signal_emit (stack, gSignals [CHANGED], 0);
 }
 
 gboolean
@@ -312,7 +315,6 @@ gb_tab_stack_combobox_changed (GbTabStack  *stack,
   GbTab *tab = NULL;
 
   g_return_if_fail (GB_IS_TAB_STACK (stack));
-  g_print ("changed\n");
 
   model = gtk_combo_box_get_model (combobox);
 
@@ -329,8 +331,6 @@ gb_tab_stack_combobox_changed (GbTabStack  *stack,
 
           if ((controls = gb_tab_get_controls (tab)))
             gtk_stack_set_visible_child (stack->priv->controls, controls);
-
-          g_print ("Controls: %p\n", controls);
         }
       else
         {
@@ -351,12 +351,22 @@ gb_tab_stack_queue_draw (gpointer data)
   return G_SOURCE_REMOVE;
 }
 
-GtkWidget *
+GbTab *
 gb_tab_stack_get_active (GbTabStack *stack)
 {
   g_return_val_if_fail (GB_IS_TAB_STACK (stack), NULL);
 
-  return gtk_stack_get_visible_child (stack->priv->stack);
+  return GB_TAB (gtk_stack_get_visible_child (stack->priv->stack));
+}
+
+static void
+gb_tab_stack_tab_closed (GbTabStack *stack,
+                         GbTab      *tab)
+{
+  g_return_if_fail (GB_IS_TAB_STACK (stack));
+  g_return_if_fail (GB_IS_TAB (tab));
+
+  gb_tab_stack_remove_tab (stack, tab);
 }
 
 static void
@@ -380,10 +390,17 @@ gb_tab_stack_add_tab (GbTabStack *stack,
 
   /* TODO: need to disconnect on (re)move */
   g_signal_connect_object (tab,
+                           "close",
+                           G_CALLBACK (gb_tab_stack_tab_closed),
+                           stack,
+                           G_CONNECT_SWAPPED);
+  g_signal_connect_object (tab,
                            "notify::title",
                            G_CALLBACK (gb_tab_stack_queue_draw),
                            stack,
                            G_CONNECT_SWAPPED);
+
+  g_signal_emit (stack, gSignals [CHANGED], 0);
 }
 
 static void
@@ -444,68 +461,96 @@ gb_tab_stack_grab_focus (GtkWidget *widget)
 }
 
 static void
-gb_tab_stack_finalize (GObject *object)
+gb_tab_stack_real_changed (GbTabStack *stack)
+{
+  gboolean sensitive;
+
+  g_return_if_fail (GB_IS_TAB_STACK (stack));
+
+  sensitive = !!gtk_stack_get_visible_child (stack->priv->stack);
+  gtk_widget_set_sensitive (GTK_WIDGET (stack->priv->move_left), sensitive);
+  gtk_widget_set_sensitive (GTK_WIDGET (stack->priv->move_right), sensitive);
+}
+
+static GbTabGrid *
+get_grid (GbTabStack *stack)
 {
-  G_OBJECT_CLASS (gb_tab_stack_parent_class)->finalize (object);
+  GtkWidget *widget;
+
+  widget = GTK_WIDGET (stack);
+
+  while (widget && !GB_IS_TAB_GRID (widget))
+    widget = gtk_widget_get_parent (widget);
+
+  return (GbTabGrid *)widget;
 }
 
 static void
-gb_tab_stack_get_property (GObject    *object,
-                           guint       prop_id,
-                           GValue     *value,
-                           GParamSpec *pspec)
+gb_tab_stack_do_move_left (GbTabStack *stack,
+                           GdkEvent   *event,
+                           GtkButton  *button)
 {
-#if 0
-  GbTabStack *stack = GB_TAB_STACK (object);
-#endif
+  GbTabGrid *grid;
+  GbTab *tab;
 
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  g_return_if_fail (GB_IS_TAB_STACK (stack));
+
+  grid = get_grid (stack);
+  tab = gb_tab_stack_get_active (stack);
+
+  if (grid && tab)
+    gb_tab_grid_move_tab_left (grid, tab);
 }
 
 static void
-gb_tab_stack_set_property (GObject      *object,
-                           guint         prop_id,
-                           const GValue *value,
-                           GParamSpec   *pspec)
+gb_tab_stack_do_move_right (GbTabStack *stack,
+                            GdkEvent   *event,
+                            GtkButton  *button)
 {
-#if 0
-  GbTabStack *stack = GB_TAB_STACK (object);
-#endif
+  GbTabGrid *grid;
+  GbTab *tab;
 
-  switch (prop_id)
-    {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  g_return_if_fail (GB_IS_TAB_STACK (stack));
+
+  grid = get_grid (stack);
+  tab = gb_tab_stack_get_active (stack);
+
+  if (grid && tab)
+    gb_tab_grid_move_tab_right (grid, tab);
 }
 
 static void
 gb_tab_stack_class_init (GbTabStackClass *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_stack_finalize;
-  object_class->get_property = gb_tab_stack_get_property;
-  object_class->set_property = gb_tab_stack_set_property;
-
   container_class->add = gb_tab_stack_add;
 
   widget_class->grab_focus = gb_tab_stack_grab_focus;
 
+  klass->changed = gb_tab_stack_real_changed;
+
   gtk_widget_class_set_template_from_resource (widget_class,
                                                "/org/gnome/builder/ui/gb-tab-stack.ui");
   gtk_widget_class_bind_template_child_internal_private (widget_class, GbTabStack, controls);
   gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, close);
   gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, combo);
+  gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, move_left);
+  gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, move_right);
   gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, stack);
   gtk_widget_class_bind_template_child_private (widget_class, GbTabStack, store);
 
+  gSignals [CHANGED] = g_signal_new ("changed",
+                                     GB_TYPE_TAB_STACK,
+                                     G_SIGNAL_RUN_FIRST,
+                                     G_STRUCT_OFFSET (GbTabStackClass, changed),
+                                     NULL,
+                                     NULL,
+                                     g_cclosure_marshal_generic,
+                                     G_TYPE_NONE,
+                                     0);
+
   g_type_ensure (GB_TYPE_TAB);
 }
 
@@ -528,6 +573,18 @@ gb_tab_stack_init (GbTabStack *stack)
                            stack,
                            G_CONNECT_SWAPPED);
 
+  g_signal_connect_object (stack->priv->move_left,
+                           "clicked",
+                           G_CALLBACK (gb_tab_stack_do_move_left),
+                           stack,
+                           G_CONNECT_SWAPPED);
+
+  g_signal_connect_object (stack->priv->move_right,
+                           "clicked",
+                           G_CALLBACK (gb_tab_stack_do_move_right),
+                           stack,
+                           G_CONNECT_SWAPPED);
+
   layout = GTK_CELL_LAYOUT (stack->priv->combo);
   cell = gtk_cell_renderer_text_new ();
   gtk_cell_layout_pack_start (layout, cell, TRUE);
diff --git a/src/tabs/gb-tab-stack.h b/src/tabs/gb-tab-stack.h
index 1779dbf..6b52034 100644
--- a/src/tabs/gb-tab-stack.h
+++ b/src/tabs/gb-tab-stack.h
@@ -39,7 +39,7 @@ typedef struct _GbTabStackPrivate GbTabStackPrivate;
 
 struct _GbTabStack
 {
-   GtkVBox parent;
+   GtkBox parent;
 
    /*< private >*/
    GbTabStackPrivate *priv;
@@ -47,11 +47,13 @@ struct _GbTabStack
 
 struct _GbTabStackClass
 {
-   GtkVBoxClass parent_class;
+   GtkBoxClass parent_class;
+
+   void (*changed) (GbTabStack *stack);
 };
 
 GType      gb_tab_stack_get_type       (void) G_GNUC_CONST;
-GtkWidget *gb_tab_stack_get_active     (GbTabStack *stack);
+GbTab     *gb_tab_stack_get_active     (GbTabStack *stack);
 gboolean   gb_tab_stack_contains_tab   (GbTabStack *stack,
                                         GbTab      *tab);
 void       gb_tab_stack_remove_tab     (GbTabStack *stack,


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