app: use the new GEGL metadata "gimp:menu-path" and "gimp:menu-label".

Instead of unconditionally add all the non-special-cased GEGL operations into
the menu, only insert the ones which explicitly use the new "gimp:menu-path"
GEGL key.
See new operation "gegl:adaptive-threshold" added in commit 7c2a70eee for such
an example.

Note that the other operations will still get their own generated action (which
means for instance that you can still search them through the action search and
that you can create custom shortcuts for your favorite actions). But now you
won't get an overlong generic list of non-organized actions in a single submenu.
Some people were finding this messy when they had a lot of custom GEGL ops.

Also it means that GIMP doesn't assume that any custom GEGL op is usable in
GIMP. Indeed some ops are really not meant to be used as filters, which is why
we have the gimp_gegl_op_blacklisted() internal function; but this cannot apply
to custom operations. Therefore from now on, instead of GIMP guessing, operation
developers will have the say on whether their op should show in menus and in
which menu path exactly!

Moreover the "gimp:menu-label" key will be used as short label, i.e. the label
which is used in menus in particular, where the menu path is a helpful context
(hence allowing to use shorter menu labels).
The main "title" will still be used as long label, for places where there is no
such context, for instance the action search.
This commit is contained in:
Jehan 2023-06-10 22:46:07 +02:00
parent b437552580
commit 6dc5f6792e
2 changed files with 77 additions and 19 deletions

View file

@ -753,6 +753,7 @@ filters_actions_setup (GimpActionGroup *group)
gint i;
GList *op_classes;
GList *iter;
GStrvBuilder *gegl_actions;
gimp_action_group_add_string_actions (group, "filters-action",
filters_actions,
@ -775,7 +776,8 @@ filters_actions_setup (GimpActionGroup *group)
filters_actions_set_tooltips (group, filters_interactive_actions,
G_N_ELEMENTS (filters_interactive_actions));
op_classes = gimp_gegl_get_op_classes ();
gegl_actions = g_strv_builder_new ();
op_classes = gimp_gegl_get_op_classes ();
for (iter = op_classes; iter; iter = iter->next)
{
@ -826,10 +828,28 @@ filters_actions_setup (GimpActionGroup *group)
&entry, 1,
filters_apply_interactive_cmd_callback);
if (gegl_operation_class_get_key (op_class, "gimp:menu-label"))
{
GimpAction *action;
action = gimp_action_group_get_action (group, action_name);
gimp_action_set_short_label (action,
gegl_operation_class_get_key (op_class,
"gimp:menu-label"));
}
g_strv_builder_add (gegl_actions, action_name);
g_free (label);
g_free (action_name);
}
g_object_set_data_full (G_OBJECT (group),
"filters-group-generated-gegl-actions",
g_strv_builder_end (gegl_actions),
(GDestroyNotify) g_strfreev);
g_strv_builder_unref (gegl_actions);
g_list_free (op_classes);
gimp_action_group_add_enum_actions (group, "filters-action",

View file

@ -28,8 +28,9 @@
#include "core/gimp.h"
#include "core/gimp-filter-history.h"
#include "widgets/gimpactiongroup.h"
#include "widgets/gimpstringaction.h"
#include "widgets/gimpuimanager.h"
#include "widgets/gimpwidgets-utils.h"
#include "filters-menu.h"
@ -40,9 +41,9 @@ void
filters_menu_setup (GimpUIManager *manager,
const gchar *ui_path)
{
GList *op_classes;
GList *iter;
gint i;
GimpActionGroup *group;
gchar **gegl_actions;
gint i;
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (ui_path != NULL);
@ -59,24 +60,61 @@ filters_menu_setup (GimpUIManager *manager,
g_free (action_name);
}
op_classes = gimp_gegl_get_op_classes ();
group = gimp_ui_manager_get_action_group (manager, "filters");
gegl_actions = g_object_get_data (G_OBJECT (group), "filters-group-generated-gegl-actions");
for (iter = op_classes; iter; iter = iter->next)
g_return_if_fail (gegl_actions != NULL);
for (i = 0; i < g_strv_length (gegl_actions); i++)
{
GeglOperationClass *opclass = GEGL_OPERATION_CLASS (iter->data);
gchar *formatted_op_name;
gchar *action_name;
GimpAction *action;
gchar *path;
gchar *root;
const gchar *op_name;
formatted_op_name = g_strdup (opclass->name);
gimp_make_valid_action_name (formatted_op_name);
action_name = g_strdup_printf ("filters-%s", formatted_op_name);
g_free (formatted_op_name);
action = gimp_action_group_get_action (group, gegl_actions[i]);
op_name = (const gchar *) GIMP_STRING_ACTION (action)->value;
path = (gchar *) gegl_operation_get_key (op_name, "gimp:menu-path");
gimp_ui_manager_add_ui (manager, "/Filters/GEGL Operations",
action_name, NULL, FALSE);
if (path == NULL)
continue;
g_free (action_name);
path = g_strdup (path);
root = strstr (path, "/");
if (root == NULL || root == path)
{
g_printerr ("GEGL operation \"%s\" attempted to register a menu item "
"with an invalid value for key \"gimp:menu-path\": \"%s\"\n"
"Expected format is \"<MenuName>/menu/submenu.\n",
gegl_actions[i], path);
}
else
{
GList *managers;
*root = '\0';
managers = gimp_ui_managers_from_name (path);
if (managers == NULL)
{
g_printerr ("GEGL operation \"%s\" attempted to register an item in "
"the invalid menu \"%s\": use either \"<Image>\", "
"\"<Layers>\", \"<Channels>\", \"<Vectors>\", "
"\"<Colormap>\", \"<Brushes>\", \"<Dynamics>\", "
"\"<MyPaintBrushes>\", \"<Gradients>\", \"<Palettes>\", "
"\"<Patterns>\", \"<ToolPresets>\", \"<Fonts>\" "
"\"<Buffers>\" or \"<QuickMask>\".\n",
gegl_actions[i], path);
}
else
{
*root = '/';
for (GList *m = managers; m; m = m->next)
gimp_ui_manager_add_ui (m->data, root, gegl_actions[i], NULL, FALSE);
}
}
g_free (path);
}
g_list_free (op_classes);
}