gtkmodelmenu: move to new action regime
Drop the explicit passing of GActionGroup into the GtkMenu(Bar) constructors and operate from the action context instead. With GtkMenuItem implementing GtkActionable, this turns out to be pretty easy (and most of the code can be removed from GtkModelMenuItem, including the GActionObserver implementation).
This commit is contained in:
parent
ea5a56dacf
commit
dd45862a06
@ -258,7 +258,7 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
|
|||||||
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
|
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
|
||||||
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
|
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
|
||||||
|
|
||||||
window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined), window->priv->muxer, window->priv->accels);
|
window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined), window->priv->accels);
|
||||||
gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
|
gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
|
||||||
gtk_widget_show_all (window->priv->menubar);
|
gtk_widget_show_all (window->priv->menubar);
|
||||||
g_object_unref (combined);
|
g_object_unref (combined);
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#define MODEL_MENU_WIDGET_DATA "gtk-model-menu-widget-data"
|
#define MODEL_MENU_WIDGET_DATA "gtk-model-menu-widget-data"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GActionObservable *actions;
|
|
||||||
GMenuModel *model;
|
GMenuModel *model;
|
||||||
GtkAccelGroup *accels;
|
GtkAccelGroup *accels;
|
||||||
GtkMenuShell *shell;
|
GtkMenuShell *shell;
|
||||||
@ -66,8 +65,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -85,12 +82,13 @@ gtk_model_menu_binding_append_item (GtkModelMenuBinding *binding,
|
|||||||
{
|
{
|
||||||
g_menu_model_get_item_attribute (model, item_index, "label", "s", heading);
|
g_menu_model_get_item_attribute (model, item_index, "label", "s", heading);
|
||||||
gtk_model_menu_binding_append_model (binding, section, FALSE);
|
gtk_model_menu_binding_append_model (binding, section, FALSE);
|
||||||
|
g_object_unref (section);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GtkMenuItem *item;
|
GtkMenuItem *item;
|
||||||
|
|
||||||
item = gtk_model_menu_item_new (model, item_index, binding->actions, binding->accels);
|
item = gtk_model_menu_item_new (model, item_index, binding->accels);
|
||||||
gtk_menu_shell_append (binding->shell, GTK_WIDGET (item));
|
gtk_menu_shell_append (binding->shell, GTK_WIDGET (item));
|
||||||
gtk_widget_show (GTK_WIDGET (item));
|
gtk_widget_show (GTK_WIDGET (item));
|
||||||
binding->n_items++;
|
binding->n_items++;
|
||||||
@ -227,15 +225,14 @@ gtk_model_menu_binding_items_changed (GMenuModel *model,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_model_menu_bind (GtkMenuShell *shell,
|
gtk_model_menu_bind (GtkMenuShell *shell,
|
||||||
GMenuModel *model,
|
GMenuModel *model,
|
||||||
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 = NULL;
|
|
||||||
binding->accels = NULL;
|
binding->accels = NULL;
|
||||||
binding->shell = shell;
|
binding->shell = shell;
|
||||||
binding->update_idle = 0;
|
binding->update_idle = 0;
|
||||||
@ -247,24 +244,21 @@ gtk_model_menu_bind (GtkMenuShell *shell,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_model_menu_populate (GtkMenuShell *shell,
|
gtk_model_menu_populate (GtkMenuShell *shell,
|
||||||
GActionObservable *actions,
|
GtkAccelGroup *accels)
|
||||||
GtkAccelGroup *accels)
|
|
||||||
{
|
{
|
||||||
GtkModelMenuBinding *binding;
|
GtkModelMenuBinding *binding;
|
||||||
|
|
||||||
binding = (GtkModelMenuBinding*) g_object_get_data (G_OBJECT (shell), "gtk-model-menu-binding");
|
binding = (GtkModelMenuBinding*) g_object_get_data (G_OBJECT (shell), "gtk-model-menu-binding");
|
||||||
|
|
||||||
binding->actions = g_object_ref (actions);
|
|
||||||
binding->accels = accels;
|
binding->accels = accels;
|
||||||
|
|
||||||
gtk_model_menu_binding_populate (binding);
|
gtk_model_menu_binding_populate (binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
gtk_model_menu_create_menu (GMenuModel *model,
|
gtk_model_menu_create_menu (GMenuModel *model,
|
||||||
GActionObservable *actions,
|
GtkAccelGroup *accels)
|
||||||
GtkAccelGroup *accels)
|
|
||||||
{
|
{
|
||||||
GtkWidget *menu;
|
GtkWidget *menu;
|
||||||
|
|
||||||
@ -272,69 +266,11 @@ gtk_model_menu_create_menu (GMenuModel *model,
|
|||||||
gtk_menu_set_accel_group (GTK_MENU (menu), accels);
|
gtk_menu_set_accel_group (GTK_MENU (menu), accels);
|
||||||
|
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, TRUE);
|
gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, TRUE);
|
||||||
gtk_model_menu_populate (GTK_MENU_SHELL (menu), actions, accels);
|
gtk_model_menu_populate (GTK_MENU_SHELL (menu), accels);
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_model_menu_connect_app_window (GtkMenu *menu,
|
|
||||||
GtkApplicationWindow *window)
|
|
||||||
{
|
|
||||||
GActionObservable *actions;
|
|
||||||
GtkAccelGroup *accels;
|
|
||||||
|
|
||||||
actions = gtk_application_window_get_observable (window);
|
|
||||||
accels = gtk_application_window_get_accel_group (window);
|
|
||||||
|
|
||||||
gtk_menu_set_accel_group (menu, accels);
|
|
||||||
gtk_model_menu_populate (GTK_MENU_SHELL (menu), actions, accels);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
attach_widget_hierarchy_changed (GtkWidget *attach_widget,
|
|
||||||
GtkWidget *previous_toplevel,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GtkWidget *toplevel;
|
|
||||||
GtkMenu *menu = user_data;
|
|
||||||
|
|
||||||
toplevel = gtk_widget_get_toplevel (attach_widget);
|
|
||||||
if (GTK_IS_APPLICATION_WINDOW (toplevel))
|
|
||||||
gtk_model_menu_connect_app_window (menu, GTK_APPLICATION_WINDOW (toplevel));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
notify_attach (GtkMenu *menu,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkWidget *attach_widget, *toplevel;
|
|
||||||
|
|
||||||
attach_widget = g_object_get_data (G_OBJECT (menu), MODEL_MENU_WIDGET_DATA);
|
|
||||||
if (attach_widget != NULL)
|
|
||||||
{
|
|
||||||
g_signal_handlers_disconnect_by_func (attach_widget, attach_widget_hierarchy_changed, menu);
|
|
||||||
g_object_set_data (G_OBJECT (menu), MODEL_MENU_WIDGET_DATA, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
attach_widget = gtk_menu_get_attach_widget (menu);
|
|
||||||
if (!attach_widget)
|
|
||||||
return;
|
|
||||||
|
|
||||||
toplevel = gtk_widget_get_toplevel (attach_widget);
|
|
||||||
if (GTK_IS_APPLICATION_WINDOW (toplevel))
|
|
||||||
{
|
|
||||||
gtk_model_menu_connect_app_window (menu, GTK_APPLICATION_WINDOW (toplevel));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_object_set_data (G_OBJECT (menu), MODEL_MENU_WIDGET_DATA, attach_widget);
|
|
||||||
g_signal_connect_object (attach_widget, "hierarchy-changed",
|
|
||||||
G_CALLBACK (attach_widget_hierarchy_changed), menu, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_menu_new_from_model:
|
* gtk_menu_new_from_model:
|
||||||
* @model: a #GMenuModel
|
* @model: a #GMenuModel
|
||||||
@ -358,46 +294,25 @@ gtk_menu_new_from_model (GMenuModel *model)
|
|||||||
|
|
||||||
menu = gtk_menu_new ();
|
menu = gtk_menu_new ();
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, TRUE);
|
gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, TRUE);
|
||||||
g_signal_connect (menu, "notify::attach-widget",
|
gtk_model_menu_populate (GTK_MENU_SHELL (menu), NULL);
|
||||||
G_CALLBACK (notify_attach), NULL);
|
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
gtk_model_menu_create_menu_bar (GMenuModel *model,
|
gtk_model_menu_create_menu_bar (GMenuModel *model,
|
||||||
GActionObservable *actions,
|
GtkAccelGroup *accels)
|
||||||
GtkAccelGroup *accels)
|
|
||||||
{
|
{
|
||||||
GtkWidget *menubar;
|
GtkWidget *menubar;
|
||||||
|
|
||||||
menubar = gtk_menu_bar_new ();
|
menubar = gtk_menu_bar_new ();
|
||||||
|
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, FALSE);
|
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, FALSE);
|
||||||
gtk_model_menu_populate (GTK_MENU_SHELL (menubar), actions, accels);
|
gtk_model_menu_populate (GTK_MENU_SHELL (menubar), 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:
|
* gtk_menu_bar_new_from_model:
|
||||||
* @model: a #GMenuModel
|
* @model: a #GMenuModel
|
||||||
@ -422,9 +337,7 @@ gtk_menu_bar_new_from_model (GMenuModel *model)
|
|||||||
menubar = gtk_menu_bar_new ();
|
menubar = gtk_menu_bar_new ();
|
||||||
|
|
||||||
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, FALSE);
|
gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, FALSE);
|
||||||
|
gtk_model_menu_populate (GTK_MENU_SHELL (menubar), NULL);
|
||||||
g_signal_connect (menubar, "hierarchy-changed",
|
|
||||||
G_CALLBACK (hierarchy_changed), NULL);
|
|
||||||
|
|
||||||
return menubar;
|
return menubar;
|
||||||
}
|
}
|
||||||
|
@ -20,19 +20,16 @@
|
|||||||
#ifndef __GTK_MODEL_MENU_H__
|
#ifndef __GTK_MODEL_MENU_H__
|
||||||
#define __GTK_MODEL_MENU_H__
|
#define __GTK_MODEL_MENU_H__
|
||||||
|
|
||||||
#include <gtk/gactionobservable.h>
|
|
||||||
#include <gtk/gtkmenushell.h>
|
#include <gtk/gtkmenushell.h>
|
||||||
#include <gtk/gtkaccelgroup.h>
|
#include <gtk/gtkaccelgroup.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
GtkWidget * gtk_model_menu_create_menu_bar (GMenuModel *model,
|
GtkWidget * gtk_model_menu_create_menu_bar (GMenuModel *model,
|
||||||
GActionObservable *actions,
|
|
||||||
GtkAccelGroup *accels);
|
GtkAccelGroup *accels);
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
GtkWidget * gtk_model_menu_create_menu (GMenuModel *model,
|
GtkWidget * gtk_model_menu_create_menu (GMenuModel *model,
|
||||||
GActionObservable *actions,
|
|
||||||
GtkAccelGroup *accels);
|
GtkAccelGroup *accels);
|
||||||
|
|
||||||
#endif /* __GTK_MODEL_MENU_H__ */
|
#endif /* __GTK_MODEL_MENU_H__ */
|
||||||
|
@ -22,33 +22,21 @@
|
|||||||
#include "gtkmodelmenuitem.h"
|
#include "gtkmodelmenuitem.h"
|
||||||
|
|
||||||
#include "gtkaccelmapprivate.h"
|
#include "gtkaccelmapprivate.h"
|
||||||
|
#include "gtkactionhelper.h"
|
||||||
#include "gtkmodelmenu.h"
|
#include "gtkmodelmenu.h"
|
||||||
|
|
||||||
struct _GtkModelMenuItem
|
struct _GtkModelMenuItem
|
||||||
{
|
{
|
||||||
GtkCheckMenuItem parent_instance;
|
GtkCheckMenuItem parent_instance;
|
||||||
|
GtkActionHelperRole role;
|
||||||
GActionGroup *actions;
|
|
||||||
const gchar *action_name;
|
|
||||||
gboolean has_indicator;
|
gboolean has_indicator;
|
||||||
gboolean can_activate;
|
|
||||||
GVariant *target;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GtkCheckMenuItemClass GtkModelMenuItemClass;
|
typedef GtkCheckMenuItemClass GtkModelMenuItemClass;
|
||||||
|
|
||||||
static void gtk_model_menu_item_observer_iface_init (GActionObserverInterface *iface);
|
G_DEFINE_TYPE (GtkModelMenuItem, gtk_model_menu_item, GTK_TYPE_CHECK_MENU_ITEM)
|
||||||
G_DEFINE_TYPE_WITH_CODE (GtkModelMenuItem, gtk_model_menu_item, GTK_TYPE_CHECK_MENU_ITEM,
|
|
||||||
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVER, gtk_model_menu_item_observer_iface_init))
|
|
||||||
|
|
||||||
static void
|
#define PROP_ACTION_ROLE 1
|
||||||
gtk_model_menu_item_activate (GtkMenuItem *menu_item)
|
|
||||||
{
|
|
||||||
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (menu_item);
|
|
||||||
|
|
||||||
if (item->can_activate)
|
|
||||||
g_action_group_activate_action (item->actions, item->action_name, item->target);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_model_menu_item_toggle_size_request (GtkMenuItem *menu_item,
|
gtk_model_menu_item_toggle_size_request (GtkMenuItem *menu_item,
|
||||||
@ -75,123 +63,10 @@ gtk_model_menu_item_draw_indicator (GtkCheckMenuItem *check_item,
|
|||||||
->draw_indicator (check_item, cr);
|
->draw_indicator (check_item, cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_model_menu_item_set_active (GtkModelMenuItem *item,
|
|
||||||
gboolean active)
|
|
||||||
{
|
|
||||||
GtkCheckMenuItem *checkitem = GTK_CHECK_MENU_ITEM (item);
|
|
||||||
|
|
||||||
if (gtk_check_menu_item_get_active (checkitem) != active)
|
|
||||||
{
|
|
||||||
_gtk_check_menu_item_set_active (checkitem, active);
|
|
||||||
g_object_notify (G_OBJECT (checkitem), "active");
|
|
||||||
gtk_check_menu_item_toggled (checkitem);
|
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_model_menu_item_action_added (GActionObserver *observer,
|
|
||||||
GActionObservable *observable,
|
|
||||||
const gchar *action_name,
|
|
||||||
const GVariantType *parameter_type,
|
|
||||||
gboolean enabled,
|
|
||||||
GVariant *state)
|
|
||||||
{
|
|
||||||
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (observer);
|
|
||||||
|
|
||||||
/* we can only activate the item if we have the correct type of parameter */
|
|
||||||
item->can_activate = (item->target == NULL && parameter_type == NULL) ||
|
|
||||||
(item->target != NULL && parameter_type != NULL &&
|
|
||||||
g_variant_is_of_type (item->target, parameter_type));
|
|
||||||
|
|
||||||
if (item->can_activate)
|
|
||||||
{
|
|
||||||
if (item->target != NULL && state != NULL)
|
|
||||||
{
|
|
||||||
/* actions with states and targets are radios */
|
|
||||||
gboolean selected;
|
|
||||||
|
|
||||||
selected = g_variant_equal (state, item->target);
|
|
||||||
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), TRUE);
|
|
||||||
gtk_model_menu_item_set_active (item, selected);
|
|
||||||
item->has_indicator = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (state != NULL && g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
|
|
||||||
{
|
|
||||||
/* boolean state actions without target are checks */
|
|
||||||
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), FALSE);
|
|
||||||
gtk_model_menu_item_set_active (item, g_variant_get_boolean (state));
|
|
||||||
item->has_indicator = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* stateless items are just plain actions */
|
|
||||||
gtk_model_menu_item_set_active (item, FALSE);
|
|
||||||
item->has_indicator = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (item), enabled);
|
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_model_menu_item_action_enabled_changed (GActionObserver *observer,
|
|
||||||
GActionObservable *observable,
|
|
||||||
const gchar *action_name,
|
|
||||||
gboolean enabled)
|
|
||||||
{
|
|
||||||
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (observer);
|
|
||||||
|
|
||||||
if (!item->can_activate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (item), item->can_activate && enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_model_menu_item_action_state_changed (GActionObserver *observer,
|
|
||||||
GActionObservable *observable,
|
|
||||||
const gchar *action_name,
|
|
||||||
GVariant *state)
|
|
||||||
{
|
|
||||||
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (observer);
|
|
||||||
|
|
||||||
if (!item->can_activate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (item->target)
|
|
||||||
gtk_model_menu_item_set_active (item, g_variant_equal (state, item->target));
|
|
||||||
|
|
||||||
else if (g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
|
|
||||||
gtk_model_menu_item_set_active (item, g_variant_get_boolean (state));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_model_menu_item_action_removed (GActionObserver *observer,
|
|
||||||
GActionObservable *observable,
|
|
||||||
const gchar *action_name)
|
|
||||||
{
|
|
||||||
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (observer);
|
|
||||||
|
|
||||||
if (!item->can_activate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
|
|
||||||
gtk_model_menu_item_set_active (item, FALSE);
|
|
||||||
item->has_indicator = FALSE;
|
|
||||||
|
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (item));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
||||||
GMenuModel *model,
|
GMenuModel *model,
|
||||||
gint item_index,
|
gint item_index,
|
||||||
GActionObservable *actions,
|
|
||||||
GtkAccelGroup *accels)
|
GtkAccelGroup *accels)
|
||||||
{
|
{
|
||||||
GMenuAttributeIter *iter;
|
GMenuAttributeIter *iter;
|
||||||
@ -201,7 +76,7 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
|||||||
|
|
||||||
if ((submenu = g_menu_model_get_item_link (model, item_index, "submenu")))
|
if ((submenu = g_menu_model_get_item_link (model, item_index, "submenu")))
|
||||||
{
|
{
|
||||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), gtk_model_menu_create_menu (submenu, actions, accels));
|
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), gtk_model_menu_create_menu (submenu, accels));
|
||||||
g_object_unref (submenu);
|
g_object_unref (submenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,54 +87,69 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
|
|||||||
gtk_menu_item_set_label (GTK_MENU_ITEM (item), g_variant_get_string (value, NULL));
|
gtk_menu_item_set_label (GTK_MENU_ITEM (item), g_variant_get_string (value, NULL));
|
||||||
|
|
||||||
else if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
else if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||||
item->action_name = g_variant_get_string (value, NULL);
|
gtk_actionable_set_action_name (GTK_ACTIONABLE (item), g_variant_get_string (value, NULL));
|
||||||
|
|
||||||
else if (g_str_equal (key, "target"))
|
else if (g_str_equal (key, "target"))
|
||||||
item->target = g_variant_ref (value);
|
gtk_actionable_set_action_target_value (GTK_ACTIONABLE (item), value);
|
||||||
|
|
||||||
g_variant_unref (value);
|
g_variant_unref (value);
|
||||||
}
|
}
|
||||||
g_object_unref (iter);
|
g_object_unref (iter);
|
||||||
|
|
||||||
gtk_menu_item_set_use_underline (GTK_MENU_ITEM (item), TRUE);
|
gtk_menu_item_set_use_underline (GTK_MENU_ITEM (item), TRUE);
|
||||||
|
|
||||||
if (item->action_name)
|
|
||||||
{
|
|
||||||
const GVariantType *type;
|
|
||||||
gboolean enabled;
|
|
||||||
GVariant *state;
|
|
||||||
gchar *path;
|
|
||||||
|
|
||||||
/* observer already causes us to hold a hard ref on the group */
|
|
||||||
item->actions = G_ACTION_GROUP (actions);
|
|
||||||
|
|
||||||
if (actions)
|
|
||||||
{
|
|
||||||
g_action_observable_register_observer (actions, item->action_name, G_ACTION_OBSERVER (item));
|
|
||||||
|
|
||||||
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
|
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
|
|
||||||
|
|
||||||
path = _gtk_accel_path_for_action (item->action_name, item->target);
|
|
||||||
gtk_menu_item_set_accel_path (GTK_MENU_ITEM (item), path);
|
|
||||||
g_free (path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_model_menu_item_finalize (GObject *object)
|
gtk_model_menu_item_set_has_indicator (GtkModelMenuItem *item,
|
||||||
|
gboolean has_indicator)
|
||||||
{
|
{
|
||||||
G_OBJECT_CLASS (gtk_model_menu_item_parent_class)
|
if (has_indicator == item->has_indicator)
|
||||||
->finalize (object);
|
return;
|
||||||
|
|
||||||
|
item->has_indicator = has_indicator;
|
||||||
|
|
||||||
|
gtk_widget_queue_resize (GTK_WIDGET (item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_model_menu_item_set_property (GObject *object, guint prop_id,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (object);
|
||||||
|
GtkActionHelperRole role;
|
||||||
|
AtkObject *accessible;
|
||||||
|
AtkRole a11y_role;
|
||||||
|
|
||||||
|
g_assert (prop_id == PROP_ACTION_ROLE);
|
||||||
|
|
||||||
|
role = g_value_get_uint (value);
|
||||||
|
|
||||||
|
if (role == item->role)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), role == GTK_ACTION_HELPER_ROLE_RADIO);
|
||||||
|
gtk_model_menu_item_set_has_indicator (item, role != GTK_ACTION_HELPER_ROLE_NORMAL);
|
||||||
|
|
||||||
|
accessible = gtk_widget_get_accessible (GTK_WIDGET (item));
|
||||||
|
switch (role)
|
||||||
|
{
|
||||||
|
case GTK_ACTION_HELPER_ROLE_NORMAL:
|
||||||
|
a11y_role = ATK_ROLE_MENU_ITEM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GTK_ACTION_HELPER_ROLE_TOGGLE:
|
||||||
|
a11y_role = ATK_ROLE_CHECK_MENU_ITEM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GTK_ACTION_HELPER_ROLE_RADIO:
|
||||||
|
a11y_role = ATK_ROLE_RADIO_MENU_ITEM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
atk_object_set_role (accessible, a11y_role);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -267,15 +157,6 @@ gtk_model_menu_item_init (GtkModelMenuItem *item)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_model_menu_item_observer_iface_init (GActionObserverInterface *iface)
|
|
||||||
{
|
|
||||||
iface->action_added = gtk_model_menu_item_action_added;
|
|
||||||
iface->action_enabled_changed = gtk_model_menu_item_action_enabled_changed;
|
|
||||||
iface->action_state_changed = gtk_model_menu_item_action_state_changed;
|
|
||||||
iface->action_removed = gtk_model_menu_item_action_removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_model_menu_item_class_init (GtkModelMenuItemClass *class)
|
gtk_model_menu_item_class_init (GtkModelMenuItemClass *class)
|
||||||
{
|
{
|
||||||
@ -285,23 +166,25 @@ gtk_model_menu_item_class_init (GtkModelMenuItemClass *class)
|
|||||||
|
|
||||||
check_class->draw_indicator = gtk_model_menu_item_draw_indicator;
|
check_class->draw_indicator = gtk_model_menu_item_draw_indicator;
|
||||||
|
|
||||||
item_class->activate = gtk_model_menu_item_activate;
|
|
||||||
item_class->toggle_size_request = gtk_model_menu_item_toggle_size_request;
|
item_class->toggle_size_request = gtk_model_menu_item_toggle_size_request;
|
||||||
|
|
||||||
object_class->finalize = gtk_model_menu_item_finalize;
|
object_class->set_property = gtk_model_menu_item_set_property;
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_ACTION_ROLE,
|
||||||
|
g_param_spec_uint ("action-role", "action role", "action role",
|
||||||
|
0, 2, 0, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkMenuItem *
|
GtkMenuItem *
|
||||||
gtk_model_menu_item_new (GMenuModel *model,
|
gtk_model_menu_item_new (GMenuModel *model,
|
||||||
gint item_index,
|
gint item_index,
|
||||||
GActionObservable *actions,
|
|
||||||
GtkAccelGroup *accels)
|
GtkAccelGroup *accels)
|
||||||
{
|
{
|
||||||
GtkModelMenuItem *item;
|
GtkModelMenuItem *item;
|
||||||
|
|
||||||
item = g_object_new (GTK_TYPE_MODEL_MENU_ITEM, NULL);
|
item = g_object_new (GTK_TYPE_MODEL_MENU_ITEM, NULL);
|
||||||
|
|
||||||
gtk_model_menu_item_setup (item, model, item_index, actions, accels);
|
gtk_model_menu_item_setup (item, model, item_index, accels);
|
||||||
|
|
||||||
return GTK_MENU_ITEM (item);
|
return GTK_MENU_ITEM (item);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#ifndef __GTK_MODEL_MENU_ITEM_H__
|
#ifndef __GTK_MODEL_MENU_ITEM_H__
|
||||||
#define __GTK_MODEL_MENU_ITEM_H__
|
#define __GTK_MODEL_MENU_ITEM_H__
|
||||||
|
|
||||||
#include <gtk/gactionobservable.h>
|
|
||||||
#include <gtk/gtkcheckmenuitem.h>
|
#include <gtk/gtkcheckmenuitem.h>
|
||||||
|
|
||||||
#define GTK_TYPE_MODEL_MENU_ITEM (gtk_model_menu_item_get_type ())
|
#define GTK_TYPE_MODEL_MENU_ITEM (gtk_model_menu_item_get_type ())
|
||||||
@ -37,7 +36,6 @@ GType gtk_model_menu_item_get_type (void) G
|
|||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
GtkMenuItem * gtk_model_menu_item_new (GMenuModel *model,
|
GtkMenuItem * gtk_model_menu_item_new (GMenuModel *model,
|
||||||
gint item_index,
|
gint item_index,
|
||||||
GActionObservable *actions,
|
|
||||||
GtkAccelGroup *accels);
|
GtkAccelGroup *accels);
|
||||||
|
|
||||||
#endif /* __GTK_MODEL_MENU_ITEM_H__ */
|
#endif /* __GTK_MODEL_MENU_ITEM_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user