Demonstrate the use of the connect-proxy signal.

2003-09-27  Matthias Clasen  <maclas@gmx.de>

	* tests/testmerge.c: Demonstrate the use of the
	connect-proxy signal.

	* gtk/gtkaction.c (connect_proxy): Add connect-proxy and
	disconnect-proxy signals to do small customizations
	like displaying tooltips in the statusbar without
	custom actions.  (#122894, Philip Langdale)

	* gtk/gtkuimanager.c (update_node): Don't leak tooltip.
This commit is contained in:
Matthias Clasen 2003-09-26 23:01:32 +00:00 committed by Matthias Clasen
parent c920afd9c5
commit eeed9d1890
8 changed files with 223 additions and 21 deletions

View File

@ -1,3 +1,15 @@
2003-09-27 Matthias Clasen <maclas@gmx.de>
* tests/testmerge.c: Demonstrate the use of the
connect-proxy signal.
* gtk/gtkaction.c (connect_proxy): Add connect-proxy and
disconnect-proxy signals to do small customizations
like displaying tooltips in the statusbar without
custom actions. (#122894, Philip Langdale)
* gtk/gtkuimanager.c (update_node): Don't leak tooltip.
Fri Sep 26 23:49:44 2003 Kristian Rietveld <kris@gtk.org>
Landing the new ComboBox. Note that only gtkcombobox.h and

View File

@ -1,3 +1,15 @@
2003-09-27 Matthias Clasen <maclas@gmx.de>
* tests/testmerge.c: Demonstrate the use of the
connect-proxy signal.
* gtk/gtkaction.c (connect_proxy): Add connect-proxy and
disconnect-proxy signals to do small customizations
like displaying tooltips in the statusbar without
custom actions. (#122894, Philip Langdale)
* gtk/gtkuimanager.c (update_node): Don't leak tooltip.
Fri Sep 26 23:49:44 2003 Kristian Rietveld <kris@gtk.org>
Landing the new ComboBox. Note that only gtkcombobox.h and

View File

@ -1,3 +1,15 @@
2003-09-27 Matthias Clasen <maclas@gmx.de>
* tests/testmerge.c: Demonstrate the use of the
connect-proxy signal.
* gtk/gtkaction.c (connect_proxy): Add connect-proxy and
disconnect-proxy signals to do small customizations
like displaying tooltips in the statusbar without
custom actions. (#122894, Philip Langdale)
* gtk/gtkuimanager.c (update_node): Don't leak tooltip.
Fri Sep 26 23:49:44 2003 Kristian Rietveld <kris@gtk.org>
Landing the new ComboBox. Note that only gtkcombobox.h and

View File

@ -1,3 +1,15 @@
2003-09-27 Matthias Clasen <maclas@gmx.de>
* tests/testmerge.c: Demonstrate the use of the
connect-proxy signal.
* gtk/gtkaction.c (connect_proxy): Add connect-proxy and
disconnect-proxy signals to do small customizations
like displaying tooltips in the statusbar without
custom actions. (#122894, Philip Langdale)
* gtk/gtkuimanager.c (update_node): Don't leak tooltip.
Fri Sep 26 23:49:44 2003 Kristian Rietveld <kris@gtk.org>
Landing the new ComboBox. Note that only gtkcombobox.h and

View File

@ -1,3 +1,15 @@
2003-09-27 Matthias Clasen <maclas@gmx.de>
* tests/testmerge.c: Demonstrate the use of the
connect-proxy signal.
* gtk/gtkaction.c (connect_proxy): Add connect-proxy and
disconnect-proxy signals to do small customizations
like displaying tooltips in the statusbar without
custom actions. (#122894, Philip Langdale)
* gtk/gtkuimanager.c (update_node): Don't leak tooltip.
Fri Sep 26 23:49:44 2003 Kristian Rietveld <kris@gtk.org>
Landing the new ComboBox. Note that only gtkcombobox.h and

View File

@ -37,6 +37,7 @@
#include "gtkimagemenuitem.h"
#include "gtkintl.h"
#include "gtklabel.h"
#include "gtkmarshalers.h"
#include "gtkmenuitem.h"
#include "gtkstock.h"
#include "gtktoolbutton.h"
@ -71,6 +72,8 @@ struct _GtkActionPrivate
enum
{
CONNECT_PROXY,
DISCONNECT_PROXY,
ACTIVATE,
LAST_SIGNAL
};
@ -248,6 +251,47 @@ gtk_action_class_init (GtkActionClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkAction::connect-proxy:
* @action: the action
* @proxy: the proxy
*
* The connect_proxy signal is emitted after connecting a proxy to
* an action. Note that the proxy may have been connected to a different
* action before.
*
* This is intended for simple customizations for which a custom action
* class would be too clumsy, e.g. showing tooltips for menuitems in the
* statusbar.
*
* Since: 2.4
*/
action_signals[CONNECT_PROXY] =
g_signal_new ("connect_proxy",
G_OBJECT_CLASS_TYPE (klass),
0, 0, NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_WIDGET);
/**
* GtkAction::disconnect-proxy:
* @action: the action
* @proxy: the proxy
*
* The disconnect_proxy signal is emitted after disconnecting a proxy
* from an action.
*
* Since: 2.4
*/
action_signals[DISCONNECT_PROXY] =
g_signal_new ("disconnect_proxy",
G_OBJECT_CLASS_TYPE (klass),
0, 0, NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_WIDGET);
g_type_class_add_private (gobject_class, sizeof (GtkActionPrivate));
}
@ -709,6 +753,8 @@ connect_proxy (GtkAction *action,
G_CALLBACK (gtk_action_activate), action,
G_CONNECT_SWAPPED);
}
g_signal_emit (action, action_signals[CONNECT_PROXY], 0, proxy);
}
static void
@ -749,6 +795,8 @@ disconnect_proxy (GtkAction *action,
g_signal_handlers_disconnect_by_func (proxy,
G_CALLBACK (gtk_action_create_menu_proxy),
action);
g_signal_emit (action, action_signals[DISCONNECT_PROXY], 0, proxy);
}
/**

View File

@ -136,7 +136,6 @@ static void node_remove_ui_reference (Node *node,
guint merge_id);
enum
{
ADD_WIDGET,
@ -197,7 +196,7 @@ gtk_ui_manager_class_init (GtkUIManagerClass *klass)
gobject_class->finalize = gtk_ui_manager_finalize;
gobject_class->set_property = gtk_ui_manager_set_property;
gobject_class->get_property = gtk_ui_manager_get_property;
/**
* GtkUIManager:add-tearoffs:
*
@ -1856,6 +1855,7 @@ update_node (GtkUIManager *self,
}
else
gtk_action_connect_proxy (action, info->proxy);
if (prev_submenu)
{
gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy),
@ -2029,11 +2029,13 @@ update_node (GtkUIManager *self,
gtk_toolbar_insert (GTK_TOOLBAR (toolbar),
GTK_TOOL_ITEM (info->proxy), pos);
/* FIXME: this is necessary, since tooltips on toolitems
* can't be set before the toolitem is added to the toolbar.
*/
/* FIXME: we must trigger the notify::tooltip handler, since
* tooltips on toolitems can't be set before the toolitem
* is added to the toolbar.
*/
g_object_get (G_OBJECT (action), "tooltip", &tooltip, NULL);
g_object_set (G_OBJECT (action), "tooltip", tooltip, NULL);
g_free (tooltip);
}
}
else
@ -2042,7 +2044,6 @@ update_node (GtkUIManager *self,
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);

View File

@ -125,19 +125,19 @@ static GtkActionEntry entries[] = {
{ "JustifyMenuAction", NULL, "_Justify" },
{ "Test", NULL, "Test" },
{ "QuitAction", GTK_STOCK_QUIT, NULL, "<control>q", NULL, G_CALLBACK (gtk_main_quit) },
{ "NewAction", GTK_STOCK_NEW, NULL, "<control>n", NULL, G_CALLBACK (activate_action) },
{ "New2Action", GTK_STOCK_NEW, NULL, "<control>m", NULL, G_CALLBACK (activate_action) },
{ "OpenAction", GTK_STOCK_OPEN, NULL, "<control>o", NULL, G_CALLBACK (activate_action) },
{ "CutAction", GTK_STOCK_CUT, NULL, "<control>x", NULL, G_CALLBACK (activate_action) },
{ "CopyAction", GTK_STOCK_COPY, NULL, "<control>c", NULL, G_CALLBACK (activate_action) },
{ "PasteAction", GTK_STOCK_PASTE, NULL, "<control>v", NULL, G_CALLBACK (activate_action) },
{ "AboutAction", NULL, "_About", NULL, NULL, G_CALLBACK (activate_action) },
{ "QuitAction", GTK_STOCK_QUIT, NULL, "<control>q", "Quit", G_CALLBACK (gtk_main_quit) },
{ "NewAction", GTK_STOCK_NEW, NULL, "<control>n", "Create something", G_CALLBACK (activate_action) },
{ "New2Action", GTK_STOCK_NEW, NULL, "<control>m", "Create something else", G_CALLBACK (activate_action) },
{ "OpenAction", GTK_STOCK_OPEN, NULL, "<control>o", "Open it", G_CALLBACK (activate_action) },
{ "CutAction", GTK_STOCK_CUT, NULL, "<control>x", "Knive", G_CALLBACK (activate_action) },
{ "CopyAction", GTK_STOCK_COPY, NULL, "<control>c", "Copy", G_CALLBACK (activate_action) },
{ "PasteAction", GTK_STOCK_PASTE, NULL, "<control>v", "Paste", G_CALLBACK (activate_action) },
{ "AboutAction", NULL, "_About", NULL, "About", G_CALLBACK (activate_action) },
};
static guint n_entries = G_N_ELEMENTS (entries);
static GtkToggleActionEntry toggle_entries[] = {
{ "BoldAction", GTK_STOCK_BOLD, "_Bold", "<control>b", NULL, G_CALLBACK (toggle_action),
{ "BoldAction", GTK_STOCK_BOLD, "_Bold", "<control>b", "Make it bold", G_CALLBACK (toggle_action),
TRUE },
};
static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
@ -442,13 +442,97 @@ activate_path (GtkWidget *button,
g_message ("no action found");
}
typedef struct _ActionStatus ActionStatus;
struct _ActionStatus {
GtkAction *action;
GtkWidget *statusbar;
};
static void
action_status_destroy (gpointer data)
{
ActionStatus *action_status = data;
g_object_unref (action_status->action);
g_object_unref (action_status->statusbar);
g_free (action_status);
}
static void
set_tip (GtkWidget *widget)
{
ActionStatus *data;
gchar *tooltip;
data = g_object_get_data (G_OBJECT (widget), "action-status");
if (data)
{
g_object_get (G_OBJECT (data->action), "tooltip", &tooltip, NULL);
gtk_statusbar_push (GTK_STATUSBAR (data->statusbar), 0,
tooltip ? tooltip : "");
g_free (tooltip);
}
}
static void
unset_tip (GtkWidget *widget)
{
ActionStatus *data;
data = g_object_get_data (G_OBJECT (widget), "action-status");
if (data)
gtk_statusbar_pop (GTK_STATUSBAR (data->statusbar), 0);
}
static void
connect_proxy (GtkAction *action,
GtkWidget *proxy,
GtkWidget *statusbar)
{
if (GTK_IS_MENU_ITEM (proxy))
{
ActionStatus *data;
data = g_object_get_data (G_OBJECT (proxy), "action-status");
if (data)
{
g_object_unref (data->action);
g_object_unref (data->statusbar);
data->action = g_object_ref (action);
data->statusbar = g_object_ref (statusbar);
}
else
{
data = g_new0 (ActionStatus, 1);
data->action = g_object_ref (action);
data->statusbar = g_object_ref (statusbar);
g_object_set_data_full (G_OBJECT (proxy), "action-status",
data, action_status_destroy);
g_signal_connect (proxy, "select", G_CALLBACK (set_tip), 0);
g_signal_connect (proxy, "deselect", G_CALLBACK (unset_tip), 0);
}
}
}
int
main (int argc, char **argv)
{
GtkActionGroup *action_group;
GtkAction *action;
GList *tmp;
GtkUIManager *merge;
GtkWidget *window, *table, *frame, *menu_box, *vbox, *view;
GtkWidget *button, *area;
GtkWidget *button, *area, *statusbar;
gint i;
gtk_init (&argc, &argv);
@ -482,7 +566,10 @@ main (int argc, char **argv)
menu_box = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (menu_box), 2);
gtk_container_add (GTK_CONTAINER (frame), menu_box);
statusbar = gtk_statusbar_new ();
gtk_box_pack_end (GTK_BOX (menu_box), statusbar, FALSE, FALSE, 0);
area = gtk_drawing_area_new ();
gtk_widget_set_events (area, GDK_BUTTON_PRESS_MASK);
gtk_widget_set_size_request (area, -1, 40);
@ -494,17 +581,23 @@ main (int argc, char **argv)
gtk_action_connect_proxy (gtk_action_group_get_action (action_group, "AboutAction"),
button);
gtk_widget_show (button);
merge = gtk_ui_manager_new ();
button = gtk_check_button_new ();
gtk_box_pack_end (GTK_BOX (menu_box), button, FALSE, FALSE, 0);
gtk_action_connect_proxy (gtk_action_group_get_action (action_group, "BoldAction"),
button);
gtk_widget_show (button);
merge = gtk_ui_manager_new ();
g_signal_connect (area, "button_press_event",
G_CALLBACK (area_press), merge);
for (tmp = gtk_action_group_list_actions (action_group);
tmp != NULL;
tmp = tmp->next)
{
action = tmp->data;
g_signal_connect (action, "connect-proxy",
G_CALLBACK (connect_proxy), statusbar);
}
merge = gtk_ui_manager_new ();
g_signal_connect (area, "button_press_event", G_CALLBACK (area_press), merge);
gtk_ui_manager_insert_action_group (merge, action_group, 0);
g_signal_connect (merge, "add_widget", G_CALLBACK (add_widget), menu_box);