diff options
author | Matthias Clasen <maclas@gmx.de> | 2003-08-24 19:58:30 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2003-08-24 19:58:30 +0000 |
commit | e7e395652cfac4aa5385aa91fd6079fae13dd129 (patch) | |
tree | 0673f20be9d82055803dd59a058961c0f0d8b964 /tests | |
parent | 9897d659c082f5e2661b5c26a24c3ed8d0096f0d (diff) | |
download | gtk+-e7e395652cfac4aa5385aa91fd6079fae13dd129.tar.gz |
A model-view separation for menus and toolbars, using the EggMenu code by
2003-08-24 Matthias Clasen <maclas@gmx.de>
* gtk/gtkaction.[ch]:
* gtk/gtktoggleaction.[ch]:
* gtk/gtktoggleactionprivate.h:
* gtk/gtkradioaction.[ch]:
* gtk/gtkactiongroup.[ch]:
* gtk/gtkmenumerge.[ch]: A model-view separation for menus and
toolbars, using the EggMenu code by James Henstridge.
* gtk/gtk.h: Include new headers.
* gtk/Makefile.am: Add new files.
* tests/testactions.c: Test for actions.
* tests/testmerge.c: Test for menu merging.
* tests/merge-[123].ui: Test data for testmerge.
* tests/Makefile.am: Add testactions and testmerge.
* demos/gtk-demo/appwindow.c: Use GtkMenuMerge to construct the
menubar and toolbar.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 19 | ||||
-rw-r--r-- | tests/merge-1.ui | 20 | ||||
-rw-r--r-- | tests/merge-2.ui | 27 | ||||
-rw-r--r-- | tests/merge-3.ui | 23 | ||||
-rw-r--r-- | tests/testactions.c | 268 | ||||
-rw-r--r-- | tests/testmerge.c | 419 |
6 files changed, 774 insertions, 2 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index adff1476f4..367777581a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -54,7 +54,9 @@ noinst_PROGRAMS = \ pixbuf-read \ pixbuf-lowmem \ pixbuf-randomly-modified \ - pixbuf-random + pixbuf-random \ + testmerge \ + testactions simple_DEPENDENCIES = $(TEST_DEPS) testicontheme_DEPENDENCIES = $(TEST_DEPS) @@ -79,6 +81,8 @@ testtreecolumns_DEPENDENCIES = $(DEPS) testtreesort_DEPENDENCIES = $(DEPS) treestoretest_DEPENDENCIES = $(TEST_DEPS) testxinerama_DEPENDENCIES = $(TEST_DEPS) +testmerge_DEPENDENCIES = $(TEST_DEPS) +testactions_DEPENDENCIES = $(TEST_DEPS) simple_LDADD = $(LDADDS) testcalendar_LDADD = $(LDADDS) @@ -109,6 +113,8 @@ pixbuf_read_LDADD = $(LDADDS) pixbuf_lowmem_LDADD = $(LDADDS) pixbuf_randomly_modified_LDADD = $(LDADDS) pixbuf_random_LDADD = $(LDADDS) +testmerge_LDADD = $(LDADDS) +testactions_LDADD = $(LDADDS) testgtk_SOURCES = \ prop-editor.c \ @@ -137,6 +143,12 @@ testsocket_child_SOURCES = \ testsocket_child.c \ testsocket_common.c +testmerge_SOURCES = \ + testmerge.c + +testactions_SOURCES = \ + testactions.c + EXTRA_DIST = \ prop-editor.h \ testgtk.1 \ @@ -152,4 +164,7 @@ EXTRA_DIST = \ test.xpm \ check-y.xpm \ check-n.xpm \ - test.xpm + test.xpm \ + merge-1.ui \ + merge-2.ui \ + merge-3.ui diff --git a/tests/merge-1.ui b/tests/merge-1.ui new file mode 100644 index 0000000000..8ff6a72b2b --- /dev/null +++ b/tests/merge-1.ui @@ -0,0 +1,20 @@ +<!--*- xml -*--> +<Root> + <menu> + <submenu name="FileMenu" verb="StockFileMenuAction"> + <menuitem name="Open" verb="OpenAction" /> + </submenu> + <submenu name="EditMenu" verb="StockEditMenuAction"> + <menuitem name="Cut" verb="CutAction" /> + </submenu> + <placeholder name="TestPlaceholder" /> + </menu> + <dockitem name="toolbar1"> + <placeholder name="ToolbarPlaceholder" /> + <toolitem name="NewButton" verb="NewAction" /> + <toolitem name="CutButton" verb="CutAction" /> + <toolitem name="CopyButton" verb="CopyAction" /> + <toolitem name="PasteButton" verb="PasteAction" /> + <placeholder name="JustifyToolItems"/> + </dockitem> +</Root> diff --git a/tests/merge-2.ui b/tests/merge-2.ui new file mode 100644 index 0000000000..cf32ecfcc4 --- /dev/null +++ b/tests/merge-2.ui @@ -0,0 +1,27 @@ +<!--*- xml -*--> +<Root> + <menu> + <submenu name="FileMenu" verb="StockFileMenuAction"> + <menuitem name="New" verb="NewAction" pos="top" /> + <separator /> + <menuitem name="Quit" verb="QuitAction" /> + </submenu> + <submenu name="HelpMenu" verb="StockHelpMenuAction"> + <menuitem name="About" verb="AboutAction" /> + </submenu> + </menu> + <dockitem name="toolbar1"> + <placeholder name="ToolbarPlaceholder"> + <toolitem name="Quit" verb="QuitAction" /> + <separator /> + </placeholder> + </dockitem> + <popups> + <popup name="FileMenu" verb="StockFileMenuAction"> + <menuitem name="New" verb="NewAction" pos="top" /> + <submenu name="HelpMenu" verb="StockHelpMenuAction"> + <menuitem name="About" verb="AboutAction" /> + </submenu> + </popup> + </popups> +</Root> diff --git a/tests/merge-3.ui b/tests/merge-3.ui new file mode 100644 index 0000000000..397930d27e --- /dev/null +++ b/tests/merge-3.ui @@ -0,0 +1,23 @@ +<!--*- xml -*--> +<Root> + <menu> + <submenu name="FileMenu" verb="StockFileMenuAction"> + <menuitem name="New" verb="New2Action" /> + </submenu> + <placeholder name="TestPlaceholder"> + <submenu name="Test"> + <menuitem name="Cut" verb="CutAction" /> + </submenu> + </placeholder> + </menu> + <dockitem name="toolbar1"> + <placeholder name="JustifyToolItems"> + <separator name="first-sep"/> + <toolitem name="Left" verb="justify-left"/> + <toolitem name="Centre" verb="justify-center"/> + <toolitem name="Right" verb="justify-right"/> + <toolitem name="Fill" verb="justify-fill"/> + <separator name="second-sep" /> + </placeholder> + </dockitem> +</Root> diff --git a/tests/testactions.c b/tests/testactions.c new file mode 100644 index 0000000000..b5e1f6c7d1 --- /dev/null +++ b/tests/testactions.c @@ -0,0 +1,268 @@ +#undef GTK_DISABLE_DEPRECATED +#include <gtk/gtk.h> + +#ifndef _ +# define _(String) (String) +# define N_(String) (String) +#endif + +static GtkActionGroup *action_group = NULL; +static GtkToolbar *toolbar = NULL; + +static void +activate_action (GtkAction *action) +{ + const gchar *name = gtk_action_get_name (action); + const gchar *typename = G_OBJECT_TYPE_NAME (action); + + g_message ("Action %s (type=%s) activated", name, typename); +} + +static void +toggle_action (GtkAction *action) +{ + const gchar *name = gtk_action_get_name (action); + const gchar *typename = G_OBJECT_TYPE_NAME (action); + + g_message ("Action %s (type=%s) activated (active=%d)", name, typename, + gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); +} + +static void +toggle_cnp_actions (GtkAction *action) +{ + gboolean sensitive; + + sensitive = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + action = gtk_action_group_get_action (action_group, "cut"); + g_object_set (action, "sensitive", sensitive, NULL); + action = gtk_action_group_get_action (action_group, "copy"); + g_object_set (action, "sensitive", sensitive, NULL); + action = gtk_action_group_get_action (action_group, "paste"); + g_object_set (action, "sensitive", sensitive, NULL); + + action = gtk_action_group_get_action (action_group, "toggle-cnp"); + if (sensitive) + g_object_set (action, "label", _("Disable Cut and paste ops"), NULL); + else + g_object_set (action, "label", _("Enable Cut and paste ops"), NULL); +} + +static void +show_accel_dialog (GtkAction *action) +{ + g_message ("Sorry, accel dialog not available"); +} + +static void +toolbar_style (GtkAction *action, + gpointer user_data) +{ + GtkToolbarStyle style; + + g_return_if_fail (toolbar != NULL); + style = GPOINTER_TO_INT (user_data); + + gtk_toolbar_set_style (toolbar, style); +} + +static void +toolbar_size (GtkAction *action, + gpointer user_data) +{ + GtkIconSize size; + + g_return_if_fail (toolbar != NULL); + size = GPOINTER_TO_INT (user_data); + + gtk_toolbar_set_icon_size (toolbar, size); +} + +/* convenience functions for declaring actions */ +static GtkActionGroupEntry entries[] = { + { "Menu1Action", N_("Menu _1"), NULL, NULL, NULL, NULL, NULL }, + { "Menu2Action", N_("Menu _2"), NULL, NULL, NULL, NULL, NULL }, + + { "cut", N_("C_ut"), GTK_STOCK_CUT, "<control>X", + N_("Cut the selected text to the clipboard"), + G_CALLBACK (activate_action), NULL }, + { "copy", N_("_Copy"), GTK_STOCK_COPY, "<control>C", + N_("Copy the selected text to the clipboard"), + G_CALLBACK (activate_action), NULL }, + { "paste", N_("_Paste"), GTK_STOCK_PASTE, "<control>V", + N_("Paste the text from the clipboard"), + G_CALLBACK (activate_action), NULL }, + { "bold", N_("_Bold"), GTK_STOCK_BOLD, "<control>B", + N_("Change to bold face"), + G_CALLBACK (toggle_action), NULL, TOGGLE_ACTION }, + + { "justify-left", N_("_Left"), GTK_STOCK_JUSTIFY_LEFT, "<control>L", + N_("Left justify the text"), + G_CALLBACK (toggle_action), NULL, RADIO_ACTION }, + { "justify-center", N_("C_enter"), GTK_STOCK_JUSTIFY_CENTER, "<control>E", + N_("Center justify the text"), + G_CALLBACK (toggle_action), NULL, RADIO_ACTION, "justify-left" }, + { "justify-right", N_("_Right"), GTK_STOCK_JUSTIFY_RIGHT, "<control>R", + N_("Right justify the text"), + G_CALLBACK (toggle_action), NULL, RADIO_ACTION, "justify-left" }, + { "justify-fill", N_("_Fill"), GTK_STOCK_JUSTIFY_FILL, "<control>J", + N_("Fill justify the text"), + G_CALLBACK (toggle_action), NULL, RADIO_ACTION, "justify-left" }, + { "quit", NULL, GTK_STOCK_QUIT, "<control>Q", + N_("Quit the application"), + G_CALLBACK (gtk_main_quit), NULL }, + { "toggle-cnp", N_("Enable Cut/Copy/Paste"), NULL, NULL, + N_("Change the sensitivity of the cut, copy and paste actions"), + G_CALLBACK (toggle_cnp_actions), NULL, TOGGLE_ACTION }, + { "customise-accels", N_("Customise _Accels"), NULL, NULL, + N_("Customise keyboard shortcuts"), + G_CALLBACK (show_accel_dialog), NULL }, + { "toolbar-icons", N_("Icons"), NULL, NULL, + NULL, G_CALLBACK (toolbar_style), GINT_TO_POINTER (GTK_TOOLBAR_ICONS), + RADIO_ACTION, NULL }, + { "toolbar-text", N_("Text"), NULL, NULL, + NULL, G_CALLBACK (toolbar_style), GINT_TO_POINTER (GTK_TOOLBAR_TEXT), + RADIO_ACTION, "toolbar-icons" }, + { "toolbar-both", N_("Both"), NULL, NULL, + NULL, G_CALLBACK (toolbar_style), GINT_TO_POINTER (GTK_TOOLBAR_BOTH), + RADIO_ACTION, "toolbar-icons" }, + { "toolbar-both-horiz", N_("Both Horizontal"), NULL, NULL, + NULL, G_CALLBACK (toolbar_style), GINT_TO_POINTER(GTK_TOOLBAR_BOTH_HORIZ), + RADIO_ACTION, "toolbar-icons" }, + { "toolbar-small-icons", N_("Small Icons"), NULL, NULL, + NULL, + G_CALLBACK (toolbar_size), GINT_TO_POINTER (GTK_ICON_SIZE_SMALL_TOOLBAR) }, + { "toolbar-large-icons", N_("Large Icons"), NULL, NULL, + NULL, + G_CALLBACK (toolbar_size), GINT_TO_POINTER (GTK_ICON_SIZE_LARGE_TOOLBAR) }, +}; +static guint n_entries = G_N_ELEMENTS (entries); + +/* XML description of the menus for the test app. The parser understands + * a subset of the Bonobo UI XML format, and uses GMarkup for parsing */ +static const gchar *ui_info = +"<Root>\n" +" <menu>\n" +" <submenu name=\"Menu _1\" verb=\"Menu1Action\">\n" +" <menuitem name=\"cut\" verb=\"cut\" />\n" +" <menuitem name=\"copy\" verb=\"copy\" />\n" +" <menuitem name=\"paste\" verb=\"paste\" />\n" +" <separator name=\"sep1\" />\n" +" <menuitem name=\"bold1\" verb=\"bold\" />\n" +" <menuitem name=\"bold2\" verb=\"bold\" />\n" +" <separator name=\"sep2\" />\n" +" <menuitem name=\"toggle-cnp\" verb=\"toggle-cnp\" />\n" +" <separator name=\"sep3\" />\n" +" <menuitem name=\"quit\" verb=\"quit\" />\n" +" </submenu>\n" +" <submenu name=\"Menu _2\" verb=\"Menu2Action\">\n" +" <menuitem name=\"cut\" verb=\"cut\" />\n" +" <menuitem name=\"copy\" verb=\"copy\" />\n" +" <menuitem name=\"paste\" verb=\"paste\" />\n" +" <separator name=\"sep4\"/>\n" +" <menuitem name=\"bold\" verb=\"bold\" />\n" +" <separator name=\"sep5\"/>\n" +" <menuitem name=\"justify-left\" verb=\"justify-left\" />\n" +" <menuitem name=\"justify-center\" verb=\"justify-center\" />\n" +" <menuitem name=\"justify-right\" verb=\"justify-right\" />\n" +" <menuitem name=\"justify-fill\" verb=\"justify-fill\" />\n" +" <separator name=\"sep6\"/>\n" +" <menuitem name=\"customise-accels\" verb=\"customise-accels\" />\n" +" <separator name=\"sep7\"/>\n" +" <menuitem verb=\"toolbar-icons\" />\n" +" <menuitem verb=\"toolbar-text\" />\n" +" <menuitem verb=\"toolbar-both\" />\n" +" <menuitem verb=\"toolbar-both-horiz\" />\n" +" <separator name=\"sep8\"/>\n" +" <menuitem verb=\"toolbar-small-icons\" />\n" +" <menuitem verb=\"toolbar-large-icons\" />\n" +" </submenu>\n" +" </menu>\n" +" <dockitem name=\"toolbar\">\n" +" <toolitem name=\"cut\" verb=\"cut\" />\n" +" <toolitem name=\"copy\" verb=\"copy\" />\n" +" <toolitem name=\"paste\" verb=\"paste\" />\n" +" <separator name=\"sep9\" />\n" +" <toolitem name=\"bold\" verb=\"bold\" />\n" +" <separator name=\"sep10\" />\n" +" <toolitem name=\"justify-left\" verb=\"justify-left\" />\n" +" <toolitem name=\"justify-center\" verb=\"justify-center\" />\n" +" <toolitem name=\"justify-right\" verb=\"justify-right\" />\n" +" <toolitem name=\"justify-fill\" verb=\"justify-fill\" />\n" +" <separator name=\"sep11\"/>\n" +" <toolitem name=\"quit\" verb=\"quit\" />\n" +" </dockitem>\n" +"</Root>\n"; + +static void +add_widget (GtkMenuMerge *merge, + GtkWidget *widget, + GtkContainer *container) +{ + + gtk_container_add (container, widget); + gtk_widget_show (widget); + + if (GTK_IS_TOOLBAR (widget)) + { + toolbar = GTK_TOOLBAR (widget); + gtk_toolbar_set_show_arrow (toolbar, TRUE); + } +} + +static void +create_window (GtkActionGroup *action_group) +{ + GtkMenuMerge *merge; + GtkWidget *window; + GtkWidget *box; + GError *error = NULL; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size (GTK_WINDOW (window), -1, -1); + gtk_window_set_title (GTK_WINDOW (window), "Action Test"); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); + + box = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (window), box); + gtk_widget_show (box); + + merge = gtk_menu_merge_new (); + gtk_menu_merge_insert_action_group (merge, action_group, 0); + g_signal_connect (merge, "add_widget", G_CALLBACK (add_widget), box); + + gtk_window_add_accel_group (GTK_WINDOW (window), + gtk_menu_merge_get_accel_group (merge)); + + if (!gtk_menu_merge_add_ui_from_string (merge, ui_info, -1, &error)) + { + g_message ("building menus failed: %s", error->message); + g_error_free (error); + } + + gtk_widget_show (window); +} + +int +main (int argc, char **argv) +{ + gtk_init (&argc, &argv); + + if (g_file_test ("accels", G_FILE_TEST_IS_REGULAR)) + gtk_accel_map_load ("accels"); + + action_group = gtk_action_group_new ("TestActions"); + gtk_action_group_add_actions (action_group, entries, n_entries); + + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (gtk_action_group_get_action (action_group, "toggle-cnp")), TRUE); + + create_window (action_group); + + gtk_main (); + + g_object_unref (action_group); + + gtk_accel_map_save ("accels"); + + return 0; +} diff --git a/tests/testmerge.c b/tests/testmerge.c new file mode 100644 index 0000000000..8e501af7a3 --- /dev/null +++ b/tests/testmerge.c @@ -0,0 +1,419 @@ +#include <stdio.h> +#include <string.h> +#include <gtk/gtk.h> + +#ifndef _ +# define _(String) (String) +# define N_(String) (String) +#endif + +struct { const gchar *filename; guint merge_id; } merge_ids[] = { + { "merge-1.ui", 0 }, + { "merge-2.ui", 0 }, + { "merge-3.ui", 0 } +}; + +static void +dump_tree (GtkWidget *button, + GtkMenuMerge *merge) +{ + gchar *dump; + + dump = gtk_menu_merge_get_ui (merge); + g_message (dump); + g_free (dump); +} + +static void +activate_action (GtkAction *action) +{ + const gchar *name = gtk_action_get_name (action); + const gchar *typename = G_OBJECT_TYPE_NAME (action); + + g_message ("Action %s (type=%s) activated", name, typename); +} + +static void +toggle_action (GtkAction *action) +{ + const gchar *name = gtk_action_get_name (action); + const gchar *typename = G_OBJECT_TYPE_NAME (action); + + g_message ("Action %s (type=%s) activated (active=%d)", name, typename, + gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); +} + + +static GtkActionGroupEntry entries[] = { + { "StockFileMenuAction", N_("_File"), NULL, NULL, NULL, NULL, NULL }, + { "StockEditMenuAction", N_("_Edit"), NULL, NULL, NULL, NULL, NULL }, + { "StockHelpMenuAction", N_("_Help"), NULL, NULL, NULL, NULL, NULL }, + { "Test", N_("Test"), NULL, NULL, NULL, NULL, NULL }, + + { "NewAction", NULL, GTK_STOCK_NEW, "<control>n", NULL, + G_CALLBACK (activate_action), NULL }, + { "New2Action", NULL, GTK_STOCK_NEW, "<control>m", NULL, + G_CALLBACK (activate_action), NULL }, + { "OpenAction", NULL, GTK_STOCK_OPEN, "<control>o", NULL, + G_CALLBACK (activate_action), NULL }, + { "QuitAction", NULL, GTK_STOCK_QUIT, "<control>q", NULL, + G_CALLBACK (gtk_main_quit), NULL }, + { "CutAction", NULL, GTK_STOCK_CUT, "<control>x", NULL, + G_CALLBACK (activate_action), NULL }, + { "CopyAction", NULL, GTK_STOCK_COPY, "<control>c", NULL, + G_CALLBACK (activate_action), NULL }, + { "PasteAction", NULL, GTK_STOCK_PASTE, "<control>v", NULL, + G_CALLBACK (activate_action), NULL }, + { "justify-left", NULL, GTK_STOCK_JUSTIFY_LEFT, "<control>L", + N_("Left justify the text"), + G_CALLBACK (toggle_action), NULL, RADIO_ACTION, NULL }, + { "justify-center", NULL, GTK_STOCK_JUSTIFY_CENTER, "<control>E", + N_("Center justify the text"), + G_CALLBACK (toggle_action), NULL, RADIO_ACTION, "justify-left" }, + { "justify-right", NULL, GTK_STOCK_JUSTIFY_RIGHT, "<control>R", + N_("Right justify the text"), + G_CALLBACK (toggle_action), NULL, RADIO_ACTION, "justify-left" }, + { "justify-fill", NULL, GTK_STOCK_JUSTIFY_FILL, "<control>J", + N_("Fill justify the text"), + G_CALLBACK (toggle_action), NULL, RADIO_ACTION, "justify-left" }, + { "AboutAction", N_("_About"), NULL, NULL, NULL, + G_CALLBACK (activate_action), NULL }, +}; +static guint n_entries = G_N_ELEMENTS (entries); + +static void +add_widget (GtkMenuMerge *merge, + GtkWidget *widget, + GtkBox *box) +{ + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); + gtk_widget_show (widget); +} + +static void +toggle_merge (GtkWidget *button, + GtkMenuMerge *merge) +{ + gint mergenum; + + mergenum = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "mergenum")); + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) + { + GError *err = NULL; + + g_message ("merging %s", merge_ids[mergenum].filename); + merge_ids[mergenum].merge_id = + gtk_menu_merge_add_ui_from_file (merge, merge_ids[mergenum].filename, &err); + if (err != NULL) + { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (button)), + 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, + "could not merge %s: %s", merge_ids[mergenum].filename, + err->message); + + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_object_destroy), NULL); + gtk_widget_show (dialog); + + g_clear_error (&err); + } + } + else + { + g_message ("unmerging %s (merge_id=%u)", merge_ids[mergenum].filename, + merge_ids[mergenum].merge_id); + gtk_menu_merge_remove_ui (merge, merge_ids[mergenum].merge_id); + } +} + +static void +set_name_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + GtkAction *action; + char *name; + + gtk_tree_model_get (tree_model, iter, 0, &action, -1); + g_object_get (G_OBJECT (action), "name", &name, NULL); + g_object_set (G_OBJECT (cell), "text", name, NULL); + g_free (name); + g_object_unref (action); +} + +static void +set_sensitive_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + GtkAction *action; + gboolean sensitive; + + gtk_tree_model_get (tree_model, iter, 0, &action, -1); + g_object_get (G_OBJECT (action), "sensitive", &sensitive, NULL); + g_object_set (G_OBJECT (cell), "active", sensitive, NULL); + g_object_unref (action); +} + + +static void +set_visible_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + GtkAction *action; + gboolean visible; + + gtk_tree_model_get (tree_model, iter, 0, &action, -1); + g_object_get (G_OBJECT (action), "visible", &visible, NULL); + g_object_set (G_OBJECT (cell), "active", visible, NULL); + g_object_unref (action); +} + +static void +sensitivity_toggled (GtkCellRendererToggle *cell, + const gchar *path_str, + GtkTreeModel *model) +{ + GtkTreePath *path; + GtkTreeIter iter; + GtkAction *action; + gboolean sensitive; + + path = gtk_tree_path_new_from_string (path_str); + gtk_tree_model_get_iter (model, &iter, path); + + gtk_tree_model_get (model, &iter, 0, &action, -1); + g_object_get (G_OBJECT (action), "sensitive", &sensitive, NULL); + g_object_set (G_OBJECT (action), "sensitive", !sensitive, NULL); + gtk_tree_model_row_changed (model, path, &iter); + gtk_tree_path_free (path); +} + +static void +visibility_toggled (GtkCellRendererToggle *cell, + const gchar *path_str, + GtkTreeModel *model) +{ + GtkTreePath *path; + GtkTreeIter iter; + GtkAction *action; + gboolean visible; + + path = gtk_tree_path_new_from_string (path_str); + gtk_tree_model_get_iter (model, &iter, path); + + gtk_tree_model_get (model, &iter, 0, &action, -1); + g_object_get (G_OBJECT (action), "visible", &visible, NULL); + g_object_set (G_OBJECT (action), "visible", !visible, NULL); + gtk_tree_model_row_changed (model, path, &iter); + gtk_tree_path_free (path); +} + +static gint +iter_compare_func (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer user_data) +{ + GValue a_value = { 0, }, b_value = { 0, }; + GtkAction *a_action, *b_action; + const gchar *a_name, *b_name; + gint retval = 0; + + gtk_tree_model_get_value (model, a, 0, &a_value); + gtk_tree_model_get_value (model, b, 0, &b_value); + a_action = GTK_ACTION (g_value_get_object (&a_value)); + b_action = GTK_ACTION (g_value_get_object (&b_value)); + + a_name = gtk_action_get_name (a_action); + b_name = gtk_action_get_name (b_action); + if (a_name == NULL && b_name == NULL) + retval = 0; + else if (a_name == NULL) + retval = -1; + else if (b_name == NULL) + retval = 1; + else + retval = strcmp (a_name, b_name); + + g_value_unset (&b_value); + g_value_unset (&a_value); + + return retval; +} + +static GtkWidget * +create_tree_view (GtkMenuMerge *merge) +{ + GtkWidget *tree_view, *sw; + GtkListStore *store; + GList *p; + GtkCellRenderer *cell; + + store = gtk_list_store_new (1, GTK_TYPE_ACTION); + gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), 0, + iter_compare_func, NULL, NULL); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), 0, + GTK_SORT_ASCENDING); + + for (p = gtk_menu_merge_get_action_groups (merge); p; p = p->next) + { + GList *actions, *l; + + actions = gtk_action_group_list_actions (p->data); + + for (l = actions; l; l = l->next) + { + GtkTreeIter iter; + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, l->data, -1); + } + } + + tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + g_object_unref (store); + + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view), + -1, "Action", + gtk_cell_renderer_text_new (), + set_name_func, NULL, NULL); + + gtk_tree_view_column_set_sort_column_id (gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), 0), 0); + + cell = gtk_cell_renderer_toggle_new (); + g_signal_connect (cell, "toggled", G_CALLBACK (sensitivity_toggled), store); + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view), + -1, "Sensitive", + cell, + set_sensitive_func, NULL, NULL); + + cell = gtk_cell_renderer_toggle_new (); + g_signal_connect (cell, "toggled", G_CALLBACK (visibility_toggled), store); + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (tree_view), + -1, "Visible", + cell, + set_visible_func, NULL, NULL); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (sw), tree_view); + + return sw; +} + +static gboolean +area_press (GtkWidget *drawing_area, + GdkEventButton *event, + GtkMenuMerge *merge) +{ + gtk_widget_grab_focus (drawing_area); + + if (event->button == 3 && + event->type == GDK_BUTTON_PRESS) + { + GtkWidget *menu = gtk_menu_merge_get_widget (merge, "/popups/FileMenu"); + + if (GTK_IS_MENU (menu)) + { + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, + NULL, drawing_area, + 3, event->time); + return TRUE; + } + } + + return FALSE; + +} + +int +main (int argc, char **argv) +{ + GtkActionGroup *action_group; + GtkMenuMerge *merge; + GtkWidget *window, *table, *frame, *menu_box, *vbox, *view, *area; + GtkWidget *button; + gint i; + + gtk_init (&argc, &argv); + + action_group = gtk_action_group_new ("TestActions"); + gtk_action_group_add_actions (action_group, entries, n_entries); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size (GTK_WINDOW (window), -1, 400); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); + + table = gtk_table_new (2, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 2); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_container_set_border_width (GTK_CONTAINER (table), 2); + gtk_container_add (GTK_CONTAINER (window), table); + + frame = gtk_frame_new ("Menus and Toolbars"); + gtk_table_attach (GTK_TABLE (table), frame, 0,2, 1,2, + GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0); + + 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); + + area = gtk_drawing_area_new (); + gtk_widget_set_events (area, GDK_BUTTON_PRESS_MASK); + gtk_widget_set_size_request (area, -1, 40); + gtk_box_pack_end (GTK_BOX (menu_box), area, FALSE, FALSE, 0); + gtk_widget_show (area); + + merge = gtk_menu_merge_new (); + + g_signal_connect (area, "button_press_event", + G_CALLBACK (area_press), merge); + + gtk_menu_merge_insert_action_group (merge, action_group, 0); + g_signal_connect (merge, "add_widget", G_CALLBACK (add_widget), menu_box); + + gtk_window_add_accel_group (GTK_WINDOW (window), + gtk_menu_merge_get_accel_group (merge)); + + frame = gtk_frame_new ("UI Files"); + gtk_table_attach (GTK_TABLE (table), frame, 0,1, 0,1, + GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0); + + vbox = gtk_vbox_new (FALSE, 2); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); + gtk_container_add (GTK_CONTAINER (frame), vbox); + + for (i = 0; i < G_N_ELEMENTS (merge_ids); i++) + { + button = gtk_check_button_new_with_label (merge_ids[i].filename); + g_object_set_data (G_OBJECT (button), "mergenum", GINT_TO_POINTER (i)); + g_signal_connect (button, "toggled", G_CALLBACK (toggle_merge), merge); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + } + + button = gtk_button_new_with_mnemonic ("_Dump Tree"); + g_signal_connect (button, "clicked", G_CALLBACK (dump_tree), merge); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + + view = create_tree_view (merge); + gtk_table_attach (GTK_TABLE (table), view, 1,2, 0,1, + GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0); + + gtk_widget_show_all (window); + gtk_main (); + + + return 0; +} |