[gimp] app: allowing to "Lock position" on layer groups.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: allowing to "Lock position" on layer groups.
- Date: Tue, 15 Feb 2022 21:08:36 +0000 (UTC)
commit ed5934440603e4c46777208dea847b84c2f25c1f
Author: Jehan <jehan girinstud io>
Date: Tue Feb 15 18:30:53 2022 +0100
app: allowing to "Lock position" on layer groups.
Since we are now allowed to move groups (which is the same thing as
multi-selecting all its children and moving them), it makes no sense
that this lock is disabled.
This works the same way as "Lock pixels" in that a locked grouped also
forbid moving children. And there was already some logics so that you
can't move a layer group if one of it's children is locked. So this lock
really works both ways and is a bit special.
Finally I cleaned up a bit the multi-layer selection logics and
messaging, as well as which lock to blink (similar to the previous
commit) for the "Lock position" case.
app/actions/drawable-actions.c | 2 +-
app/actions/layers-actions.c | 2 +-
app/core/gimpgrouplayer.c | 51 ++++++++++++++++++++++++++++++---------
app/core/gimpitem.c | 43 ++++++++++++++++++++++++---------
app/core/gimpitem.h | 7 ++++--
app/core/gimplayermask.c | 10 +++++---
app/display/gimptoolpath.c | 4 +--
app/pdb/gimppdb-utils.c | 2 +-
app/tools/gimpeditselectiontool.c | 22 ++++++++++-------
app/tools/gimpmovetool.c | 40 +++++++++++++-----------------
app/tools/gimptransformtool.c | 10 ++++----
11 files changed, 122 insertions(+), 71 deletions(-)
---
diff --git a/app/actions/drawable-actions.c b/app/actions/drawable-actions.c
index a549fa2df2..8f1adbd097 100644
--- a/app/actions/drawable-actions.c
+++ b/app/actions/drawable-actions.c
@@ -197,7 +197,7 @@ drawable_actions_update (GimpActionGroup *group,
writable = ! gimp_item_is_content_locked (item, NULL);
locked_pos = gimp_item_get_lock_position (item);
can_lock_pos = gimp_item_can_lock_position (item);
- movable = ! gimp_item_is_position_locked (item);
+ movable = ! gimp_item_is_position_locked (item, NULL);
if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
children = TRUE;
diff --git a/app/actions/layers-actions.c b/app/actions/layers-actions.c
index b6f0fe6394..1a70a1a3b8 100644
--- a/app/actions/layers-actions.c
+++ b/app/actions/layers-actions.c
@@ -841,7 +841,7 @@ layers_actions_update (GimpActionGroup *group,
else
all_writable = FALSE;
- if (gimp_item_is_position_locked (GIMP_ITEM (iter->data)))
+ if (gimp_item_is_position_locked (GIMP_ITEM (iter->data), NULL))
all_movable = FALSE;
if (gimp_layer_can_lock_alpha (iter->data))
diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c
index 202c46388c..9b2e447389 100644
--- a/app/core/gimpgrouplayer.c
+++ b/app/core/gimpgrouplayer.c
@@ -102,7 +102,9 @@ static gboolean gimp_group_layer_get_expanded (GimpViewable *viewable)
static void gimp_group_layer_set_expanded (GimpViewable *viewable,
gboolean expanded);
-static gboolean gimp_group_layer_is_position_locked (GimpItem *item);
+static gboolean gimp_group_layer_is_position_locked (GimpItem *item,
+ GimpItem **locked_item,
+ gboolean check_children);
static GimpItem * gimp_group_layer_duplicate (GimpItem *item,
GType new_type);
static void gimp_group_layer_convert (GimpItem *item,
@@ -517,22 +519,47 @@ gimp_group_layer_set_expanded (GimpViewable *viewable,
}
static gboolean
-gimp_group_layer_is_position_locked (GimpItem *item)
+gimp_group_layer_is_position_locked (GimpItem *item,
+ GimpItem **locked_item,
+ gboolean check_children)
{
- GimpGroupLayerPrivate *private = GET_PRIVATE (item);
- GList *list;
-
- for (list = gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (private->children));
- list;
- list = g_list_next (list))
+ /* Lock position is particular because a locked child locks the group
+ * too.
+ */
+ if (check_children)
{
- GimpItem *child = list->data;
+ GimpGroupLayerPrivate *private = GET_PRIVATE (item);
+ GList *list;
- if (gimp_item_is_position_locked (child))
- return TRUE;
+ for (list = gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (private->children));
+ list;
+ list = g_list_next (list))
+ {
+ GimpItem *child = list->data;
+
+ if (gimp_item_get_lock_position (child))
+ {
+ if (locked_item)
+ *locked_item = child;
+
+ return TRUE;
+ }
+ else if (GIMP_IS_GROUP_LAYER (child) &&
+ gimp_group_layer_is_position_locked (child,
+ locked_item,
+ TRUE))
+ {
+ return TRUE;
+ }
+ }
}
- return GIMP_ITEM_CLASS (parent_class)->is_position_locked (item);
+ /* And a locked parent locks the group too! Which is handled by parent
+ * implementation of the method.
+ */
+ return GIMP_ITEM_CLASS (parent_class)->is_position_locked (item,
+ locked_item,
+ FALSE);
}
static GimpItem *
diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c
index cf117f694a..6918d3cb54 100644
--- a/app/core/gimpitem.c
+++ b/app/core/gimpitem.c
@@ -127,7 +127,9 @@ static gint64 gimp_item_get_memsize (GimpObject *object,
static gboolean gimp_item_real_is_content_locked (GimpItem *item,
GimpItem **locked_item);
-static gboolean gimp_item_real_is_position_locked (GimpItem *item);
+static gboolean gimp_item_real_is_position_locked (GimpItem *item,
+ GimpItem **locked_item,
+ gboolean check_children);
static gboolean gimp_item_real_is_visibility_locked (GimpItem *item);
static gboolean gimp_item_real_bounds (GimpItem *item,
gdouble *x,
@@ -477,18 +479,37 @@ gimp_item_real_is_content_locked (GimpItem *item,
{
GimpItem *parent = gimp_item_get_parent (item);
- if (parent && gimp_item_is_content_locked (parent, locked_item))
- return TRUE;
-
- if (GET_PRIVATE (item)->lock_content && locked_item)
- *locked_item = item;
+ if (GET_PRIVATE (item)->lock_content)
+ {
+ if (locked_item)
+ *locked_item = item;
+ }
+ else if (parent && gimp_item_is_content_locked (parent, locked_item))
+ {
+ return TRUE;
+ }
return GET_PRIVATE (item)->lock_content;
}
static gboolean
-gimp_item_real_is_position_locked (GimpItem *item)
+gimp_item_real_is_position_locked (GimpItem *item,
+ GimpItem **locked_item,
+ gboolean check_children)
{
+ GimpItem *parent = gimp_item_get_parent (item);
+
+ if (GET_PRIVATE (item)->lock_position)
+ {
+ if (locked_item)
+ *locked_item = item;
+ }
+ else if (parent &&
+ GIMP_ITEM_GET_CLASS (item)->is_position_locked (parent, locked_item, FALSE))
+ {
+ return TRUE;
+ }
+
return GET_PRIVATE (item)->lock_position;
}
@@ -2514,18 +2535,16 @@ gimp_item_can_lock_position (GimpItem *item)
{
g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
- if (gimp_viewable_get_children (GIMP_VIEWABLE (item)))
- return FALSE;
-
return TRUE;
}
gboolean
-gimp_item_is_position_locked (GimpItem *item)
+gimp_item_is_position_locked (GimpItem *item,
+ GimpItem **locked_item)
{
g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
- return GIMP_ITEM_GET_CLASS (item)->is_position_locked (item);
+ return GIMP_ITEM_GET_CLASS (item)->is_position_locked (item, locked_item, TRUE);
}
void
diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h
index 0444023a55..ef66e14893 100644
--- a/app/core/gimpitem.h
+++ b/app/core/gimpitem.h
@@ -54,7 +54,9 @@ struct _GimpItemClass
gboolean (* is_attached) (GimpItem *item);
gboolean (* is_content_locked) (GimpItem *item,
GimpItem **locked_item);
- gboolean (* is_position_locked) (GimpItem *item);
+ gboolean (* is_position_locked) (GimpItem *item,
+ GimpItem **locked_item,
+ gboolean checking_children);
gboolean (* is_visibility_locked) (GimpItem *item);
GimpItemTree * (* get_tree) (GimpItem *item);
gboolean (* bounds) (GimpItem *item,
@@ -382,7 +384,8 @@ void gimp_item_set_lock_position (GimpItem *item,
gboolean push_undo);
gboolean gimp_item_get_lock_position (GimpItem *item);
gboolean gimp_item_can_lock_position (GimpItem *item);
-gboolean gimp_item_is_position_locked (GimpItem *item);
+gboolean gimp_item_is_position_locked (GimpItem *item,
+ GimpItem **locked_item);
void gimp_item_set_lock_visibility (GimpItem *item,
gboolean lock_visibility,
diff --git a/app/core/gimplayermask.c b/app/core/gimplayermask.c
index 2660a29113..4d2879f3e1 100644
--- a/app/core/gimplayermask.c
+++ b/app/core/gimplayermask.c
@@ -38,7 +38,9 @@ static void gimp_layer_mask_preview_thaw (GimpViewable *
static gboolean gimp_layer_mask_is_attached (GimpItem *item);
static gboolean gimp_layer_mask_is_content_locked (GimpItem *item,
GimpItem **locked_item);
-static gboolean gimp_layer_mask_is_position_locked (GimpItem *item);
+static gboolean gimp_layer_mask_is_position_locked (GimpItem *item,
+ GimpItem **locked_item,
+ gboolean check_children);
static GimpItemTree * gimp_layer_mask_get_tree (GimpItem *item);
static GimpItem * gimp_layer_mask_duplicate (GimpItem *item,
GType new_type);
@@ -145,13 +147,15 @@ gimp_layer_mask_is_content_locked (GimpItem *item,
}
static gboolean
-gimp_layer_mask_is_position_locked (GimpItem *item)
+gimp_layer_mask_is_position_locked (GimpItem *item,
+ GimpItem **locked_item,
+ gboolean check_children)
{
GimpLayerMask *mask = GIMP_LAYER_MASK (item);
GimpLayer *layer = gimp_layer_mask_get_layer (mask);
if (layer)
- return gimp_item_is_position_locked (GIMP_ITEM (layer));
+ return gimp_item_is_position_locked (GIMP_ITEM (layer), locked_item);
return FALSE;
}
diff --git a/app/display/gimptoolpath.c b/app/display/gimptoolpath.c
index ca8f06b735..cf2444aaf2 100644
--- a/app/display/gimptoolpath.c
+++ b/app/display/gimptoolpath.c
@@ -544,10 +544,10 @@ gimp_tool_path_check_writable (GimpToolPath *path)
GimpItem *locked_item = NULL;
if (gimp_item_is_content_locked (GIMP_ITEM (private->vectors), &locked_item) ||
- gimp_item_is_position_locked (GIMP_ITEM (private->vectors)))
+ gimp_item_is_position_locked (GIMP_ITEM (private->vectors), &locked_item))
{
gimp_tool_widget_message_literal (GIMP_TOOL_WIDGET (path),
- _("The active path is locked."));
+ _("The selected path is locked."));
if (locked_item == NULL)
locked_item = GIMP_ITEM (private->vectors);
diff --git a/app/pdb/gimppdb-utils.c b/app/pdb/gimppdb-utils.c
index 49b9482b37..dbd4e42b48 100644
--- a/app/pdb/gimppdb-utils.c
+++ b/app/pdb/gimppdb-utils.c
@@ -594,7 +594,7 @@ gimp_pdb_item_is_modifiable (GimpItem *item,
return FALSE;
}
- if ((modify & GIMP_PDB_ITEM_POSITION) && gimp_item_is_position_locked (item))
+ if ((modify & GIMP_PDB_ITEM_POSITION) && gimp_item_is_position_locked (item, NULL))
{
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
_("Item '%s' (%d) cannot be modified because its "
diff --git a/app/tools/gimpeditselectiontool.c b/app/tools/gimpeditselectiontool.c
index e1c09caf79..c0cef46ff9 100644
--- a/app/tools/gimpeditselectiontool.c
+++ b/app/tools/gimpeditselectiontool.c
@@ -1062,7 +1062,8 @@ gimp_edit_selection_tool_translate (GimpTool *tool,
/* cannot happen, don't translate this message */
null_message = "There is no selection to move.";
}
- else if (gimp_item_is_position_locked (active_item))
+ else if (gimp_item_is_position_locked (active_item,
+ &locked_item))
{
/* cannot happen, don't translate this message */
locked_message = "The selection's position is locked.";
@@ -1079,9 +1080,10 @@ gimp_edit_selection_tool_translate (GimpTool *tool,
{
null_message = _("There is no path to move.");
}
- else if (gimp_item_is_position_locked (active_item))
+ else if (gimp_item_is_position_locked (active_item,
+ &locked_item))
{
- locked_message = _("The active path's position is locked.");
+ locked_message = _("The selected path's position is locked.");
}
break;
@@ -1098,9 +1100,10 @@ gimp_edit_selection_tool_translate (GimpTool *tool,
{
edit_mode = GIMP_TRANSLATE_MODE_LAYER_MASK;
- if (gimp_item_is_position_locked (selected_items->data))
+ if (gimp_item_is_position_locked (selected_items->data,
+ &locked_item))
{
- locked_message = _("The active layer's position is locked.");
+ locked_message = _("The selected layer's position is locked.");
}
else if (gimp_item_is_content_locked (selected_items->data,
&locked_item))
@@ -1115,7 +1118,7 @@ gimp_edit_selection_tool_translate (GimpTool *tool,
edit_mode = GIMP_TRANSLATE_MODE_CHANNEL;
for (iter = selected_items; iter; iter = iter->next)
- if (! gimp_item_is_position_locked (iter->data) &&
+ if (! gimp_item_is_position_locked (iter->data, NULL) &&
! gimp_item_is_content_locked (iter->data, NULL))
n_items++;
@@ -1126,9 +1129,10 @@ gimp_edit_selection_tool_translate (GimpTool *tool,
{
edit_mode = GIMP_TRANSLATE_MODE_FLOATING_SEL;
- if (gimp_item_is_position_locked (selected_items->data))
+ if (gimp_item_is_position_locked (selected_items->data,
+ &locked_item))
{
- locked_message = _("The active layer's position is locked.");
+ locked_message = _("The selected layer's position is locked.");
}
}
else
@@ -1138,7 +1142,7 @@ gimp_edit_selection_tool_translate (GimpTool *tool,
edit_mode = GIMP_TRANSLATE_MODE_LAYER;
for (iter = selected_items; iter; iter = iter->next)
- if (! gimp_item_is_position_locked (iter->data))
+ if (! gimp_item_is_position_locked (iter->data, NULL))
n_items++;
if (n_items == 0)
diff --git a/app/tools/gimpmovetool.c b/app/tools/gimpmovetool.c
index cb2b499576..71a16c35a9 100644
--- a/app/tools/gimpmovetool.c
+++ b/app/tools/gimpmovetool.c
@@ -189,6 +189,7 @@ gimp_move_tool_button_press (GimpTool *tool,
GimpTranslateMode translate_mode = GIMP_TRANSLATE_MODE_MASK;
const gchar *null_message = NULL;
const gchar *locked_message = NULL;
+ GimpItem *locked_item = NULL;
tool->display = display;
@@ -297,7 +298,7 @@ gimp_move_tool_button_press (GimpTool *tool,
for (iter = selected_items; iter; iter = iter->next)
{
- if (! gimp_item_is_position_locked (iter->data))
+ if (! gimp_item_is_position_locked (iter->data, &locked_item))
n_items++;
}
@@ -321,7 +322,7 @@ gimp_move_tool_button_press (GimpTool *tool,
/* cannot happen, don't translate this message */
null_message = "There is no selection to move.";
}
- else if (gimp_item_is_position_locked (active_item))
+ else if (gimp_item_is_position_locked (active_item, &locked_item))
{
locked_message = "The selection's position is locked.";
}
@@ -342,37 +343,27 @@ gimp_move_tool_button_press (GimpTool *tool,
translate_mode = GIMP_TRANSLATE_MODE_LAYER_MASK;
- if (gimp_item_is_position_locked (selected_items->data))
+ if (gimp_item_is_position_locked (selected_items->data, &locked_item))
locked_message = _("The selected layer's position is locked.");
else if (gimp_item_is_content_locked (selected_items->data, NULL))
locked_message = _("The selected layer's pixels are locked.");
}
else if (GIMP_IS_CHANNEL (selected_items->data))
{
- gint n_items = 0;
-
translate_mode = GIMP_TRANSLATE_MODE_CHANNEL;
for (iter = selected_items; iter; iter = iter->next)
- if (! gimp_item_is_position_locked (iter->data) &&
- ! gimp_item_is_content_locked (iter->data, NULL))
- n_items++;
-
- if (n_items == 0)
- locked_message = _("All selected channels' positions or pixels are locked.");
+ if (gimp_item_is_position_locked (iter->data, &locked_item) ||
+ gimp_item_is_content_locked (iter->data, &locked_item))
+ locked_message = _("A selected channel's position or pixels are locked.");
}
else
{
- gint n_items = 0;
-
translate_mode = GIMP_TRANSLATE_MODE_LAYER;
for (iter = selected_items; iter; iter = iter->next)
- if (! gimp_item_is_position_locked (iter->data))
- n_items++;
-
- if (n_items == 0)
- locked_message = _("All selected layers' positions are locked.");
+ if (gimp_item_is_position_locked (iter->data, &locked_item))
+ locked_message = _("A selected layers' position is locked.");
}
}
break;
@@ -391,8 +382,11 @@ gimp_move_tool_button_press (GimpTool *tool,
else if (locked_message)
{
gimp_tool_message_literal (tool, display, locked_message);
- gimp_tools_blink_lock_box (display->gimp,
- active_item ? active_item : selected_items->data);
+
+ if (locked_item == NULL)
+ locked_item = active_item ? active_item : selected_items->data;
+
+ gimp_tools_blink_lock_box (display->gimp, locked_item);
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
g_list_free (selected_items);
return;
@@ -603,7 +597,7 @@ gimp_move_tool_cursor_update (GimpTool *tool,
for (iter = selected; iter; iter = iter->next)
{
- if (! gimp_item_is_position_locked (iter->data))
+ if (! gimp_item_is_position_locked (iter->data, NULL))
n_items++;
}
@@ -640,7 +634,7 @@ gimp_move_tool_cursor_update (GimpTool *tool,
gint n_items = 0;
for (iter = items; iter; iter = iter->next)
- if (! gimp_item_is_position_locked (iter->data))
+ if (! gimp_item_is_position_locked (iter->data, NULL))
n_items++;
if (n_items == 0)
modifier = GIMP_CURSOR_MODIFIER_BAD;
@@ -670,7 +664,7 @@ gimp_move_tool_cursor_update (GimpTool *tool,
tool_cursor = GIMP_TOOL_CURSOR_MOVE;
modifier = GIMP_CURSOR_MODIFIER_ANCHOR;
}
- else if (gimp_item_is_position_locked (GIMP_ITEM (layer)))
+ else if (gimp_item_is_position_locked (GIMP_ITEM (layer), NULL))
{
modifier = GIMP_CURSOR_MODIFIER_BAD;
}
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index 1f39aca065..1eee63db19 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -680,7 +680,7 @@ gimp_transform_tool_check_selected_objects (GimpTransformTool *tr_tool,
if (gimp_item_is_content_locked (item, &locked_item))
locked_message = _("A selected layer's pixels are locked.");
- else if (gimp_item_is_position_locked (item))
+ else if (gimp_item_is_position_locked (item, &locked_item))
locked_message = _("A selected layer's position and size are locked.");
if (! gimp_item_is_visible (item) &&
@@ -711,7 +711,7 @@ gimp_transform_tool_check_selected_objects (GimpTransformTool *tr_tool,
/* cannot happen, so don't translate these messages */
if (gimp_item_is_content_locked (item, &locked_item))
locked_message = "The selection's pixels are locked.";
- else if (gimp_item_is_position_locked (item))
+ else if (gimp_item_is_position_locked (item, &locked_item))
locked_message = "The selection's position and size are locked.";
}
break;
@@ -725,10 +725,10 @@ gimp_transform_tool_check_selected_objects (GimpTransformTool *tr_tool,
if (gimp_item_is_content_locked (item, &locked_item))
locked_message = _("The selected path's strokes are locked.");
- else if (gimp_item_is_position_locked (item))
- locked_message = _("The active path's position is locked.");
+ else if (gimp_item_is_position_locked (item, &locked_item))
+ locked_message = _("The selected path's position is locked.");
else if (! gimp_vectors_get_n_strokes (GIMP_VECTORS (item)))
- locked_message = _("The active path has no strokes.");
+ locked_message = _("The selected path has no strokes.");
}
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]