summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <matthiasc@src.gnome.org>2003-09-15 20:35:28 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2003-09-15 20:35:28 +0000
commitc77b0caab16f094176938c30d7d6a25bbfb69fcc (patch)
treebbf467cc7e2e5841d7f2be8ad835844a5f68355b
parentcaf380c793789e868458e32fbb64a33b5ef1d852 (diff)
downloadgtk+-c77b0caab16f094176938c30d7d6a25bbfb69fcc.tar.gz
New function which implements "smart" separators by iterating once over
* gtk/gtkuimanager.c (update_smart_separators): New function which implements "smart" separators by iterating once over the entries of a menu, hiding and showing separators as necessary. (update_node): Mark separators used as fences of placeholders as hidden. Explicitly added separators are marked as smart. Call update_smart_separators after updating a menu or toolbar node. Connect update_smart_separators to "notify::visible" signal on menu and tool items. * tests/merge-[12].ui: Test smart separators. * gtk/tmpl/gtkuimanager.sgml: Add a paragraph about smart separators.
-rw-r--r--ChangeLog18
-rw-r--r--ChangeLog.pre-2-1018
-rw-r--r--ChangeLog.pre-2-418
-rw-r--r--ChangeLog.pre-2-618
-rw-r--r--ChangeLog.pre-2-818
-rw-r--r--docs/reference/ChangeLog2
-rw-r--r--docs/reference/gtk/tmpl/gtkuimanager.sgml28
-rw-r--r--gtk/gtkuimanager.c183
-rw-r--r--tests/merge-1.ui1
-rw-r--r--tests/merge-2.ui6
10 files changed, 273 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index 95b37d0b83..a4ddcf40ad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
2003-09-15 Matthias Clasen <maclas@gmx.de>
+ Smart separators; see
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00133.html:
+
+ * gtk/gtkuimanager.c (update_smart_separators): New function which
+ implements "smart" separators by iterating once over the entries of a
+ menu, hiding and showing separators as necessary.
+ (update_node): Mark separators used as fences of placeholders as
+ hidden. Explicitly added separators are marked as smart. Call
+ update_smart_separators after updating a menu or toolbar node.
+ Connect update_smart_separators to "notify::visible" signal on menu
+ and tool items.
+
+ * tests/merge-[12].ui: Test smart separators.
+
+ Changes to allow setting action state before connecting signal; see
+ the thread starting at
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00140.html:
+
* gtk/gtkactiongroup.[hc]: (gtk_action_group_add_radio_actions):
(gtk_action_group_add_radio_actions_full): Add value parameter to allow
setting the currently selected group member before connecting signals.
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 95b37d0b83..a4ddcf40ad 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,5 +1,23 @@
2003-09-15 Matthias Clasen <maclas@gmx.de>
+ Smart separators; see
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00133.html:
+
+ * gtk/gtkuimanager.c (update_smart_separators): New function which
+ implements "smart" separators by iterating once over the entries of a
+ menu, hiding and showing separators as necessary.
+ (update_node): Mark separators used as fences of placeholders as
+ hidden. Explicitly added separators are marked as smart. Call
+ update_smart_separators after updating a menu or toolbar node.
+ Connect update_smart_separators to "notify::visible" signal on menu
+ and tool items.
+
+ * tests/merge-[12].ui: Test smart separators.
+
+ Changes to allow setting action state before connecting signal; see
+ the thread starting at
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00140.html:
+
* gtk/gtkactiongroup.[hc]: (gtk_action_group_add_radio_actions):
(gtk_action_group_add_radio_actions_full): Add value parameter to allow
setting the currently selected group member before connecting signals.
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 95b37d0b83..a4ddcf40ad 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,5 +1,23 @@
2003-09-15 Matthias Clasen <maclas@gmx.de>
+ Smart separators; see
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00133.html:
+
+ * gtk/gtkuimanager.c (update_smart_separators): New function which
+ implements "smart" separators by iterating once over the entries of a
+ menu, hiding and showing separators as necessary.
+ (update_node): Mark separators used as fences of placeholders as
+ hidden. Explicitly added separators are marked as smart. Call
+ update_smart_separators after updating a menu or toolbar node.
+ Connect update_smart_separators to "notify::visible" signal on menu
+ and tool items.
+
+ * tests/merge-[12].ui: Test smart separators.
+
+ Changes to allow setting action state before connecting signal; see
+ the thread starting at
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00140.html:
+
* gtk/gtkactiongroup.[hc]: (gtk_action_group_add_radio_actions):
(gtk_action_group_add_radio_actions_full): Add value parameter to allow
setting the currently selected group member before connecting signals.
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 95b37d0b83..a4ddcf40ad 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,5 +1,23 @@
2003-09-15 Matthias Clasen <maclas@gmx.de>
+ Smart separators; see
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00133.html:
+
+ * gtk/gtkuimanager.c (update_smart_separators): New function which
+ implements "smart" separators by iterating once over the entries of a
+ menu, hiding and showing separators as necessary.
+ (update_node): Mark separators used as fences of placeholders as
+ hidden. Explicitly added separators are marked as smart. Call
+ update_smart_separators after updating a menu or toolbar node.
+ Connect update_smart_separators to "notify::visible" signal on menu
+ and tool items.
+
+ * tests/merge-[12].ui: Test smart separators.
+
+ Changes to allow setting action state before connecting signal; see
+ the thread starting at
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00140.html:
+
* gtk/gtkactiongroup.[hc]: (gtk_action_group_add_radio_actions):
(gtk_action_group_add_radio_actions_full): Add value parameter to allow
setting the currently selected group member before connecting signals.
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 95b37d0b83..a4ddcf40ad 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,5 +1,23 @@
2003-09-15 Matthias Clasen <maclas@gmx.de>
+ Smart separators; see
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00133.html:
+
+ * gtk/gtkuimanager.c (update_smart_separators): New function which
+ implements "smart" separators by iterating once over the entries of a
+ menu, hiding and showing separators as necessary.
+ (update_node): Mark separators used as fences of placeholders as
+ hidden. Explicitly added separators are marked as smart. Call
+ update_smart_separators after updating a menu or toolbar node.
+ Connect update_smart_separators to "notify::visible" signal on menu
+ and tool items.
+
+ * tests/merge-[12].ui: Test smart separators.
+
+ Changes to allow setting action state before connecting signal; see
+ the thread starting at
+ http://mail.gnome.org/archives/gtk-devel-list/2003-September/msg00140.html:
+
* gtk/gtkactiongroup.[hc]: (gtk_action_group_add_radio_actions):
(gtk_action_group_add_radio_actions_full): Add value parameter to allow
setting the currently selected group member before connecting signals.
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index bf0bc1a7ed..a810a23007 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,5 +1,7 @@
2003-09-15 Matthias Clasen <maclas@gmx.de>
+ * gtk/tmpl/gtkuimanager.sgml: Add a paragraph about smart separators.
+
* gtk/gtk-sections.txt: Add gtk_action_group_add_toggle_actions[_full].
2003-09-12 Matthias Clasen <maclas@gmx.de>
diff --git a/docs/reference/gtk/tmpl/gtkuimanager.sgml b/docs/reference/gtk/tmpl/gtkuimanager.sgml
index 012166f84f..a34872a37e 100644
--- a/docs/reference/gtk/tmpl/gtkuimanager.sgml
+++ b/docs/reference/gtk/tmpl/gtkuimanager.sgml
@@ -127,6 +127,17 @@ has the path <literal>/ui/menubar/JustifyMenu/Left</literal> and the
toolitem with the same name has path
<literal>/ui/toolbar1/JustifyToolItems/Left</literal>.
</para>
+<refsect2 id="Smart-Separators">
+<title>Smart Separators</title>
+<para>
+The separators created by #GtkUIManager are "smart", i.e. they do not show up in the
+UI unless they end up between two visible menu or tool items. Separators which are located
+at the very beginning or end of the menu or toolbar containing them, or multiple separators
+next to each other, are hidden. This is a useful feature, since the merging of UI elements
+from multiple sources can make it hard or impossible to determine in advance whether a
+separator will end up in such an unfortunate position.
+</para>
+</refsect2>
</refsect2>
<!-- ##### SECTION See_Also ##### -->
@@ -256,6 +267,21 @@ members and should not be accessed directly.
@Returns:
+<!-- ##### ENUM GtkUIManagerItemType ##### -->
+<para>
+
+</para>
+
+@GTK_UI_MANAGER_AUTO:
+@GTK_UI_MANAGER_MENUBAR:
+@GTK_UI_MANAGER_MENU:
+@GTK_UI_MANAGER_TOOLBAR:
+@GTK_UI_MANAGER_PLACEHOLDER:
+@GTK_UI_MANAGER_POPUP:
+@GTK_UI_MANAGER_MENUITEM:
+@GTK_UI_MANAGER_TOOLITEM:
+@GTK_UI_MANAGER_SEPARATOR:
+
<!-- ##### FUNCTION gtk_ui_manager_add_ui ##### -->
<para>
@@ -266,6 +292,8 @@ members and should not be accessed directly.
@path:
@name:
@action:
+@type:
+@top:
<!-- ##### FUNCTION gtk_ui_manager_remove_ui ##### -->
diff --git a/gtk/gtkuimanager.c b/gtk/gtkuimanager.c
index 03a978dbd9..5a0538e918 100644
--- a/gtk/gtkuimanager.c
+++ b/gtk/gtkuimanager.c
@@ -102,37 +102,37 @@ struct _NodeUIReference
GQuark action_quark;
};
-static void gtk_ui_manager_class_init (GtkUIManagerClass *class);
-static void gtk_ui_manager_init (GtkUIManager *self);
-static void gtk_ui_manager_finalize (GObject *object);
-static void gtk_ui_manager_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_ui_manager_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void queue_update (GtkUIManager *self);
-static void dirty_all_nodes (GtkUIManager *self);
-static GNode *get_child_node (GtkUIManager *self,
- GNode *parent,
- const gchar *childname,
- gint childname_length,
- NodeType node_type,
- gboolean create,
- gboolean top);
-static GNode *get_node (GtkUIManager *self,
- const gchar *path,
- NodeType node_type,
- gboolean create);
-static gboolean free_node (GNode *node);
-
-static void node_prepend_ui_reference (Node *node,
- guint merge_id,
- GQuark action_quark);
-static void node_remove_ui_reference (Node *node,
- guint merge_id);
+static void gtk_ui_manager_class_init (GtkUIManagerClass *class);
+static void gtk_ui_manager_init (GtkUIManager *self);
+static void gtk_ui_manager_finalize (GObject *object);
+static void gtk_ui_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_ui_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void queue_update (GtkUIManager *self);
+static void dirty_all_nodes (GtkUIManager *self);
+static GNode * get_child_node (GtkUIManager *self,
+ GNode *parent,
+ const gchar *childname,
+ gint childname_length,
+ NodeType node_type,
+ gboolean create,
+ gboolean top);
+static GNode * get_node (GtkUIManager *self,
+ const gchar *path,
+ NodeType node_type,
+ gboolean create);
+static gboolean free_node (GNode *node);
+static void node_prepend_ui_reference (Node *node,
+ guint merge_id,
+ GQuark action_quark);
+static void node_remove_ui_reference (Node *node,
+ guint merge_id);
+
enum
@@ -1569,6 +1569,79 @@ find_toolbar_position (GNode *node,
return TRUE;
}
+enum {
+ SEPARATOR_MODE_SMART,
+ SEPARATOR_MODE_VISIBLE,
+ SEPARATOR_MODE_HIDDEN
+};
+
+static void
+update_smart_separators (GtkWidget *proxy)
+{
+ GtkWidget *parent = NULL;
+
+ if (GTK_IS_MENU (proxy) || GTK_IS_TOOLBAR (proxy))
+ parent = proxy;
+ else if (GTK_IS_MENU_ITEM (proxy) || GTK_IS_TOOL_ITEM (proxy))
+ parent = gtk_widget_get_parent (proxy);
+
+ if (parent)
+ {
+ gboolean visible;
+ GList *children, *cur, *last;
+
+ children = gtk_container_get_children (GTK_CONTAINER (parent));
+
+ visible = FALSE;
+ last = NULL;
+ cur = children;
+ while (cur)
+ {
+ if (GTK_IS_SEPARATOR_MENU_ITEM (cur->data) ||
+ GTK_IS_SEPARATOR_TOOL_ITEM (cur->data))
+ {
+ gint mode =
+ GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cur->data),
+ "gtk-separator-mode"));
+ switch (mode)
+ {
+ case SEPARATOR_MODE_VISIBLE:
+ gtk_widget_show (GTK_WIDGET (cur->data));
+ last = NULL;
+ visible = FALSE;
+ break;
+ case SEPARATOR_MODE_HIDDEN:
+ gtk_widget_hide (GTK_WIDGET (cur->data));
+ break;
+ case SEPARATOR_MODE_SMART:
+ if (visible)
+ {
+ gtk_widget_show (GTK_WIDGET (cur->data));
+ last = cur;
+ visible = FALSE;
+ }
+ else
+ gtk_widget_hide (GTK_WIDGET (cur->data));
+ break;
+ }
+ }
+ else if (GTK_WIDGET_VISIBLE (cur->data))
+ {
+ last = NULL;
+ if (GTK_IS_TEAROFF_MENU_ITEM (cur->data))
+ visible = FALSE;
+ else
+ visible = TRUE;
+ }
+
+ cur = cur->next;
+ }
+
+ if (last)
+ gtk_widget_hide (GTK_WIDGET (last->data));
+ }
+}
+
static void
update_node (GtkUIManager *self,
GNode *node,
@@ -1756,11 +1829,17 @@ update_node (GtkUIManager *self,
if (find_menu_position (node, &menushell, &pos))
{
- NODE_INFO (node)->proxy = gtk_separator_menu_item_new ();
+ info->proxy = gtk_separator_menu_item_new ();
+ g_object_set_data (G_OBJECT (info->proxy),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
NODE_INFO (node)->proxy, pos);
- NODE_INFO (node)->extra = gtk_separator_menu_item_new ();
+ info->extra = gtk_separator_menu_item_new ();
+ g_object_set_data (G_OBJECT (info->extra),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
NODE_INFO (node)->extra, pos+1);
}
@@ -1795,11 +1874,17 @@ update_node (GtkUIManager *self,
item = gtk_separator_tool_item_new ();
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos);
- NODE_INFO(node)->proxy = GTK_WIDGET (item);
+ info->proxy = GTK_WIDGET (item);
+ g_object_set_data (G_OBJECT (info->proxy),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
item = gtk_separator_tool_item_new ();
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos+1);
- NODE_INFO (node)->extra = GTK_WIDGET (item);
+ info->extra = GTK_WIDGET (item);
+ g_object_set_data (G_OBJECT (info->extra),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
}
}
break;
@@ -1808,6 +1893,9 @@ update_node (GtkUIManager *self,
if (info->proxy && G_OBJECT_TYPE (info->proxy) !=
GTK_ACTION_GET_CLASS (action)->menu_item_type)
{
+ g_signal_handlers_disconnect_by_func (info->proxy,
+ G_CALLBACK (update_smart_separators),
+ 0);
gtk_action_disconnect_proxy (info->action, info->proxy);
gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
info->proxy);
@@ -1829,15 +1917,23 @@ update_node (GtkUIManager *self,
}
else
{
+ g_signal_handlers_disconnect_by_func (info->proxy,
+ G_CALLBACK (update_smart_separators),
+ 0);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), NULL);
gtk_action_connect_proxy (action, info->proxy);
}
+ g_signal_connect (info->proxy, "notify::visible",
+ G_CALLBACK (update_smart_separators), 0);
break;
case NODE_TYPE_TOOLITEM:
/* remove the proxy if it is of the wrong type ... */
if (info->proxy && G_OBJECT_TYPE (info->proxy) !=
GTK_ACTION_GET_CLASS (action)->toolbar_item_type)
{
+ g_signal_handlers_disconnect_by_func (info->proxy,
+ G_CALLBACK (update_smart_separators),
+ 0);
gtk_action_disconnect_proxy (info->action, info->proxy);
gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
info->proxy);
@@ -1859,8 +1955,13 @@ update_node (GtkUIManager *self,
}
else
{
+ g_signal_handlers_disconnect_by_func (info->proxy,
+ G_CALLBACK (update_smart_separators),
+ 0);
gtk_action_connect_proxy (action, info->proxy);
}
+ g_signal_connect (info->proxy, "notify::visible",
+ G_CALLBACK (update_smart_separators), 0);
break;
case NODE_TYPE_SEPARATOR:
if (NODE_INFO (node->parent)->type == NODE_TYPE_TOOLBAR ||
@@ -1881,6 +1982,9 @@ update_node (GtkUIManager *self,
GtkToolItem *item = gtk_separator_tool_item_new ();
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos);
info->proxy = GTK_WIDGET (item);
+ g_object_set_data (G_OBJECT (info->proxy),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_SMART));
gtk_widget_show (info->proxy);
}
}
@@ -1899,6 +2003,9 @@ update_node (GtkUIManager *self,
if (find_menu_position (node, &menushell, &pos))
{
info->proxy = gtk_separator_menu_item_new ();
+ g_object_set_data (G_OBJECT (info->proxy),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_SMART));
gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
info->proxy, pos);
gtk_widget_show (info->proxy);
@@ -1926,6 +2033,12 @@ update_node (GtkUIManager *self,
update_node (self, current, add_tearoffs && (info->type != NODE_TYPE_POPUP));
}
+ if (info->type == NODE_TYPE_MENU)
+ update_smart_separators (gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy)));
+ else if (info->type == NODE_TYPE_TOOLBAR)
+ update_smart_separators (info->proxy);
+
+
/* handle cleanup of dead nodes */
if (node->children == NULL && info->uifiles == NULL)
{
diff --git a/tests/merge-1.ui b/tests/merge-1.ui
index 55b3455592..a7fb9779d4 100644
--- a/tests/merge-1.ui
+++ b/tests/merge-1.ui
@@ -12,6 +12,7 @@
<toolbar name="toolbar1">
<placeholder name="ToolbarPlaceholder">
<toolitem name="nb2" action="NewAction" />
+ <separator name="Sep1" />
</placeholder>
<toolitem name="NewButton" action="NewAction" />
<toolitem name="CutButton" action="CutAction" />
diff --git a/tests/merge-2.ui b/tests/merge-2.ui
index 18fbc607f6..a073f917dc 100644
--- a/tests/merge-2.ui
+++ b/tests/merge-2.ui
@@ -3,8 +3,10 @@
<menubar>
<menu name="FileMenu" action="FileMenuAction">
<menuitem name="New" action="NewAction" position="top" />
- <separator />
+ <separator name="Sep1" />
+ <separator name="Sep2" />
<menuitem name="Quit" action="QuitAction" />
+ <separator name="Sep3" />
</menu>
<menu name="HelpMenu" action="HelpMenuAction">
<menuitem name="About" action="AboutAction" />
@@ -13,7 +15,7 @@
<toolbar name="toolbar1">
<placeholder name="ToolbarPlaceholder">
<toolitem name="Quit" action="QuitAction" />
- <separator />
+ <separator name="Sep2"/>
</placeholder>
</toolbar>
<popup name="FileMenu" action="FileMenuAction">