mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 05:50:10 +00:00
Add API to create menus from models
This is needed to bring context menus, etc into the GAction world.
This commit is contained in:
parent
e7d6400149
commit
4240bfb74a
@ -2059,6 +2059,7 @@ gtk_link_button_get_type
|
|||||||
<TITLE>GtkMenu</TITLE>
|
<TITLE>GtkMenu</TITLE>
|
||||||
GtkMenu
|
GtkMenu
|
||||||
gtk_menu_new
|
gtk_menu_new
|
||||||
|
gtk_menu_new_from_model
|
||||||
gtk_menu_set_screen
|
gtk_menu_set_screen
|
||||||
gtk_menu_reorder_child
|
gtk_menu_reorder_child
|
||||||
gtk_menu_attach
|
gtk_menu_attach
|
||||||
@ -2103,6 +2104,7 @@ gtk_menu_get_type
|
|||||||
<TITLE>GtkMenuBar</TITLE>
|
<TITLE>GtkMenuBar</TITLE>
|
||||||
GtkMenuBar
|
GtkMenuBar
|
||||||
gtk_menu_bar_new
|
gtk_menu_bar_new
|
||||||
|
gtk_menu_bar_new_from_model
|
||||||
GtkPackDirection
|
GtkPackDirection
|
||||||
gtk_menu_bar_set_pack_direction
|
gtk_menu_bar_set_pack_direction
|
||||||
gtk_menu_bar_get_pack_direction
|
gtk_menu_bar_get_pack_direction
|
||||||
|
@ -1533,6 +1533,7 @@ gtk_menu_bar_get_child_pack_direction
|
|||||||
gtk_menu_bar_get_pack_direction
|
gtk_menu_bar_get_pack_direction
|
||||||
gtk_menu_bar_get_type
|
gtk_menu_bar_get_type
|
||||||
gtk_menu_bar_new
|
gtk_menu_bar_new
|
||||||
|
gtk_menu_bar_new_from_model
|
||||||
gtk_menu_bar_set_child_pack_direction
|
gtk_menu_bar_set_child_pack_direction
|
||||||
gtk_menu_bar_set_pack_direction
|
gtk_menu_bar_set_pack_direction
|
||||||
gtk_menu_detach
|
gtk_menu_detach
|
||||||
@ -1569,6 +1570,7 @@ gtk_menu_item_set_use_underline
|
|||||||
gtk_menu_item_toggle_size_allocate
|
gtk_menu_item_toggle_size_allocate
|
||||||
gtk_menu_item_toggle_size_request
|
gtk_menu_item_toggle_size_request
|
||||||
gtk_menu_new
|
gtk_menu_new
|
||||||
|
gtk_menu_new_from_model
|
||||||
gtk_menu_popdown
|
gtk_menu_popdown
|
||||||
gtk_menu_popup
|
gtk_menu_popup
|
||||||
gtk_menu_popup_for_device
|
gtk_menu_popup_for_device
|
||||||
|
@ -38,6 +38,13 @@ G_GNUC_INTERNAL
|
|||||||
GSimpleActionObserver * gtk_application_window_create_observer (GtkApplicationWindow *window,
|
GSimpleActionObserver * gtk_application_window_create_observer (GtkApplicationWindow *window,
|
||||||
const gchar *action_name,
|
const gchar *action_name,
|
||||||
GVariant *target);
|
GVariant *target);
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
GActionObservable * gtk_application_window_get_observable (GtkApplicationWindow *window);
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
GtkAccelGroup * gtk_application_window_get_accel_group (GtkApplicationWindow *window);
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
const gchar * gtk_application_get_dbus_object_path (GtkApplication *application);
|
const gchar * gtk_application_get_dbus_object_path (GtkApplication *application);
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
|
@ -1012,3 +1012,15 @@ gtk_application_window_create_observer (GtkApplicationWindow *window,
|
|||||||
|
|
||||||
return g_simple_action_observer_new (window->priv->muxer, action_name, target);
|
return g_simple_action_observer_new (window->priv->muxer, action_name, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GActionObservable *
|
||||||
|
gtk_application_window_get_observable (GtkApplicationWindow *window)
|
||||||
|
{
|
||||||
|
return G_ACTION_OBSERVABLE (window->priv->muxer);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkAccelGroup *
|
||||||
|
gtk_application_window_get_accel_group (GtkApplicationWindow *window)
|
||||||
|
{
|
||||||
|
return window->priv->accels;
|
||||||
|
}
|
||||||
|
@ -117,6 +117,7 @@ struct _GtkMenuClass
|
|||||||
|
|
||||||
GType gtk_menu_get_type (void) G_GNUC_CONST;
|
GType gtk_menu_get_type (void) G_GNUC_CONST;
|
||||||
GtkWidget* gtk_menu_new (void);
|
GtkWidget* gtk_menu_new (void);
|
||||||
|
GtkWidget* gtk_menu_new_from_model (GMenuModel *model);
|
||||||
|
|
||||||
/* Display the menu onscreen */
|
/* Display the menu onscreen */
|
||||||
void gtk_menu_popup (GtkMenu *menu,
|
void gtk_menu_popup (GtkMenu *menu,
|
||||||
|
@ -71,6 +71,7 @@ struct _GtkMenuBarClass
|
|||||||
|
|
||||||
GType gtk_menu_bar_get_type (void) G_GNUC_CONST;
|
GType gtk_menu_bar_get_type (void) G_GNUC_CONST;
|
||||||
GtkWidget* gtk_menu_bar_new (void);
|
GtkWidget* gtk_menu_bar_new (void);
|
||||||
|
GtkWidget* gtk_menu_bar_new_from_model (GMenuModel *model);
|
||||||
|
|
||||||
GtkPackDirection gtk_menu_bar_get_pack_direction (GtkMenuBar *menubar);
|
GtkPackDirection gtk_menu_bar_get_pack_direction (GtkMenuBar *menubar);
|
||||||
void gtk_menu_bar_set_pack_direction (GtkMenuBar *menubar,
|
void gtk_menu_bar_set_pack_direction (GtkMenuBar *menubar,
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "gtkmenubar.h"
|
#include "gtkmenubar.h"
|
||||||
#include "gtkseparatormenuitem.h"
|
#include "gtkseparatormenuitem.h"
|
||||||
#include "gtkmodelmenuitem.h"
|
#include "gtkmodelmenuitem.h"
|
||||||
|
#include "gtkapplicationprivate.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GActionObservable *actions;
|
GActionObservable *actions;
|
||||||
@ -65,7 +66,8 @@ gtk_model_menu_binding_free (gpointer data)
|
|||||||
binding->connected = g_slist_delete_link (binding->connected, binding->connected);
|
binding->connected = g_slist_delete_link (binding->connected, binding->connected);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (binding->actions);
|
if (binding->actions)
|
||||||
|
g_object_unref (binding->actions);
|
||||||
g_object_unref (binding->model);
|
g_object_unref (binding->model);
|
||||||
|
|
||||||
g_slice_free (GtkModelMenuBinding, binding);
|
g_slice_free (GtkModelMenuBinding, binding);
|
||||||
@ -224,25 +226,38 @@ gtk_model_menu_binding_items_changed (GMenuModel *model,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
gtk_model_menu_bind (GtkMenuShell *shell,
|
gtk_model_menu_bind (GtkMenuShell *shell,
|
||||||
GMenuModel *model,
|
GMenuModel *model,
|
||||||
GActionObservable *actions,
|
|
||||||
GtkAccelGroup *accels,
|
|
||||||
gboolean with_separators)
|
gboolean with_separators)
|
||||||
{
|
{
|
||||||
GtkModelMenuBinding *binding;
|
GtkModelMenuBinding *binding;
|
||||||
|
|
||||||
binding = g_slice_new (GtkModelMenuBinding);
|
binding = g_slice_new (GtkModelMenuBinding);
|
||||||
binding->model = g_object_ref (model);
|
binding->model = g_object_ref (model);
|
||||||
binding->actions = g_object_ref (actions);
|
binding->actions = NULL;
|
||||||
binding->accels = accels;
|
binding->accels = NULL;
|
||||||
binding->shell = shell;
|
binding->shell = shell;
|
||||||
binding->update_idle = 0;
|
binding->update_idle = 0;
|
||||||
binding->connected = NULL;
|
binding->connected = NULL;
|
||||||
binding->with_separators = with_separators;
|
binding->with_separators = with_separators;
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (shell), "gtk-model-menu-binding", binding, gtk_model_menu_binding_free);
|
g_object_set_data_full (G_OBJECT (shell), "gtk-model-menu-binding", binding, gtk_model_menu_binding_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_model_menu_populate (GtkMenuShell *shell,
|
||||||
|
GActionObservable *actions,
|
||||||
|
GtkAccelGroup *accels)
|
||||||
|
{
|
||||||
|
GtkModelMenuBinding *binding;
|
||||||
|
|
||||||
|
binding = (GtkModelMenuBinding*) g_object_get_data (G_OBJECT (shell), "gtk-model-menu-binding");
|
||||||
|
|
||||||
|
binding->actions = g_object_ref (actions);
|
||||||
|
binding->accels = accels;
|
||||||
|
|
||||||
gtk_model_menu_binding_populate (binding);
|
gtk_model_menu_binding_populate (binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,8 +269,59 @@ gtk_model_menu_create_menu (GMenuModel *model,
|
|||||||
GtkWidget *menu;
|
GtkWidget *menu;
|
||||||
|
|
||||||
menu = gtk_menu_new ();
|
menu = gtk_menu_new ();
|
||||||
gtk_menu_set_accel_group (GTK_MENU (menu), accels);
|
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, actions, accels, TRUE);
|
gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, FALSE);
|
||||||
|
gtk_model_menu_populate (GTK_MENU_SHELL (menu), actions, accels);
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_attach (GtkMenu *menu,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkWidget *widget;
|
||||||
|
GtkWidget *toplevel;
|
||||||
|
GActionObservable *actions;
|
||||||
|
GtkAccelGroup *accels;
|
||||||
|
|
||||||
|
widget = gtk_menu_get_attach_widget (menu);
|
||||||
|
toplevel = gtk_widget_get_toplevel (widget);
|
||||||
|
if (GTK_IS_APPLICATION_WINDOW (toplevel))
|
||||||
|
{
|
||||||
|
actions = gtk_application_window_get_observable (GTK_APPLICATION_WINDOW (toplevel));
|
||||||
|
accels = gtk_application_window_get_accel_group (GTK_APPLICATION_WINDOW (toplevel));
|
||||||
|
|
||||||
|
gtk_model_menu_populate (GTK_MENU_SHELL (menu), actions, accels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_menu_new_from_model:
|
||||||
|
* @model: a #GMenuModel
|
||||||
|
*
|
||||||
|
* Creates a #GtkMenu and populates it with menu items and
|
||||||
|
* submenus according to @model.
|
||||||
|
*
|
||||||
|
* The created menu items are connected to actions found in the
|
||||||
|
* #GtkApplicationWindow to which the menu belongs - typically
|
||||||
|
* by means of being attached to a widget (see gtk_menu_attach_to_widget())
|
||||||
|
* that is contained within the #GtkApplicationWindows widget hierarchy.
|
||||||
|
*
|
||||||
|
* Returns: a new #GtkMenu
|
||||||
|
*
|
||||||
|
* Since: 3.4
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
gtk_menu_new_from_model (GMenuModel *model)
|
||||||
|
{
|
||||||
|
GtkWidget *menu;
|
||||||
|
|
||||||
|
menu = gtk_menu_new ();
|
||||||
|
gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, TRUE);
|
||||||
|
g_signal_connect (menu, "notify::attach-widget",
|
||||||
|
G_CALLBACK (notify_attach), NULL);
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
@ -268,8 +334,59 @@ gtk_model_menu_create_menu_bar (GMenuModel *model,
|
|||||||
GtkWidget *menubar;
|
GtkWidget *menubar;
|
||||||
|
|
||||||
menubar = gtk_menu_bar_new ();
|
menubar = gtk_menu_bar_new ();
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, actions, accels, FALSE);
|
|
||||||
|
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, FALSE);
|
||||||
|
gtk_model_menu_populate (GTK_MENU_SHELL (menubar), actions, accels);
|
||||||
|
|
||||||
return menubar;
|
return menubar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hierarchy_changed (GtkMenuShell *shell,
|
||||||
|
GObject *previous_toplevel,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkWidget *toplevel;
|
||||||
|
GActionObservable *actions;
|
||||||
|
GtkAccelGroup *accels;
|
||||||
|
|
||||||
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
|
||||||
|
if (GTK_IS_APPLICATION_WINDOW (toplevel))
|
||||||
|
{
|
||||||
|
actions = gtk_application_window_get_observable (GTK_APPLICATION_WINDOW (toplevel));
|
||||||
|
accels = gtk_application_window_get_accel_group (GTK_APPLICATION_WINDOW (toplevel));
|
||||||
|
|
||||||
|
gtk_model_menu_populate (shell, actions, accels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_menu_bar_new_from_model:
|
||||||
|
* @model: a #GMenuModel
|
||||||
|
*
|
||||||
|
* Creates a new #GtkMenuBar and populates it with menu items
|
||||||
|
* and submenus according to @model.
|
||||||
|
*
|
||||||
|
* The created menu items are connected to actions found in the
|
||||||
|
* #GtkApplicationWindow to which the menu bar belongs - typically
|
||||||
|
* by means of being contained within the #GtkApplicationWindows
|
||||||
|
* widget hierarchy.
|
||||||
|
*
|
||||||
|
* Returns: a new #GtkMenuBar
|
||||||
|
*
|
||||||
|
* Since: 3.4
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
gtk_menu_bar_new_from_model (GMenuModel *model)
|
||||||
|
{
|
||||||
|
GtkWidget *menubar;
|
||||||
|
|
||||||
|
menubar = gtk_menu_bar_new ();
|
||||||
|
|
||||||
|
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, FALSE);
|
||||||
|
|
||||||
|
g_signal_connect (menubar, "hierarchy-changed",
|
||||||
|
G_CALLBACK (hierarchy_changed), NULL);
|
||||||
|
|
||||||
|
return menubar;
|
||||||
|
}
|
||||||
|
@ -27,19 +27,10 @@
|
|||||||
#include <gtk/gtkaccelgroup.h>
|
#include <gtk/gtkaccelgroup.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
|
||||||
void gtk_model_menu_bind (GtkMenuShell *shell,
|
|
||||||
GMenuModel *model,
|
|
||||||
GActionObservable *actions,
|
|
||||||
GtkAccelGroup *accels,
|
|
||||||
gboolean with_separators);
|
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
|
||||||
GtkWidget * gtk_model_menu_create_menu_bar (GMenuModel *model,
|
GtkWidget * gtk_model_menu_create_menu_bar (GMenuModel *model,
|
||||||
GActionObservable *actions,
|
GActionObservable *actions,
|
||||||
GtkAccelGroup *accels);
|
GtkAccelGroup *accels);
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
|
||||||
GtkWidget * gtk_model_menu_create_menu (GMenuModel *model,
|
GtkWidget * gtk_model_menu_create_menu (GMenuModel *model,
|
||||||
GActionObservable *actions,
|
GActionObservable *actions,
|
||||||
GtkAccelGroup *accels);
|
GtkAccelGroup *accels);
|
||||||
|
@ -235,15 +235,19 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
|||||||
/* observer already causes us to hold a hard ref on the group */
|
/* observer already causes us to hold a hard ref on the group */
|
||||||
item->actions = G_ACTION_GROUP (actions);
|
item->actions = G_ACTION_GROUP (actions);
|
||||||
|
|
||||||
g_action_observable_register_observer (actions, item->action_name, G_ACTION_OBSERVER (item));
|
if (actions)
|
||||||
|
|
||||||
if (g_action_group_query_action (G_ACTION_GROUP (actions), item->action_name, &enabled, &type, NULL, NULL, &state))
|
|
||||||
{
|
{
|
||||||
gtk_model_menu_item_action_added (G_ACTION_OBSERVER (item), actions, item->action_name, type, enabled, state);
|
g_action_observable_register_observer (actions, item->action_name, G_ACTION_OBSERVER (item));
|
||||||
if (state != NULL)
|
|
||||||
g_variant_unref (state);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (g_action_group_query_action (G_ACTION_GROUP (actions), item->action_name, &enabled, &type, NULL, NULL, &state))
|
||||||
|
{
|
||||||
|
gtk_model_menu_item_action_added (G_ACTION_OBSERVER (item), actions, item->action_name, type, enabled, state);
|
||||||
|
if (state != NULL)
|
||||||
|
g_variant_unref (state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
|
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user