forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
caf380c793
commit
c77b0caab1
18
ChangeLog
18
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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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 ##### -->
|
||||
|
@ -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 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 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)
|
||||
{
|
||||
|
@ -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" />
|
||||
|
@ -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">
|
||||
|
Loading…
Reference in New Issue
Block a user