diff --git a/app/actions/gradient-editor-actions.c b/app/actions/gradient-editor-actions.c index ec0cdb56e7..984311ec47 100644 --- a/app/actions/gradient-editor-actions.c +++ b/app/actions/gradient-editor-actions.c @@ -32,6 +32,7 @@ #include "widgets/gimpactiongroup.h" #include "widgets/gimpgradienteditor.h" #include "widgets/gimphelp-ids.h" +#include "widgets/gimpradioaction.h" #include "data-editor-commands.h" #include "gradient-editor-actions.h" @@ -60,6 +61,9 @@ static const GimpActionEntry gradient_editor_actions[] = { "gradient-editor-save-right-color", GIMP_ICON_DOCUMENT_SAVE, NC_("gradient-editor-action", "Sa_ve Right Color To") }, + /* TODO GMenu: remove these 2 bogus actions once old style XML menu files are + * deleted. + */ { "gradient-editor-blending-func", NULL, "blending-function" }, { "gradient-editor-coloring-type", NULL, "coloring-type" }, @@ -577,6 +581,9 @@ gradient_editor_actions_update (GimpActionGroup *group, gimp_action_group_set_action_color (group, action, (color), (set_label)) #define SET_LABEL(action,label) \ gimp_action_group_set_action_label (group, action, (label)) +#define SET_GROUP_LABEL(action,label) \ + gimp_radio_action_set_group_label (GIMP_RADIO_ACTION (gimp_action_group_get_action (group, action)), \ + label) #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0, NULL) #define SET_VISIBLE(action,condition) \ @@ -780,10 +787,10 @@ gradient_editor_actions_update (GimpActionGroup *group, if (! selection) { - SET_LABEL ("gradient-editor-blending-func", - _("_Blending Function for Segment")); - SET_LABEL ("gradient-editor-coloring-type", - _("Coloring _Type for Segment")); + SET_GROUP_LABEL ("gradient-editor-blending-linear", + _("_Blending Function for Segment")); + SET_GROUP_LABEL ("gradient-editor-coloring-rgb", + _("Coloring _Type for Segment")); SET_LABEL ("gradient-editor-flip", _("_Flip Segment")); @@ -802,10 +809,10 @@ gradient_editor_actions_update (GimpActionGroup *group, } else { - SET_LABEL ("gradient-editor-blending-func", - _("_Blending Function for Selection")); - SET_LABEL ("gradient-editor-coloring-type", - _("Coloring _Type for Selection")); + SET_GROUP_LABEL ("gradient-editor-blending-linear", + _("_Blending Function for Selection")); + SET_GROUP_LABEL ("gradient-editor-coloring-rgb", + _("Coloring _Type for Selection")); SET_LABEL ("gradient-editor-flip", _("_Flip Selection")); diff --git a/app/widgets/gimpmenushell.c b/app/widgets/gimpmenushell.c index 7116a91c03..7ad4302f0f 100644 --- a/app/widgets/gimpmenushell.c +++ b/app/widgets/gimpmenushell.c @@ -75,6 +75,9 @@ static void gimp_menu_shell_radio_item_toggled (GtkWidget *i static void gimp_menu_shell_action_activate (GtkMenuItem *item, GimpAction *action); +static void gimp_menu_shell_notify_group_label (GimpRadioAction *action, + const GParamSpec *pspec, + GtkMenuItem *item); static void gimp_menu_shell_toggle_action_changed (GimpAction *action, GVariant *value G_GNUC_UNUSED, GtkCheckMenuItem *item); @@ -391,6 +394,15 @@ gimp_menu_shell_action_activate (GtkMenuItem *item, gimp_action_activate (action); } +static void +gimp_menu_shell_notify_group_label (GimpRadioAction *action, + const GParamSpec *pspec, + GtkMenuItem *item) +{ + gtk_menu_item_set_use_underline (item, TRUE); + gtk_menu_item_set_label (item, gimp_radio_action_get_group_label (action)); +} + static void gimp_menu_shell_toggle_action_changed (GimpAction *action, /* Unused because this is used for 2 signals @@ -509,6 +521,45 @@ gimp_menu_shell_append_model (GimpMenuShell *shell, gtk_container_add (GTK_CONTAINER (shell), item); gtk_widget_show (item); } + else if (submenu != NULL && label == NULL) + { + GApplication *app; + GAction *action; + const gchar *group_label; + GtkWidget *subcontainer; + GtkWidget *item; + + group = NULL; + + g_return_if_fail (action_name != NULL); + + app = priv->manager->gimp->app; + action = g_action_map_lookup_action (G_ACTION_MAP (app), action_name + 4); + + /* As a special case, when a submenu has no label, we expect it to + * have an action attribute, which must be for a radio action. In such + * a case, we'll use the radio actions' group label as submenu title. + * See e.g.: menus/gradient-editor-menu.ui + */ + g_return_if_fail (GIMP_IS_RADIO_ACTION (action)); + + group_label = gimp_radio_action_get_group_label (GIMP_RADIO_ACTION (action)); + + item = gtk_menu_item_new_with_mnemonic (group_label); + g_signal_connect_object (action, "notify::group-label", + G_CALLBACK (gimp_menu_shell_notify_group_label), + item, 0); + gtk_container_add (GTK_CONTAINER (shell), item); + + subcontainer = gimp_menu_new (priv->manager); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), subcontainer); + gimp_menu_shell_append_model (GIMP_MENU_SHELL (subcontainer), submenu); + gtk_widget_show (subcontainer); + + g_tree_insert (priv->submenus, + gimp_menu_shell_make_canonical_path (group_label), + subcontainer); + } else if (submenu != NULL) { GtkWidget *subcontainer; diff --git a/app/widgets/gimpradioaction.c b/app/widgets/gimpradioaction.c index 7451fced77..1dea7ae5de 100644 --- a/app/widgets/gimpradioaction.c +++ b/app/widgets/gimpradioaction.c @@ -49,17 +49,21 @@ enum PROP_0 = GIMP_ACTION_PROP_LAST, PROP_VALUE, PROP_GROUP, + PROP_GROUP_LABEL, PROP_CURRENT_VALUE }; struct _GimpRadioActionPrivate { GSList *group; + gchar *group_label; + gint value; }; static void gimp_radio_action_g_action_iface_init (GActionInterface *iface); +static void gimp_radio_action_finalize (GObject *object); static void gimp_radio_action_get_property (GObject *object, guint prop_id, GValue *value, @@ -97,6 +101,7 @@ gimp_radio_action_class_init (GimpRadioActionClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GimpToggleActionClass *toggle_class = GIMP_TOGGLE_ACTION_CLASS (klass); + object_class->finalize = gimp_radio_action_finalize; object_class->get_property = gimp_radio_action_get_property; object_class->set_property = gimp_radio_action_set_property; @@ -133,6 +138,19 @@ gimp_radio_action_class_init (GimpRadioActionClass *klass) "The radio action whose group this action belongs to.", GIMP_TYPE_RADIO_ACTION, GIMP_PARAM_WRITABLE)); + + /** + * GimpRadioAction:group-label: + * + * Sets the group label. It will be common to all actions in a same group. + */ + g_object_class_install_property (object_class, PROP_GROUP_LABEL, + g_param_spec_string ("group-label", + "Group string", + "The label for all the radio action in the group this action belongs to.", + NULL, + GIMP_PARAM_WRITABLE | + G_PARAM_EXPLICIT_NOTIFY)); /** * GimpRadioAction:value: * @@ -165,9 +183,22 @@ gimp_radio_action_init (GimpRadioAction *action) { action->priv = gimp_radio_action_get_instance_private (action); + action->priv->group = NULL; + action->priv->group_label = NULL; + gimp_action_init (GIMP_ACTION (action)); } +static void +gimp_radio_action_finalize (GObject *object) +{ + GimpRadioAction *radio = GIMP_RADIO_ACTION (object); + + g_free (radio->priv->group_label); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + static void gimp_radio_action_get_property (GObject *object, guint prop_id, @@ -185,6 +216,10 @@ gimp_radio_action_get_property (GObject *object, g_value_set_int (value, gimp_radio_action_get_current_value (action)); break; + case PROP_GROUP_LABEL: + g_value_set_string (value, + gimp_radio_action_get_group_label (action)); + break; default: gimp_action_get_property (object, prop_id, value, pspec); @@ -219,6 +254,9 @@ gimp_radio_action_set_property (GObject *object, } } break; + case PROP_GROUP_LABEL: + gimp_radio_action_set_group_label (action, g_value_get_string (value)); + break; case PROP_CURRENT_VALUE: gimp_radio_action_set_current_value (action, g_value_get_int (value)); @@ -350,11 +388,14 @@ gimp_radio_action_set_group (GimpRadioAction *action, } action->priv->group = g_slist_prepend (group, action); + g_clear_pointer (&action->priv->group_label, g_free); if (group) { GSList *slist; + action->priv->group_label = g_strdup (GIMP_RADIO_ACTION (group->data)->priv->group_label); + for (slist = action->priv->group; slist; slist = slist->next) { GimpRadioAction *tmp_action = slist->data; @@ -366,6 +407,37 @@ gimp_radio_action_set_group (GimpRadioAction *action, { gimp_toggle_action_set_active (GIMP_TOGGLE_ACTION (action), TRUE); } + + g_object_notify (G_OBJECT (action), "group-label"); +} + +void +gimp_radio_action_set_group_label (GimpRadioAction *action, + const gchar *label) +{ + GSList *slist; + + g_return_if_fail (GIMP_IS_RADIO_ACTION (action)); + + for (slist = action->priv->group; slist; slist = slist->next) + { + GimpRadioAction *tmp_action = slist->data; + + g_clear_pointer (&tmp_action->priv->group_label, g_free); + + if (label != NULL) + tmp_action->priv->group_label = g_strdup (label); + + g_object_notify (G_OBJECT (tmp_action), "group-label"); + } +} + +const gchar * +gimp_radio_action_get_group_label (GimpRadioAction *action) +{ + g_return_val_if_fail (GIMP_IS_RADIO_ACTION (action), NULL); + + return action->priv->group_label; } gint diff --git a/app/widgets/gimpradioaction.h b/app/widgets/gimpradioaction.h index 6ea4910f66..4388d7c7d5 100644 --- a/app/widgets/gimpradioaction.h +++ b/app/widgets/gimpradioaction.h @@ -50,23 +50,26 @@ struct _GimpRadioActionClass }; -GType gimp_radio_action_get_type (void) G_GNUC_CONST; +GType gimp_radio_action_get_type (void) G_GNUC_CONST; -GimpAction * gimp_radio_action_new (const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *icon_name, - const gchar *help_id, - gint value, - GimpContext *context); +GimpAction * gimp_radio_action_new (const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *icon_name, + const gchar *help_id, + gint value, + GimpContext *context); -GSList * gimp_radio_action_get_group (GimpRadioAction *action); -void gimp_radio_action_set_group (GimpRadioAction *action, - GSList *group); +GSList * gimp_radio_action_get_group (GimpRadioAction *action); +void gimp_radio_action_set_group (GimpRadioAction *action, + GSList *group); +void gimp_radio_action_set_group_label (GimpRadioAction *action, + const gchar *label); +const gchar * gimp_radio_action_get_group_label (GimpRadioAction *action); -gint gimp_radio_action_get_current_value (GimpRadioAction *action); -void gimp_radio_action_set_current_value (GimpRadioAction *action, - gint current_value); +gint gimp_radio_action_get_current_value (GimpRadioAction *action); +void gimp_radio_action_set_current_value (GimpRadioAction *action, + gint current_value); #endif /* __GIMP_RADIO_ACTION_H__ */ diff --git a/menus/gradient-editor-menu.ui b/menus/gradient-editor-menu.ui new file mode 100644 index 0000000000..bf733117d9 --- /dev/null +++ b/menus/gradient-editor-menu.ui @@ -0,0 +1,129 @@ + + + + + + Gradient Editor Menu + gimp-tool-gradient + + Left Color Type + app.gradient-editor-left-color-fixed + app.gradient-editor-left-color-foreground + app.gradient-editor-left-color-foreground-transparent + app.gradient-editor-left-color-background + app.gradient-editor-left-color-background-transparent + + app.gradient-editor-left-color + + _Load Left Color From + app.gradient-editor-load-left-left-neighbor + app.gradient-editor-load-left-right-endpoint + app.gradient-editor-load-left-fg + app.gradient-editor-load-left-bg +
+ app.gradient-editor-load-left-01 + app.gradient-editor-load-left-02 + app.gradient-editor-load-left-03 + app.gradient-editor-load-left-04 + app.gradient-editor-load-left-05 + app.gradient-editor-load-left-06 + app.gradient-editor-load-left-07 + app.gradient-editor-load-left-08 + app.gradient-editor-load-left-09 + app.gradient-editor-load-left-10 +
+
+ + _Save Left Color To + app.gradient-editor-save-left-01 + app.gradient-editor-save-left-02 + app.gradient-editor-save-left-03 + app.gradient-editor-save-left-04 + app.gradient-editor-save-left-05 + app.gradient-editor-save-left-06 + app.gradient-editor-save-left-07 + app.gradient-editor-save-left-08 + app.gradient-editor-save-left-09 + app.gradient-editor-save-left-10 + +
+ + Right Color Type + app.gradient-editor-right-color-fixed + app.gradient-editor-right-color-foreground + app.gradient-editor-right-color-foreground-transparent + app.gradient-editor-right-color-background + app.gradient-editor-right-color-background-transparent + + app.gradient-editor-right-color + + Load Right Color Fr_om + app.gradient-editor-load-right-right-neighbor + app.gradient-editor-load-right-left-endpoint + app.gradient-editor-load-right-fg + app.gradient-editor-load-right-bg +
+ app.gradient-editor-load-right-01 + app.gradient-editor-load-right-02 + app.gradient-editor-load-right-03 + app.gradient-editor-load-right-04 + app.gradient-editor-load-right-05 + app.gradient-editor-load-right-06 + app.gradient-editor-load-right-07 + app.gradient-editor-load-right-08 + app.gradient-editor-load-right-09 + app.gradient-editor-load-right-10 +
+
+ + Sa_ve Right Color To + app.gradient-editor-save-right-01 + app.gradient-editor-save-right-02 + app.gradient-editor-save-right-03 + app.gradient-editor-save-right-04 + app.gradient-editor-save-right-05 + app.gradient-editor-save-right-06 + app.gradient-editor-save-right-07 + app.gradient-editor-save-right-08 + app.gradient-editor-save-right-09 + app.gradient-editor-save-right-10 + +
+
+ + + app.gradient-editor-blending-linear + app.gradient-editor-blending-linear + app.gradient-editor-blending-curved + app.gradient-editor-blending-sine + app.gradient-editor-blending-sphere-increasing + app.gradient-editor-blending-sphere-decreasing + app.gradient-editor-blending-step + app.gradient-editor-blending-varies + + + + app.gradient-editor-coloring-rgb + app.gradient-editor-coloring-rgb + app.gradient-editor-coloring-hsv-ccw + app.gradient-editor-coloring-hsv-cw + app.gradient-editor-coloring-varies + +
+
+ app.gradient-editor-flip + app.gradient-editor-replicate + app.gradient-editor-split-midpoint + app.gradient-editor-split-uniform + app.gradient-editor-delete + app.gradient-editor-recenter + app.gradient-editor-redistribute +
+
+ app.gradient-editor-blend-color + app.gradient-editor-blend-opacity +
+ app.gradient-editor-edit-active +
+
+
diff --git a/menus/meson.build b/menus/meson.build index e8283c1e23..aba4b83cce 100644 --- a/menus/meson.build +++ b/menus/meson.build @@ -48,6 +48,7 @@ ui_menus_files = files( 'dynamics-menu.ui', 'error-console-menu.ui', 'fonts-menu.ui', + 'gradient-editor-menu.ui', 'gradients-menu.ui', 'images-menu.ui', 'layers-menu.ui',