app: improve layer and path selection logic.

- The "Create New Vector Layer" button is now always active, as long as
  there is an image.
- When a path is selected with no matching vector layer, the button's
  label will be "Create Vector Layer from Path", indicating that it will
  create a new vector layer from the current path.
- When selecting a path while the Path tool is active, let's update the
  selected layers to all the layers (it may be several layers!) tied to
  this path. Otherwise, this can be quite confusing, showing a path
  while another layer is selected, or worse, showing a path while the
  selected layer is a vector layer (but not tied to this path).
This commit is contained in:
Jehan 2025-10-15 20:50:45 +02:00
parent 4d7135f6f2
commit 5622708c0a
4 changed files with 82 additions and 50 deletions

View file

@ -312,8 +312,7 @@ layers_edit_vector_cmd_callback (GimpAction *action,
}
if (GIMP_IS_PATH_TOOL (active_tool))
gimp_path_tool_set_path (GIMP_PATH_TOOL (active_tool),
GIMP_VECTOR_LAYER (layer)->options->path);
gimp_path_tool_set_path (GIMP_PATH_TOOL (active_tool), GIMP_VECTOR_LAYER (layer), NULL);
}
void

View file

@ -139,7 +139,7 @@ paths_edit_cmd_callback (GimpAction *action,
}
if (GIMP_IS_PATH_TOOL (active_tool))
gimp_path_tool_set_path (GIMP_PATH_TOOL (active_tool), paths->data);
gimp_path_tool_set_path (GIMP_PATH_TOOL (active_tool), NULL, paths->data);
}
void

View file

@ -143,8 +143,7 @@ static void gimp_path_tool_to_selection_extended
(GimpPathTool *path_tool,
GdkModifierType state);
static void gimp_path_tool_create_vector_layer(GimpPathTool *path_tool,
GtkWidget *button);
static void gimp_path_tool_create_vector_layer(GimpPathTool *path_tool);
static void gimp_path_tool_vector_change_notify
(GObject *options,
const GParamSpec *pspec,
@ -247,7 +246,7 @@ gimp_path_tool_dispose (GObject *object)
{
GimpPathTool *path_tool = GIMP_PATH_TOOL (object);
gimp_path_tool_set_path (path_tool, NULL);
gimp_path_tool_set_path (path_tool, NULL, NULL);
g_clear_object (&path_tool->widget);
gimp_path_tool_image_changed (path_tool, NULL, NULL);
@ -475,7 +474,7 @@ gimp_path_tool_halt (GimpPathTool *path_tool)
if (tool->display)
gimp_tool_pop_status (tool, tool->display);
gimp_path_tool_set_path (path_tool, NULL);
gimp_path_tool_set_path (path_tool, NULL, NULL);
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tool)))
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
@ -491,19 +490,37 @@ gimp_path_tool_image_changed (GimpPathTool *path_tool,
GimpImage *image,
GimpContext *context)
{
GimpPathOptions *options = GIMP_PATH_TOOL_GET_OPTIONS (path_tool);
if (path_tool->current_image)
g_signal_handlers_disconnect_by_func (path_tool->current_image,
gimp_path_tool_image_selected_layers_changed,
NULL);
{
g_signal_handlers_disconnect_by_func (path_tool->current_image,
gimp_path_tool_image_selected_layers_changed,
NULL);
g_signal_handlers_disconnect_by_func (options->vector_layer_button,
gimp_path_tool_create_vector_layer,
path_tool);
}
g_set_weak_pointer (&path_tool->current_image, image);
if (path_tool->current_image)
g_signal_connect_object (path_tool->current_image, "selected-layers-changed",
G_CALLBACK (gimp_path_tool_image_selected_layers_changed),
path_tool, G_CONNECT_SWAPPED);
{
g_signal_connect_object (path_tool->current_image, "selected-layers-changed",
G_CALLBACK (gimp_path_tool_image_selected_layers_changed),
path_tool, G_CONNECT_SWAPPED);
g_signal_connect_object (options->vector_layer_button, "clicked",
G_CALLBACK (gimp_path_tool_create_vector_layer),
path_tool, G_CONNECT_SWAPPED);
}
gimp_path_tool_image_selected_layers_changed (path_tool);
if (options->vector_layer_button)
gtk_widget_set_sensitive (options->vector_layer_button,
path_tool->current_image ? TRUE : FALSE);
}
static void
@ -550,11 +567,11 @@ gimp_path_tool_tool_path_changed (GimpToolWidget *tool_path,
GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
gimp_image_flush (image);
gimp_path_tool_set_path (path_tool, path);
gimp_path_tool_set_path (path_tool, NULL, path);
}
else
{
gimp_path_tool_set_path (path_tool, path);
gimp_path_tool_set_path (path_tool, NULL, path);
if (path)
{
@ -624,19 +641,20 @@ gimp_path_tool_path_changed (GimpImage *image,
if (g_list_length (gimp_image_get_selected_paths (image)) == 1)
path = gimp_image_get_selected_paths (image)->data;
gimp_path_tool_set_path (path_tool, path);
gimp_path_tool_set_path (path_tool, NULL, path);
}
static void
gimp_path_tool_path_removed (GimpPath *path,
GimpPathTool *path_tool)
{
gimp_path_tool_set_path (path_tool, NULL);
gimp_path_tool_set_path (path_tool, NULL, NULL);
}
void
gimp_path_tool_set_path (GimpPathTool *path_tool,
GimpPath *path)
gimp_path_tool_set_path (GimpPathTool *path_tool,
GimpVectorLayer *layer,
GimpPath *path)
{
GimpTool *tool;
GimpItem *item = NULL;
@ -644,9 +662,12 @@ gimp_path_tool_set_path (GimpPathTool *path_tool,
g_return_if_fail (GIMP_IS_PATH_TOOL (path_tool));
g_return_if_fail (path == NULL || GIMP_IS_PATH (path));
g_return_if_fail (layer == NULL || path == NULL);
tool = GIMP_TOOL (path_tool);
options = GIMP_PATH_TOOL_GET_OPTIONS (path_tool);
tool = GIMP_TOOL (path_tool);options = GIMP_PATH_TOOL_GET_OPTIONS (path_tool);
if (layer != NULL)
path = gimp_vector_layer_get_path (layer);
if (path)
item = GIMP_ITEM (path);
@ -654,6 +675,23 @@ gimp_path_tool_set_path (GimpPathTool *path_tool,
if (path == path_tool->path)
return;
if (path_tool->current_vector_layer && path && ! layer)
{
GimpImage *image = path_tool->current_image;
GList *all_layers = gimp_image_get_layer_list (image);
GList *layers = NULL;
for (GList *iter = all_layers; iter; iter = iter->next)
{
if (gimp_item_is_vector_layer (iter->data) &&
gimp_vector_layer_get_path (iter->data) == path)
layers = g_list_prepend (layers, iter->data);
}
gimp_image_set_selected_layers (image, layers);
g_list_free (all_layers);
g_list_free (layers);
}
if (path_tool->path)
{
GimpImage *old_image;
@ -679,14 +717,6 @@ gimp_path_tool_set_path (GimpPathTool *path_tool,
gimp_path_tool_to_selection_extended,
tool);
}
if (options->vector_layer_button)
{
gtk_widget_set_sensitive (options->vector_layer_button, FALSE);
g_signal_handlers_disconnect_by_func (options->vector_layer_button,
gimp_path_tool_create_vector_layer,
tool);
}
}
if (! path ||
@ -696,6 +726,13 @@ gimp_path_tool_set_path (GimpPathTool *path_tool,
gimp_path_tool_halt (path_tool);
}
if (layer || ! path)
gtk_button_set_label (GTK_BUTTON (options->vector_layer_button),
_("Create New Vector Layer"));
else
gtk_button_set_label (GTK_BUTTON (options->vector_layer_button),
_("Create Vector Layer from Path"));
if (! path)
return;
@ -719,15 +756,6 @@ gimp_path_tool_set_path (GimpPathTool *path_tool,
gtk_widget_set_sensitive (options->to_selection_button, TRUE);
}
if (options->vector_layer_button)
{
g_signal_connect_swapped (options->vector_layer_button, "clicked",
G_CALLBACK (gimp_path_tool_create_vector_layer),
tool);
gtk_widget_set_sensitive (options->vector_layer_button, TRUE);
}
if (tool->display)
{
gimp_tool_path_set_path (GIMP_TOOL_PATH (path_tool->widget), path);
@ -793,29 +821,30 @@ gimp_path_tool_to_selection_extended (GimpPathTool *path_tool,
}
static void
gimp_path_tool_create_vector_layer (GimpPathTool *path_tool,
GtkWidget *button)
gimp_path_tool_create_vector_layer (GimpPathTool *path_tool)
{
GimpImage *image;
GimpVectorLayer *layer;
GimpPathOptions *options = GIMP_PATH_TOOL_GET_OPTIONS (path_tool);
if (! path_tool->path)
if (! path_tool->current_image)
return;
image = gimp_item_get_image (GIMP_ITEM (path_tool->path));
image = path_tool->current_image;
g_signal_handlers_block_by_func (image,
gimp_path_tool_image_selected_layers_changed,
path_tool);
/* If there's already an active vector layer, create a new blank path */
if (path_tool->current_vector_layer)
/* If there's already an active vector layer, or no paths are
* selected, create a new blank path.
*/
if (path_tool->current_vector_layer || ! path_tool->path)
{
GimpPath *new_path = gimp_path_new (image, _("Vector Layer"));
gimp_image_add_path (image, new_path, GIMP_IMAGE_ACTIVE_PARENT, -1,
TRUE);
gimp_image_add_path (image, new_path, GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
gimp_path_tool_set_path (path_tool, NULL, new_path);
g_signal_handlers_disconnect_by_func (options,
gimp_path_tool_vector_change_notify,
@ -953,8 +982,7 @@ gimp_path_tool_set_layer (GimpPathTool *path_tool,
}
path_tool->current_vector_layer = vector_layer;
gimp_path_tool_set_path (path_tool,
vector_layer ? gimp_vector_layer_get_path (vector_layer) : NULL);
gimp_path_tool_set_path (path_tool, vector_layer, NULL);
if (vector_layer)
{
@ -984,6 +1012,10 @@ gimp_path_tool_set_layer (GimpPathTool *path_tool,
G_CALLBACK (gimp_path_tool_layer_rasterized),
path_tool, 0);
}
if (vector_layer)
gtk_button_set_label (GTK_BUTTON (options->vector_layer_button),
_("Create New Vector Layer"));
}
static void
@ -1073,8 +1105,8 @@ gimp_path_tool_confirm_response (GimpViewableDialog *dialog,
path = GIMP_PATH (gimp_item_duplicate (GIMP_ITEM (path),
G_TYPE_FROM_INSTANCE (path)));
gimp_image_add_path (image, path, GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
gimp_path_tool_set_path (path_tool, path);
gimp_path_tool_create_vector_layer (path_tool, NULL);
gimp_path_tool_set_path (path_tool, NULL, path);
gimp_path_tool_create_vector_layer (path_tool);
break;
case GTK_RESPONSE_ACCEPT:

View file

@ -64,4 +64,5 @@ void gimp_path_tool_register (GimpToolRegisterCallback callback,
GType gimp_path_tool_get_type (void) G_GNUC_CONST;
void gimp_path_tool_set_path (GimpPathTool *path_tool,
GimpVectorLayer *layer,
GimpPath *path);