diff options
author | Ryan Lortie <desrt@desrt.ca> | 2012-08-24 14:11:37 -0400 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2012-09-17 12:31:21 -0400 |
commit | 338b5f6c2dc6cdb73ec3dfb6973b2269d4664b80 (patch) | |
tree | ebde40d433cf55e01be7a5f46d4f5a4a3e9ac22d /examples | |
parent | 9480e215062dc8d0319414bc96bab60e85b7f7a0 (diff) | |
download | gtk+-338b5f6c2dc6cdb73ec3dfb6973b2269d4664b80.tar.gz |
GtkModelMenuItem: add a submenu action attribute
Add support for a stateful action associated with a submenu. The action
state is set to TRUE when the menu is shown and FALSE when it is
unshown.
This is useful to avoid unnecessary processing for menus that have
frequently-changing content.
A possible future feature is to add support for asynchronously filling
the initial state of the menu by waiting until the action actually emits
its state-change signal to TRUE before showing the menu.
A silly example has been added to Bloatpad to demonstrate the new
feature.
https://bugzilla.gnome.org/show_bug.cgi?id=682630
Diffstat (limited to 'examples')
-rw-r--r-- | examples/bloatpad.c | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/examples/bloatpad.c b/examples/bloatpad.c index 537b9d7091..fc8e263e1c 100644 --- a/examples/bloatpad.c +++ b/examples/bloatpad.c @@ -191,7 +191,14 @@ bloat_pad_open (GApplication *application, new_window (application, files[i]); } -typedef GtkApplication BloatPad; +typedef struct +{ + GtkApplication parent_instance; + + GMenu *time; + guint timeout; +} BloatPad; + typedef GtkApplicationClass BloatPadClass; G_DEFINE_TYPE (BloatPad, bloat_pad, GTK_TYPE_APPLICATION) @@ -234,15 +241,65 @@ quit_activated (GSimpleAction *action, g_application_quit (app); } +static gboolean +update_time (gpointer user_data) +{ + BloatPad *bloatpad = user_data; + GDateTime *now; + gchar *time; + + while (g_menu_model_get_n_items (G_MENU_MODEL (bloatpad->time))) + g_menu_remove (bloatpad->time, 0); + + g_message ("Updating the time menu (which should be open now)..."); + + now = g_date_time_new_now_local (); + time = g_date_time_format (now, "%c"); + g_menu_append (bloatpad->time, time, NULL); + g_date_time_unref (now); + g_free (time); + + return G_SOURCE_CONTINUE; +} + +static void +time_active_changed (GSimpleAction *action, + GVariant *state, + gpointer user_data) +{ + BloatPad *bloatpad = user_data; + + if (g_variant_get_boolean (state)) + { + if (!bloatpad->timeout) + { + bloatpad->timeout = g_timeout_add (1000, update_time, bloatpad); + update_time (bloatpad); + } + } + else + { + if (bloatpad->timeout) + { + g_source_remove (bloatpad->timeout); + bloatpad->timeout = 0; + } + } + + g_simple_action_set_state (action, state); +} + static GActionEntry app_entries[] = { { "new", new_activated, NULL, NULL, NULL }, { "about", about_activated, NULL, NULL, NULL }, { "quit", quit_activated, NULL, NULL, NULL }, + { "time-active", NULL, NULL, "false", time_active_changed } }; static void bloat_pad_startup (GApplication *application) { + BloatPad *bloatpad = (BloatPad*) application; GtkBuilder *builder; G_APPLICATION_CLASS (bloat_pad_parent_class) @@ -301,14 +358,34 @@ bloat_pad_startup (GApplication *application) " </item>" " </section>" " </submenu>" + " <submenu id='time-menu'>" + " <attribute name='label' translatable='yes'>Time</attribute>" + " <attribute name='submenu-action'>app.time-active</attribute>" + " </submenu>" " </menu>" "</interface>", -1, NULL); gtk_application_set_app_menu (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu"))); gtk_application_set_menubar (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "menubar"))); + bloatpad->time = G_MENU (gtk_builder_get_object (builder, "time-menu")); g_object_unref (builder); } static void +bloat_pad_shutdown (GApplication *application) +{ + BloatPad *bloatpad = (BloatPad *) application; + + if (bloatpad->timeout) + { + g_source_remove (bloatpad->timeout); + bloatpad->timeout = 0; + } + + G_APPLICATION_CLASS (bloat_pad_parent_class) + ->shutdown (application); +} + +static void bloat_pad_init (BloatPad *app) { } @@ -320,6 +397,7 @@ bloat_pad_class_init (BloatPadClass *class) GObjectClass *object_class = G_OBJECT_CLASS (class); application_class->startup = bloat_pad_startup; + application_class->shutdown = bloat_pad_shutdown; application_class->activate = bloat_pad_activate; application_class->open = bloat_pad_open; @@ -330,7 +408,7 @@ bloat_pad_class_init (BloatPadClass *class) BloatPad * bloat_pad_new (void) { - GtkApplication *bloat_pad; + BloatPad *bloat_pad; g_type_init (); |