app, libgimpwidgets: GimpAction proxy widgets will display the proper tooltip.

The tooltip contains the reason for action inactivity, if relevant. And in case
of a GtkMenuItem in particular, it will also contain the "Press F1 for more
help" text at the bottom.
This commit is contained in:
Jehan 2023-02-20 18:05:21 +01:00
parent 63e48171a4
commit 01a4feb784
7 changed files with 77 additions and 132 deletions

View File

@ -72,18 +72,18 @@ struct _GimpActionPrivate
static GimpActionPrivate *
gimp_action_get_private (GimpAction *action);
static void gimp_action_private_finalize (GimpActionPrivate *priv);
gimp_action_get_private (GimpAction *action);
static void gimp_action_private_finalize (GimpActionPrivate *priv);
static void gimp_action_label_notify (GimpAction *action,
const GParamSpec *pspec,
gpointer data);
static void gimp_action_tooltip_notify (GimpAction *action,
const GParamSpec *pspec,
gpointer data);
static void gimp_action_label_notify (GimpAction *action,
const GParamSpec *pspec,
gpointer data);
static void gimp_action_proxy_destroy (GtkWidget *proxy,
GimpAction *action);
static void gimp_action_proxy_destroy (GtkWidget *proxy,
GimpAction *action);
static void gimp_action_update_proxy_tooltip (GimpAction *action,
GtkWidget *proxy);
G_DEFINE_INTERFACE (GimpAction, gimp_action, GTK_TYPE_ACTION)
@ -133,7 +133,8 @@ gimp_action_default_init (GimpActionInterface *iface)
g_param_spec_boolean ("sensitive",
NULL, NULL,
TRUE,
GIMP_PARAM_READWRITE));
GIMP_PARAM_READWRITE |
G_PARAM_EXPLICIT_NOTIFY));
gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
g_object_interface_install_property (iface,
@ -178,9 +179,6 @@ gimp_action_init (GimpAction *action)
g_signal_connect (action, "notify::label",
G_CALLBACK (gimp_action_label_notify),
NULL);
g_signal_connect (action, "notify::tooltip",
G_CALLBACK (gimp_action_tooltip_notify),
NULL);
}
@ -216,40 +214,6 @@ gimp_action_emit_change_state (GimpAction *action,
g_variant_unref (value);
}
void
gimp_action_set_proxy_tooltip (GimpAction *action,
GtkWidget *proxy)
{
const gchar *tooltip;
const gchar *reason = NULL;
gchar *escaped_reason = NULL;
gchar *markup;
g_return_if_fail (GIMP_IS_ACTION (action));
g_return_if_fail (GTK_IS_WIDGET (proxy));
tooltip = gimp_action_get_tooltip (action);
gimp_action_get_sensitive (action, &reason);
if (reason)
escaped_reason = g_markup_escape_text (reason, -1);
markup = g_strdup_printf ("%s%s" /* Action tooltip */
"<i><span weight='light'>%s</span></i>", /* Inactive reason */
tooltip,
escaped_reason && tooltip ? "\n" : "",
escaped_reason ? escaped_reason : "");
if (tooltip || escaped_reason)
gimp_help_set_help_data_with_markup (proxy, markup,
g_object_get_qdata (G_OBJECT (proxy),
GIMP_HELP_ID));
g_free (escaped_reason);
g_free (markup);
}
const gchar *
gimp_action_get_name (GimpAction *action)
{
@ -274,6 +238,8 @@ gimp_action_set_tooltip (GimpAction *action,
const gchar *tooltip)
{
gtk_action_set_tooltip ((GtkAction *) action, tooltip);
gimp_action_update_proxy_tooltip (action, NULL);
}
const gchar *
@ -317,6 +283,7 @@ gimp_action_set_help_id (GimpAction *action,
g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
g_strdup (help_id),
(GDestroyNotify) g_free);
gimp_action_update_proxy_tooltip (action, NULL);
}
const gchar *
@ -353,13 +320,18 @@ gimp_action_set_sensitive (GimpAction *action,
{
GimpActionPrivate *priv = GET_PRIVATE (action);
g_object_set (action,
"sensitive", sensitive,
NULL);
if (priv->sensitive != sensitive || (! sensitive && reason))
{
priv->sensitive = sensitive;
g_clear_pointer (&priv->disable_reason, g_free);
if (reason && ! sensitive)
priv->disable_reason = g_strdup (reason);
g_clear_pointer (&priv->disable_reason, g_free);
if (reason && ! sensitive)
priv->disable_reason = g_strdup (reason);
g_object_notify (G_OBJECT (action), "sensitive");
gimp_action_update_proxy_tooltip (action, NULL);
}
}
gboolean
@ -711,7 +683,9 @@ gimp_action_set_property (GObject *object,
g_set_object (&priv->context, g_value_get_object (value));
break;
case GIMP_ACTION_PROP_SENSITIVE:
priv->sensitive = g_value_get_boolean (value);
gimp_action_set_sensitive (GIMP_ACTION (object),
g_value_get_boolean (value),
NULL);
break;
case GIMP_ACTION_PROP_COLOR:
g_clear_pointer (&priv->color, g_free);
@ -857,6 +831,8 @@ gimp_action_set_proxy (GimpAction *action,
g_signal_connect (proxy, "destroy",
gimp_action_proxy_destroy,
action);
gimp_action_update_proxy_tooltip (action, proxy);
}
}
@ -954,21 +930,6 @@ gimp_action_label_notify (GimpAction *action,
}
}
static void
gimp_action_tooltip_notify (GimpAction *action,
const GParamSpec *pspec,
gpointer data)
{
GSList *list;
for (list = gimp_action_get_proxies (action);
list;
list = g_slist_next (list))
{
gimp_action_set_proxy_tooltip (action, list->data);
}
}
static void
gimp_action_proxy_destroy (GtkWidget *proxy,
GimpAction *action)
@ -977,3 +938,44 @@ gimp_action_proxy_destroy (GtkWidget *proxy,
priv->proxies = g_list_remove (priv->proxies, proxy);
}
static void
gimp_action_update_proxy_tooltip (GimpAction *action,
GtkWidget *proxy)
{
GimpActionPrivate *priv;
const gchar *tooltip;
const gchar *help_id;
const gchar *reason = NULL;
gchar *escaped_reason = NULL;
gchar *markup;
g_return_if_fail (GIMP_IS_ACTION (action));
priv = GET_PRIVATE (action);
tooltip = gimp_action_get_tooltip (action);
help_id = gimp_action_get_help_id (action);
gimp_action_get_sensitive (action, &reason);
if (reason)
escaped_reason = g_markup_escape_text (reason, -1);
markup = g_strdup_printf ("%s%s" /* Action tooltip */
"<i><span weight='light'>%s</span></i>", /* Inactive reason */
tooltip,
escaped_reason && tooltip ? "\n" : "",
escaped_reason ? escaped_reason : "");
if (proxy != NULL)
{
gimp_help_set_help_data_with_markup (proxy, markup, help_id);
}
else
{
for (GList *list = priv->proxies; list; list = list->next)
gimp_help_set_help_data_with_markup (list->data, markup, help_id);
}
g_free (escaped_reason);
g_free (markup);
}

View File

@ -67,9 +67,6 @@ void gimp_action_emit_activate (GimpAction *action,
void gimp_action_emit_change_state (GimpAction *action,
GVariant *value);
void gimp_action_set_proxy_tooltip (GimpAction *action,
GtkWidget *proxy);
const gchar * gimp_action_get_name (GimpAction *action);
void gimp_action_set_label (GimpAction *action,

View File

@ -372,8 +372,6 @@ gimp_action_impl_connect_proxy (GtkAction *action,
GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
gimp_action_set_proxy (GIMP_ACTION (action), proxy);
gimp_action_set_proxy_tooltip (GIMP_ACTION (action), proxy);
}

View File

@ -110,9 +110,6 @@ static void gimp_menu_action_notify_visible (GimpAction *action,
static void gimp_menu_action_notify_label (GimpAction *action,
const GParamSpec *pspec,
GtkMenuItem *item);
static void gimp_menu_action_notify_tooltip (GimpAction *action,
const GParamSpec *pspec,
GtkWidget *item);
static GtkContainer * gimp_menu_add_submenu (GimpMenu *menu,
const gchar *label,
@ -541,15 +538,6 @@ gimp_menu_action_notify_label (GimpAction *action,
gtk_menu_item_set_label (item, gimp_action_get_label (action));
}
static void
gimp_menu_action_notify_tooltip (GimpAction *action,
const GParamSpec *pspec,
GtkWidget *item)
{
gtk_widget_set_tooltip_text (item,
gimp_action_get_tooltip (GIMP_ACTION (action)));
}
static GtkContainer *
gimp_menu_add_submenu (GimpMenu *menu,
const gchar *label,
@ -676,13 +664,6 @@ gimp_menu_add_action (GimpMenu *menu,
G_CALLBACK (gimp_menu_action_notify_sensitive),
item, 0);
if (gimp_action_get_tooltip (GIMP_ACTION (action)))
gtk_widget_set_tooltip_text (item,
gimp_action_get_tooltip (GIMP_ACTION (action)));
g_signal_connect_object (action, "notify::tooltip",
G_CALLBACK (gimp_menu_action_notify_tooltip),
item, 0);
if (placeholder)
{
gchar *key = g_strconcat (container_key, "/", placeholder, NULL);

View File

@ -80,9 +80,6 @@ static void gimp_radio_action_set_state (GimpAction *gimp_acti
static void gimp_radio_action_g_activate (GAction *action,
GVariant *parameter);
static void gimp_radio_action_connect_proxy (GtkAction *action,
GtkWidget *proxy);
static void gimp_radio_action_changed (GtkRadioAction *action,
GtkRadioAction *current);
@ -100,14 +97,11 @@ static void
gimp_radio_action_class_init (GimpRadioActionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkActionClass *action_class = GTK_ACTION_CLASS (klass);
GtkRadioActionClass *radio_class = GTK_RADIO_ACTION_CLASS (klass);
object_class->get_property = gimp_radio_action_get_property;
object_class->set_property = gimp_radio_action_set_property;
action_class->connect_proxy = gimp_radio_action_connect_proxy;
radio_class->changed = gimp_radio_action_changed;
gimp_action_install_properties (object_class);
@ -352,15 +346,6 @@ gimp_radio_action_g_activate (GAction *action,
gimp_action_history_action_activated (GIMP_ACTION (action));
}
static void
gimp_radio_action_connect_proxy (GtkAction *action,
GtkWidget *proxy)
{
GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
gimp_action_set_proxy_tooltip (GIMP_ACTION (action), proxy);
}
static void
gimp_radio_action_changed (GtkRadioAction *action,
GtkRadioAction *current)

View File

@ -75,9 +75,6 @@ static GVariant *
static void gimp_toggle_action_set_state (GimpAction *gimp_action,
GVariant *value);
static void gimp_toggle_action_connect_proxy (GtkAction *action,
GtkWidget *proxy);
static void gimp_toggle_action_toggled (GtkToggleAction *action);
static void gimp_toggle_action_g_activate (GAction *action,
@ -97,14 +94,11 @@ static void
gimp_toggle_action_class_init (GimpToggleActionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkActionClass *action_class = GTK_ACTION_CLASS (klass);
GtkToggleActionClass *toggle_class = GTK_TOGGLE_ACTION_CLASS (klass);
object_class->get_property = gimp_toggle_action_get_property;
object_class->set_property = gimp_toggle_action_set_property;
action_class->connect_proxy = gimp_toggle_action_connect_proxy;
toggle_class->toggled = gimp_toggle_action_toggled;
gimp_action_install_properties (object_class);
@ -332,15 +326,6 @@ gimp_toggle_action_set_state (GimpAction *gimp_action,
g_variant_unref (value);
}
static void
gimp_toggle_action_connect_proxy (GtkAction *action,
GtkWidget *proxy)
{
GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
gimp_action_set_proxy_tooltip (GIMP_ACTION (action), proxy);
}
static void
gimp_toggle_action_toggled (GtkToggleAction *action)
{

View File

@ -329,6 +329,11 @@ gimp_help_menu_item_set_tooltip (GtkWidget *widget,
{
g_return_if_fail (GTK_IS_MENU_ITEM (widget));
g_object_set (widget, "has-tooltip", FALSE, NULL);
g_signal_handlers_disconnect_by_func (widget,
gimp_help_menu_item_query_tooltip,
NULL);
if (tooltip && help_id)
{
g_object_set (widget, "has-tooltip", TRUE, NULL);
@ -337,14 +342,6 @@ gimp_help_menu_item_set_tooltip (GtkWidget *widget,
G_CALLBACK (gimp_help_menu_item_query_tooltip),
NULL);
}
else if (! tooltip)
{
g_object_set (widget, "has-tooltip", FALSE, NULL);
g_signal_handlers_disconnect_by_func (widget,
gimp_help_menu_item_query_tooltip,
NULL);
}
}
static gboolean