[gdl] New property tab-reorderable for GdlSwitcher.



commit 18576eca461011ecfd6c5cb0c875346159da9808
Author: Dominique Lasserre <lasserre d gmail com>
Date:   Wed Apr 10 15:24:23 2013 +0200

    New property tab-reorderable for GdlSwitcher.
    
     * tab-reorderable has only an effect with GDL_SWITCHER_STYLE_TABS style.
     * Also update example.

 gdl/gdl-dock-master.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++--
 gdl/gdl-switcher.c    | 43 ++++++++++++++++++++++++++++--
 gdl/gdl-switcher.h    |  1 +
 gdl/test-dock.c       |  1 +
 4 files changed, 113 insertions(+), 4 deletions(-)
---
diff --git a/gdl/gdl-dock-master.c b/gdl/gdl-dock-master.c
index 055d1c8..e7729bf 100644
--- a/gdl/gdl-dock-master.c
+++ b/gdl/gdl-dock-master.c
@@ -113,6 +113,8 @@ static void gdl_dock_master_set_switcher_style (GdlDockMaster *master,
                                                 GdlSwitcherStyle switcher_style);
 static void gdl_dock_master_set_tab_pos        (GdlDockMaster     *master,
                                                 GtkPositionType    pos);
+static void gdl_dock_master_set_tab_reorderable (GdlDockMaster    *master,
+                                                gboolean           reorderable);
 
 /* ----- Private data types and variables ----- */
 
@@ -121,7 +123,8 @@ enum {
     PROP_DEFAULT_TITLE,
     PROP_LOCKED,
     PROP_SWITCHER_STYLE,
-    PROP_TAB_POS
+    PROP_TAB_POS,
+    PROP_TAB_REORDERABLE
 };
 
 enum {
@@ -156,6 +159,7 @@ struct _GdlDockMasterPrivate {
 
     GdlSwitcherStyle switcher_style;
     GtkPositionType tab_pos;
+    gboolean        tab_reorderable;
 
     /* Window for preview rect */
     GtkWidget* area_window;
@@ -165,6 +169,9 @@ struct _GdlDockMasterPrivate {
     (g_hash_table_size ((master)->priv->unlocked_items) == 0 ? 1 :     \
      (g_hash_table_size ((master)->priv->locked_items) == 0 ? 0 : -1))
 
+#define GBOOLEAN_TO_POINTER(i) (GINT_TO_POINTER ((i) ? 2 : 1))
+#define GPOINTER_TO_BOOLEAN(i) ((gboolean) ((GPOINTER_TO_INT(i) == 2) ? TRUE : FALSE))
+
 static guint master_signals [LAST_SIGNAL] = { 0 };
 
 
@@ -218,6 +225,13 @@ gdl_dock_master_class_init (GdlDockMasterClass *klass)
                            GTK_POS_BOTTOM,
                            G_PARAM_READWRITE));
 
+    g_object_class_install_property (
+        object_class, PROP_TAB_REORDERABLE,
+        g_param_spec_boolean ("tab-reorderable", _("Tab reorderable"),
+                              _("Whether the tab is reorderable by user action"),
+                              FALSE,
+                              G_PARAM_READWRITE));
+
     /**
      * GdlDockMaster::layout-changed:
      *
@@ -254,6 +268,7 @@ gdl_dock_master_init (GdlDockMaster *master)
     master->priv->number = 1;
     master->priv->switcher_style = GDL_SWITCHER_STYLE_BOTH;
     master->priv->tab_pos = GTK_POS_BOTTOM;
+    master->priv->tab_reorderable = FALSE;
     master->priv->locked_items = g_hash_table_new (g_direct_hash, g_direct_equal);
     master->priv->unlocked_items = g_hash_table_new (g_direct_hash, g_direct_equal);
 }
@@ -442,6 +457,9 @@ gdl_dock_master_set_property  (GObject      *object,
         case PROP_TAB_POS:
             gdl_dock_master_set_tab_pos (master, g_value_get_enum (value));
             break;
+        case PROP_TAB_REORDERABLE:
+            gdl_dock_master_set_tab_reorderable (master, g_value_get_boolean (value));
+            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
             break;
@@ -469,6 +487,9 @@ gdl_dock_master_get_property  (GObject      *object,
         case PROP_TAB_POS:
             g_value_set_enum (value, master->priv->tab_pos);
             break;
+        case PROP_TAB_REORDERABLE:
+            g_value_set_enum (value, master->priv->tab_reorderable);
+            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
             break;
@@ -902,7 +923,8 @@ gdl_dock_master_add (GdlDockMaster *master,
             item_notify_cb (object, NULL, master);
         }
 
-        /* If the item is notebook, set the switcher style and tab position */
+        /* If the item is notebook, set the switcher style and notebook
+         * settings. */
         if (GDL_IS_DOCK_NOTEBOOK (object) &&
             GDL_IS_SWITCHER (gdl_dock_item_get_child (GDL_DOCK_ITEM (object))))
         {
@@ -911,6 +933,8 @@ gdl_dock_master_add (GdlDockMaster *master,
                           master->priv->switcher_style, NULL);
             g_object_set (child, "tab-pos",
                           master->priv->tab_pos, NULL);
+            g_object_set (child, "tab-reorderable",
+                          master->priv->tab_reorderable, NULL);
         }
 
         /* post a layout_changed emission if the item is not automatic
@@ -1196,3 +1220,47 @@ gdl_dock_master_set_tab_pos (GdlDockMaster *master,
     gdl_dock_master_foreach (master, (GFunc) set_tab_pos_foreach,
                              GINT_TO_POINTER (tab_pos));
 }
+
+static void
+set_tab_reorderable_foreach (GtkWidget *obj, gpointer user_data)
+{
+    gboolean tab_reorderable = GPOINTER_TO_BOOLEAN (user_data);
+
+    if (!GDL_IS_DOCK_ITEM (obj))
+        return;
+
+    if (GDL_IS_DOCK_NOTEBOOK (obj)) {
+
+        GtkWidget *child = gdl_dock_item_get_child (GDL_DOCK_ITEM (obj));
+        if (GDL_IS_SWITCHER (child)) {
+
+            g_object_set (child, "tab-reorderable", tab_reorderable, NULL);
+        }
+    } else if (gdl_dock_object_is_compound (GDL_DOCK_OBJECT (obj))) {
+
+        gtk_container_foreach (GTK_CONTAINER (obj),
+                               set_tab_reorderable_foreach,
+                               user_data);
+    }
+}
+
+static void
+gdl_dock_master_set_tab_reorderable (GdlDockMaster *master,
+                                     gboolean tab_reorderable)
+{
+    GList *l;
+    g_return_if_fail (GDL_IS_DOCK_MASTER (master));
+
+    master->priv->tab_reorderable = tab_reorderable;
+    for (l = master->priv->toplevel_docks; l; l = l->next) {
+        GdlDock *dock = GDL_DOCK (l->data);
+        GtkWidget *root = GTK_WIDGET (gdl_dock_get_root (dock));
+        if (root != NULL)
+            set_tab_reorderable_foreach (root,
+                                         GBOOLEAN_TO_POINTER (tab_reorderable));
+    }
+
+    /* just to be sure hidden items are set too */
+    gdl_dock_master_foreach (master, (GFunc) set_tab_reorderable_foreach,
+                             GBOOLEAN_TO_POINTER (tab_reorderable));
+}
diff --git a/gdl/gdl-switcher.c b/gdl/gdl-switcher.c
index f8ce3af..47fa837 100644
--- a/gdl/gdl-switcher.c
+++ b/gdl/gdl-switcher.c
@@ -75,12 +75,14 @@ static void gdl_switcher_set_style (GdlSwitcher *switcher,
                                     GdlSwitcherStyle switcher_style);
 static GdlSwitcherStyle gdl_switcher_get_style (GdlSwitcher *switcher);
 static void gdl_switcher_set_tab_pos (GdlSwitcher *switcher, GtkPositionType pos);
+static void gdl_switcher_set_tab_reorderable (GdlSwitcher *switcher, gboolean reorderable);
 static void gdl_switcher_update_lone_button_visibility (GdlSwitcher *switcher);
 
 enum {
     PROP_0,
     PROP_SWITCHER_STYLE,
-    PROP_TAB_POS
+    PROP_TAB_POS,
+    PROP_TAB_REORDERABLE
 };
 
 typedef struct {
@@ -97,6 +99,7 @@ struct _GdlSwitcherPrivate {
     GdlSwitcherStyle switcher_style;
     GdlSwitcherStyle toolbar_style;
     GtkPositionType tab_pos;
+    gboolean tab_reorderable;
 
     gboolean show;
     GSList *buttons;
@@ -735,6 +738,9 @@ gdl_switcher_set_property  (GObject      *object,
         case PROP_TAB_POS:
             gdl_switcher_set_tab_pos (switcher, g_value_get_enum (value));
             break;
+        case PROP_TAB_REORDERABLE:
+            gdl_switcher_set_tab_reorderable (switcher, g_value_get_boolean (value));
+            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
             break;
@@ -756,6 +762,9 @@ gdl_switcher_get_property  (GObject      *object,
         case PROP_TAB_POS:
             g_value_set_enum (value, switcher->priv->tab_pos);
             break;
+        case PROP_TAB_REORDERABLE:
+            g_value_set_enum (value, switcher->priv->tab_reorderable);
+            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
             break;
@@ -897,6 +906,13 @@ gdl_switcher_class_init (GdlSwitcherClass *klass)
                            GTK_POS_BOTTOM,
                            G_PARAM_READWRITE));
 
+    g_object_class_install_property (
+        object_class, PROP_TAB_REORDERABLE,
+        g_param_spec_boolean ("tab-reorderable", _("Tab reorderable"),
+                              _("Whether the tab is reorderable by user action"),
+                              FALSE,
+                              G_PARAM_READWRITE));
+
     g_type_class_add_private (object_class, sizeof (GdlSwitcherPrivate));
 
     /* set the style */
@@ -921,6 +937,7 @@ gdl_switcher_init (GdlSwitcher *switcher)
     priv->show = TRUE;
     priv->buttons_height_request = -1;
     priv->tab_pos = GTK_POS_BOTTOM;
+    priv->tab_reorderable = FALSE;
 
     gtk_notebook_set_tab_pos (GTK_NOTEBOOK (switcher), GTK_POS_BOTTOM);
     gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), FALSE);
@@ -1098,6 +1115,7 @@ gdl_switcher_insert_page (GdlSwitcher *switcher, GtkWidget *page,
                           const gchar *tooltips, const gchar *stock_id,
                           GdkPixbuf *pixbuf_icon, gint position)
 {
+    GtkNotebook *notebook = GTK_NOTEBOOK (switcher);
     gint ret_position;
     gint switcher_id;
     g_signal_handlers_block_by_func (switcher,
@@ -1111,8 +1129,10 @@ gdl_switcher_insert_page (GdlSwitcher *switcher, GtkWidget *page,
     switcher_id = gdl_switcher_get_page_id (page);
     gdl_switcher_add_button (switcher, label, tooltips, stock_id, pixbuf_icon, switcher_id, page);
 
-    ret_position = gtk_notebook_insert_page (GTK_NOTEBOOK (switcher), page,
+    ret_position = gtk_notebook_insert_page (notebook, page,
                                              tab_widget, position);
+    gtk_notebook_set_tab_reorderable (notebook, page,
+                                      switcher->priv->tab_reorderable);
     g_signal_handlers_unblock_by_func (switcher,
                                        gdl_switcher_page_added_cb,
                                        switcher);
@@ -1242,3 +1262,22 @@ gdl_switcher_set_tab_pos (GdlSwitcher *switcher, GtkPositionType pos)
 
     switcher->priv->tab_pos = pos;
 }
+
+static void
+gdl_switcher_set_tab_reorderable (GdlSwitcher *switcher, gboolean reorderable)
+{
+    GList *children, *l;
+
+    if (switcher->priv->tab_reorderable == reorderable)
+        return;
+
+    children = gtk_container_get_children (GTK_CONTAINER (switcher));
+    for (l = children; l != NULL; l->next) {
+        gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (switcher),
+                                          GTK_WIDGET (l->data),
+                                          reorderable);
+    }
+    g_list_free (children);
+
+    switcher->priv->tab_reorderable = reorderable;
+}
diff --git a/gdl/gdl-switcher.h b/gdl/gdl-switcher.h
index 07447ae..7cbf5b0 100644
--- a/gdl/gdl-switcher.h
+++ b/gdl/gdl-switcher.h
@@ -28,6 +28,7 @@
 #define _GDL_SWITCHER_H_
 
 #include <gtk/gtk.h>
+#include <gtk/gtkcontainer.h>
 
 G_BEGIN_DECLS
 
diff --git a/gdl/test-dock.c b/gdl/test-dock.c
index 7fd834c..1738ae6 100644
--- a/gdl/test-dock.c
+++ b/gdl/test-dock.c
@@ -211,6 +211,7 @@ main (int argc, char **argv)
        dock = gdl_dock_new ();
        GdlDockMaster *master = GDL_DOCK_MASTER (gdl_dock_object_get_master (GDL_DOCK_OBJECT (dock)));
        g_object_set (master, "tab-pos", GTK_POS_TOP, NULL);
+       g_object_set (master, "tab-reorderable", TRUE, NULL);
 
        /* ... and the layout manager */
        layout = gdl_dock_layout_new (G_OBJECT (dock));


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