app: add proxy support to GimpAction/GimpMenu.
The proxy properly shows a color area or viewable (depending on context), and this is properly updated when the associated properties are changed. The label change is also properly updated in the label part of the proxy. Very relevant actions to test the proxy items are dynamically updated are generated actions such as the "file-open-recent-*" actions (with both label and viewable updates), or again the Edit > "Fill with (FG|BG Color)|Pattern" (with color/pattern updates).
This commit is contained in:
parent
2f70d1a154
commit
69a780babb
2 changed files with 75 additions and 18 deletions
|
|
@ -56,6 +56,8 @@ typedef struct _GimpActionPrivate GimpActionPrivate;
|
|||
struct _GimpActionPrivate
|
||||
{
|
||||
GimpContext *context;
|
||||
/* This recursive pointer is needed for the finalize(). */
|
||||
GimpAction *action;
|
||||
|
||||
gboolean sensitive;
|
||||
gchar *disable_reason;
|
||||
|
|
@ -64,6 +66,8 @@ struct _GimpActionPrivate
|
|||
GimpViewable *viewable;
|
||||
PangoEllipsizeMode ellipsize;
|
||||
gint max_width_chars;
|
||||
|
||||
GList *proxies;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -78,6 +82,9 @@ static void gimp_action_tooltip_notify (GimpAction *action,
|
|||
const GParamSpec *pspec,
|
||||
gpointer data);
|
||||
|
||||
static void gimp_action_proxy_destroy (GtkWidget *proxy,
|
||||
GimpAction *action);
|
||||
|
||||
|
||||
G_DEFINE_INTERFACE (GimpAction, gimp_action, GTK_TYPE_ACTION)
|
||||
|
||||
|
|
@ -162,9 +169,11 @@ gimp_action_init (GimpAction *action)
|
|||
|
||||
priv = GET_PRIVATE (action);
|
||||
|
||||
priv->action = action;
|
||||
priv->sensitive = TRUE;
|
||||
priv->ellipsize = PANGO_ELLIPSIZE_NONE;
|
||||
priv->max_width_chars = -1;
|
||||
priv->proxies = NULL;
|
||||
|
||||
g_signal_connect (action, "notify::label",
|
||||
G_CALLBACK (gimp_action_label_notify),
|
||||
|
|
@ -524,6 +533,7 @@ gimp_action_get_display_accels (GimpAction *action)
|
|||
GSList *
|
||||
gimp_action_get_proxies (GimpAction *action)
|
||||
{
|
||||
/* TODO GAction: how exactly are these proxies set in the GtkAction API? */
|
||||
return gtk_action_get_proxies ((GtkAction *) action);
|
||||
}
|
||||
|
||||
|
|
@ -727,14 +737,15 @@ gimp_action_set_property (GObject *object,
|
|||
|
||||
if (set_proxy)
|
||||
{
|
||||
GSList *list;
|
||||
/* Set or update the proxy rendering. */
|
||||
for (GList *list = priv->proxies; list; list = list->next)
|
||||
gimp_action_set_proxy (GIMP_ACTION (object), list->data);
|
||||
|
||||
for (list = gimp_action_get_proxies (GIMP_ACTION (object));
|
||||
/* TODO GAction: remove when port complete. */
|
||||
for (GSList *list = gimp_action_get_proxies (GIMP_ACTION (object));
|
||||
list;
|
||||
list = g_slist_next (list))
|
||||
{
|
||||
gimp_action_set_proxy (GIMP_ACTION (object), list->data);
|
||||
}
|
||||
gimp_action_set_proxy (GIMP_ACTION (object), list->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -743,6 +754,7 @@ gimp_action_set_proxy (GimpAction *action,
|
|||
GtkWidget *proxy)
|
||||
{
|
||||
GimpActionPrivate *priv = GET_PRIVATE (action);
|
||||
GtkWidget *child;
|
||||
|
||||
if (! GTK_IS_MENU_ITEM (proxy))
|
||||
return;
|
||||
|
|
@ -825,20 +837,27 @@ gimp_action_set_proxy (GimpAction *action,
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
GtkWidget *child = gtk_bin_get_child (GTK_BIN (proxy));
|
||||
|
||||
if (GTK_IS_BOX (child))
|
||||
child = g_object_get_data (G_OBJECT (proxy), "gimp-menu-item-label");
|
||||
child = gtk_bin_get_child (GTK_BIN (proxy));
|
||||
|
||||
if (GTK_IS_LABEL (child))
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (child);
|
||||
if (GTK_IS_BOX (child))
|
||||
child = g_object_get_data (G_OBJECT (proxy), "gimp-menu-item-label");
|
||||
|
||||
gtk_label_set_ellipsize (label, priv->ellipsize);
|
||||
gtk_label_set_max_width_chars (label, priv->max_width_chars);
|
||||
}
|
||||
}
|
||||
if (GTK_IS_LABEL (child))
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (child);
|
||||
|
||||
gtk_label_set_ellipsize (label, priv->ellipsize);
|
||||
gtk_label_set_max_width_chars (label, priv->max_width_chars);
|
||||
}
|
||||
|
||||
if (! g_list_find (priv->proxies, proxy))
|
||||
{
|
||||
priv->proxies = g_list_prepend (priv->proxies, proxy);
|
||||
g_signal_connect (proxy, "destroy",
|
||||
gimp_action_proxy_destroy,
|
||||
action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -876,6 +895,17 @@ gimp_action_private_finalize (GimpActionPrivate *priv)
|
|||
g_clear_pointer (&priv->color, g_free);
|
||||
g_clear_object (&priv->viewable);
|
||||
|
||||
for (GList *iter = priv->proxies; iter; iter = iter->next)
|
||||
/* TODO GAction: if an action associated to a proxy menu item disappears,
|
||||
* shouldn't we also destroy the item itself (not just disconnect it)? It
|
||||
* would now point to a non-existing action.
|
||||
*/
|
||||
g_signal_handlers_disconnect_by_func (iter->data,
|
||||
gimp_action_proxy_destroy,
|
||||
priv->action);
|
||||
g_list_free (priv->proxies);
|
||||
priv->proxies = NULL;
|
||||
|
||||
g_slice_free (GimpActionPrivate, priv);
|
||||
}
|
||||
|
||||
|
|
@ -884,9 +914,26 @@ gimp_action_label_notify (GimpAction *action,
|
|||
const GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
GSList *list;
|
||||
for (GList *iter = GET_PRIVATE (action)->proxies; iter; iter = iter->next)
|
||||
{
|
||||
if (GTK_IS_MENU_ITEM (iter->data))
|
||||
{
|
||||
GtkWidget *child = gtk_bin_get_child (GTK_BIN (iter->data));
|
||||
|
||||
for (list = gimp_action_get_proxies (action);
|
||||
if (GTK_IS_BOX (child))
|
||||
{
|
||||
child = g_object_get_data (G_OBJECT (iter->data),
|
||||
"gimp-menu-item-label");
|
||||
|
||||
if (GTK_IS_LABEL (child))
|
||||
gtk_label_set_text (GTK_LABEL (child),
|
||||
gimp_action_get_label (action));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO GAction: this will have to be removed after the port is complete. */
|
||||
for (GSList *list = gimp_action_get_proxies (action);
|
||||
list;
|
||||
list = g_slist_next (list))
|
||||
{
|
||||
|
|
@ -921,3 +968,12 @@ gimp_action_tooltip_notify (GimpAction *action,
|
|||
gimp_action_set_proxy_tooltip (action, list->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_action_proxy_destroy (GtkWidget *proxy,
|
||||
GimpAction *action)
|
||||
{
|
||||
GimpActionPrivate *priv = GET_PRIVATE (action);
|
||||
|
||||
priv->proxies = g_list_remove (priv->proxies, proxy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -662,6 +662,7 @@ gimp_menu_add_action (GimpMenu *menu,
|
|||
}
|
||||
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (item), action_name);
|
||||
gimp_action_set_proxy (GIMP_ACTION (action), item);
|
||||
|
||||
g_signal_connect_object (action, "notify::label",
|
||||
G_CALLBACK (gimp_menu_action_notify_label),
|
||||
|
|
|
|||
Loading…
Reference in a new issue