[gimp/wip/Jehan/layers-dockable-refresh: 16/58] app: implement exclusive lock switching (Shift-click).
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/Jehan/layers-dockable-refresh: 16/58] app: implement exclusive lock switching (Shift-click).
- Date: Fri, 22 Oct 2021 21:36:49 +0000 (UTC)
commit 1e01df008f0d40b7a5798ac880597599cdc41f13
Author: Jehan <jehan girinstud io>
Date: Thu Feb 11 16:17:36 2021 +0100
app: implement exclusive lock switching (Shift-click).
Similar to exclusive visibility switch on layers, now for locks too, if
one wants to lock all layers within a same level for instance by
Shift-clicking the lock icon.
Also once again I factorized the exclusive switching code to ensure it
will always works the same for all similar features (visibility and all
locks).
app/core/gimpitem-exclusive.c | 102 +++++++++++++++++++++++++---------------
app/core/gimpitem-exclusive.h | 26 ++++++++--
app/widgets/gimpitemtreeview.c | 84 ++++++++++++++++++++++++++-------
app/widgets/gimpitemtreeview.h | 5 ++
app/widgets/gimplayertreeview.c | 7 ++-
5 files changed, 165 insertions(+), 59 deletions(-)
---
diff --git a/app/core/gimpitem-exclusive.c b/app/core/gimpitem-exclusive.c
index 6b07c268f3..7f62bfac81 100644
--- a/app/core/gimpitem-exclusive.c
+++ b/app/core/gimpitem-exclusive.c
@@ -37,11 +37,13 @@
#include "gimp-intl.h"
-static GList * gimp_item_exclusive_get_ancestry (GimpItem *item);
-static void gimp_item_exclusive_get_lists (GimpItem *item,
- const gchar *property,
- GList **on,
- GList **off);
+static GList * gimp_item_exclusive_get_ancestry (GimpItem *item);
+static void gimp_item_exclusive_get_lists (GimpItem *item,
+ GimpItemIsEnabledFunc is_enabled,
+ GimpItemCanSetFunc can_set,
+ GimpItemIsPropLocked is_prop_locked,
+ GList **on,
+ GList **off);
/* public functions */
@@ -50,73 +52,99 @@ void
gimp_item_toggle_exclusive_visible (GimpItem *item,
GimpContext *context)
{
- GList *ancestry;
- GList *on;
- GList *off;
- GList *list;
+ gimp_item_toggle_exclusive (item,
+ (GimpItemIsEnabledFunc) gimp_item_is_visible,
+ (GimpItemSetFunc) gimp_item_set_visible,
+ NULL,
+ (GimpItemIsPropLocked) gimp_item_is_visibility_locked,
+ (GimpItemUndoPush) gimp_image_undo_push_item_visibility,
+ _("Set Item Exclusive Visibility"),
+ GIMP_UNDO_GROUP_ITEM_VISIBILITY,
+ context);
+}
+
+void
+gimp_item_toggle_exclusive (GimpItem *item,
+ GimpItemIsEnabledFunc is_enabled,
+ GimpItemSetFunc set_prop,
+ GimpItemCanSetFunc can_set,
+ GimpItemIsPropLocked is_prop_locked,
+ GimpItemUndoPush undo_push,
+ const gchar *undo_desc,
+ GimpUndoType group_undo_type,
+ GimpContext *context)
+{
+ GList *ancestry;
+ GList *on;
+ GList *off;
+ GList *list;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (gimp_item_is_attached (item));
- g_return_if_fail (GIMP_IS_CONTEXT (context));
+ g_return_if_fail (undo_desc != NULL);
+ g_return_if_fail (context == NULL || GIMP_IS_CONTEXT (context));
ancestry = gimp_item_exclusive_get_ancestry (item);
- gimp_item_exclusive_get_lists (item, "visible", &on, &off);
+ gimp_item_exclusive_get_lists (item, is_enabled, can_set, is_prop_locked, &on, &off);
- if (on || off || ! gimp_item_is_visible (item))
+ if (on || off || (! is_enabled (item) && (can_set == NULL || can_set (item))))
{
GimpImage *image = gimp_item_get_image (item);
GimpUndo *undo;
gboolean push_undo = TRUE;
undo = gimp_image_undo_can_compress (image, GIMP_TYPE_UNDO_STACK,
- GIMP_UNDO_GROUP_ITEM_VISIBILITY);
+ group_undo_type);
- if (undo && (g_object_get_data (G_OBJECT (undo), "exclusive-visible-item") ==
+ /* Use the undo description as the undo object key, as we should
+ * assume that a same undo description means the same exclusive
+ * action.
+ */
+ if (undo && (g_object_get_data (G_OBJECT (undo), undo_desc) ==
(gpointer) item))
push_undo = FALSE;
if (push_undo)
{
if (gimp_image_undo_group_start (image,
- GIMP_UNDO_GROUP_ITEM_VISIBILITY,
- _("Set Item Exclusive Visible")))
+ group_undo_type,
+ undo_desc))
{
undo = gimp_image_undo_can_compress (image, GIMP_TYPE_UNDO_STACK,
- GIMP_UNDO_GROUP_ITEM_VISIBILITY);
+ group_undo_type);
if (undo)
- g_object_set_data (G_OBJECT (undo), "exclusive-visible-item",
- (gpointer) item);
+ g_object_set_data (G_OBJECT (undo), undo_desc, (gpointer) item);
}
for (list = ancestry; list; list = g_list_next (list))
- gimp_image_undo_push_item_visibility (image, NULL, list->data);
+ undo_push (image, NULL, list->data);
for (list = on; list; list = g_list_next (list))
- gimp_image_undo_push_item_visibility (image, NULL, list->data);
+ undo_push (image, NULL, list->data);
for (list = off; list; list = g_list_next (list))
- gimp_image_undo_push_item_visibility (image, NULL, list->data);
+ undo_push (image, NULL, list->data);
gimp_image_undo_group_end (image);
}
- else
+ else if (context)
{
gimp_undo_refresh_preview (undo, context);
}
for (list = ancestry; list; list = g_list_next (list))
- gimp_item_set_visible (list->data, TRUE, FALSE);
+ set_prop (list->data, TRUE, FALSE);
if (on)
{
for (list = on; list; list = g_list_next (list))
- gimp_item_set_visible (list->data, FALSE, FALSE);
+ set_prop (list->data, FALSE, FALSE);
}
else if (off)
{
for (list = off; list; list = g_list_next (list))
- gimp_item_set_visible (list->data, TRUE, FALSE);
+ set_prop (list->data, TRUE, FALSE);
}
g_list_free (on);
@@ -233,10 +261,12 @@ gimp_item_exclusive_get_ancestry (GimpItem *item)
}
static void
-gimp_item_exclusive_get_lists (GimpItem *item,
- const gchar *property,
- GList **on,
- GList **off)
+gimp_item_exclusive_get_lists (GimpItem *item,
+ GimpItemIsEnabledFunc is_enabled,
+ GimpItemCanSetFunc can_set,
+ GimpItemIsPropLocked is_prop_locked,
+ GList **on,
+ GList **off)
{
GimpItemTree *tree;
GList *items;
@@ -253,18 +283,16 @@ gimp_item_exclusive_get_lists (GimpItem *item,
{
GimpItem *other = list->data;
- if (other != item &&
+ if (other != item &&
/* Don't include item with visibility locks. */
- ! gimp_item_is_visibility_locked (other) &&
+ (is_prop_locked == NULL || ! is_prop_locked (other)) &&
+ /* Don't include item which can be changed. */
+ (can_set == NULL || can_set (other)) &&
/* We are only interested in same level items. */
gimp_viewable_get_parent (GIMP_VIEWABLE (other)) ==
gimp_viewable_get_parent (GIMP_VIEWABLE (item)))
{
- gboolean value;
-
- g_object_get (other, property, &value, NULL);
-
- if (value)
+ if (is_enabled (other))
*on = g_list_prepend (*on, other);
else
*off = g_list_prepend (*off, other);
diff --git a/app/core/gimpitem-exclusive.h b/app/core/gimpitem-exclusive.h
index 98838c58cb..5381721bdd 100644
--- a/app/core/gimpitem-exclusive.h
+++ b/app/core/gimpitem-exclusive.h
@@ -21,11 +21,29 @@
#ifndef __GIMP_ITEM_EXCLUSIVE_H__
#define __GIMP_ITEM_EXCLUSIVE_H__
+typedef gboolean (* GimpItemIsEnabledFunc) (GimpItem *item);
+typedef gboolean (* GimpItemCanSetFunc) (GimpItem *item);
+typedef void (* GimpItemSetFunc) (GimpItem *item,
+ gboolean enabled,
+ gboolean push_undo);
+typedef gboolean (* GimpItemIsPropLocked) (GimpItem *item);
+typedef GimpUndo * (*GimpItemUndoPush) (GimpImage *image,
+ const gchar *undo_desc,
+ GimpItem *item);
-void gimp_item_toggle_exclusive_visible (GimpItem *item,
- GimpContext *context);
-void gimp_item_toggle_exclusive_linked (GimpItem *item,
- GimpContext *context);
+void gimp_item_toggle_exclusive_visible (GimpItem *item,
+ GimpContext *context);
+void gimp_item_toggle_exclusive (GimpItem *item,
+ GimpItemIsEnabledFunc is_enabled,
+ GimpItemSetFunc set_prop,
+ GimpItemCanSetFunc can_set,
+ GimpItemIsPropLocked is_prop_locked,
+ GimpItemUndoPush undo_push,
+ const gchar *undo_desc,
+ GimpUndoType group_undo_type,
+ GimpContext *context);
+void gimp_item_toggle_exclusive_linked (GimpItem *item,
+ GimpContext *context);
#endif /* __GIMP_ITEM_EXCLUSIVE_H__ */
diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c
index 88e0cf89ff..01d4dec9e6 100644
--- a/app/widgets/gimpitemtreeview.c
+++ b/app/widgets/gimpitemtreeview.c
@@ -108,6 +108,7 @@ typedef struct
GimpIsLockedFunc is_locked;
GimpCanLockFunc can_lock;
GimpSetLockFunc lock;
+ GimpUndoLockPush undo_push;
const gchar *tooltip;
const gchar *help_id;
@@ -119,8 +120,9 @@ typedef struct
/* Undo types and labels. */
GimpUndoType undo_type;
GimpUndoType group_undo_type;
- const gchar *undo_lock_label;
- const gchar *undo_unlock_label;
+ const gchar *undo_lock_desc;
+ const gchar *undo_unlock_desc;
+ const gchar *undo_exclusive_desc;
} LockToggle;
@@ -211,6 +213,9 @@ static void gimp_item_tree_view_lock_clicked (GtkCellRendererToggle *togg
gchar *path,
GdkModifierType state,
GimpItemTreeView *view);
+static gboolean gimp_item_tree_view_lock_button_release (GtkWidget *widget,
+ GdkEvent *event,
+ GimpItemTreeView *view);
static void gimp_item_tree_view_lock_toggled (GtkWidget *widget,
GimpItemTreeView *view);
static void gimp_item_tree_view_update_lock_box (GimpItemTreeView *view,
@@ -523,13 +528,15 @@ gimp_item_tree_view_constructed (GObject *object)
gimp_item_tree_view_add_lock (item_view,
item_view_class->lock_content_icon_name,
(GimpIsLockedFunc) gimp_item_get_lock_content,
- (GimpCanLockFunc) gimp_item_can_lock_content,
- (GimpSetLockFunc) gimp_item_set_lock_content,
+ (GimpCanLockFunc) gimp_item_can_lock_content,
+ (GimpSetLockFunc) gimp_item_set_lock_content,
+ (GimpUndoLockPush) gimp_image_undo_push_item_lock_content,
"lock-content-changed",
GIMP_UNDO_ITEM_LOCK_CONTENT,
GIMP_UNDO_GROUP_ITEM_LOCK_CONTENTS,
_("Lock content"),
_("Unlock content"),
+ _("Set Item Exclusive Content Lock"),
item_view_class->lock_content_tooltip,
item_view_class->lock_content_help_id);
@@ -537,13 +544,15 @@ gimp_item_tree_view_constructed (GObject *object)
gimp_item_tree_view_add_lock (item_view,
item_view_class->lock_position_icon_name,
(GimpIsLockedFunc) gimp_item_get_lock_position,
- (GimpCanLockFunc) gimp_item_can_lock_position,
- (GimpSetLockFunc) gimp_item_set_lock_position,
+ (GimpCanLockFunc) gimp_item_can_lock_position,
+ (GimpSetLockFunc) gimp_item_set_lock_position,
+ (GimpUndoLockPush) gimp_image_undo_push_item_lock_position,
"lock-position-changed",
GIMP_UNDO_ITEM_LOCK_POSITION,
GIMP_UNDO_GROUP_ITEM_LOCK_POSITION,
_("Lock position"),
_("Unlock position"),
+ _("Set Item Exclusive Position Lock"),
item_view_class->lock_position_tooltip,
item_view_class->lock_position_help_id);
@@ -551,13 +560,15 @@ gimp_item_tree_view_constructed (GObject *object)
gimp_item_tree_view_add_lock (item_view,
item_view_class->lock_visibility_icon_name,
(GimpIsLockedFunc) gimp_item_get_lock_visibility,
- (GimpCanLockFunc) gimp_item_can_lock_visibility,
- (GimpSetLockFunc) gimp_item_set_lock_visibility,
+ (GimpCanLockFunc) gimp_item_can_lock_visibility,
+ (GimpSetLockFunc) gimp_item_set_lock_visibility,
+ (GimpUndoLockPush) gimp_image_undo_push_item_lock_visibility,
"lock-visibility-changed",
GIMP_UNDO_ITEM_LOCK_VISIBILITY,
GIMP_UNDO_GROUP_ITEM_LOCK_VISIBILITY,
_("Lock visibility"),
_("Unlock visibility"),
+ _("Set Item Exclusive Visibility Lock"),
item_view_class->lock_visibility_tooltip,
item_view_class->lock_visibility_help_id);
@@ -837,11 +848,13 @@ gimp_item_tree_view_add_lock (GimpItemTreeView *view,
GimpIsLockedFunc is_locked,
GimpCanLockFunc can_lock,
GimpSetLockFunc lock,
+ GimpUndoLockPush undo_push,
const gchar *signal_name,
GimpUndoType undo_type,
GimpUndoType group_undo_type,
- const gchar *undo_lock_label,
- const gchar *undo_unlock_label,
+ const gchar *undo_lock_desc,
+ const gchar *undo_unlock_desc,
+ const gchar *undo_exclusive_desc,
const gchar *tooltip,
const gchar *help_id)
{
@@ -856,14 +869,16 @@ gimp_item_tree_view_add_lock (GimpItemTreeView *view,
data->is_locked = is_locked;
data->can_lock = can_lock;
data->lock = lock;
+ data->undo_push = undo_push;
data->signal_name = signal_name;
data->tooltip = tooltip;
data->help_id = help_id;
- data->undo_type = undo_type;
- data->group_undo_type = group_undo_type;
- data->undo_lock_label = undo_lock_label;
- data->undo_unlock_label = undo_unlock_label;
+ data->undo_type = undo_type;
+ data->group_undo_type = group_undo_type;
+ data->undo_lock_desc = undo_lock_desc;
+ data->undo_unlock_desc = undo_unlock_desc;
+ data->undo_exclusive_desc = undo_exclusive_desc;
view->priv->locks = g_list_prepend (view->priv->locks, data);
@@ -875,6 +890,9 @@ gimp_item_tree_view_add_lock (GimpItemTreeView *view,
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_item_tree_view_lock_toggled),
view);
+ g_signal_connect (toggle, "button-release-event",
+ G_CALLBACK (gimp_item_tree_view_lock_button_release),
+ view);
gimp_help_set_help_data (toggle, tooltip, help_id);
@@ -1855,6 +1873,34 @@ gimp_item_tree_view_lock_changed (GimpItem *item,
gimp_item_tree_view_update_lock_box (view, item, NULL);
}
+static gboolean
+gimp_item_tree_view_lock_button_release (GtkWidget *widget,
+ GdkEvent *event,
+ GimpItemTreeView *view)
+{
+ GdkEventButton *bevent = (GdkEventButton *) event;
+ LockToggle *data;
+ GdkModifierType modifiers;
+
+ data = g_object_get_data (G_OBJECT (widget), "lock-data");
+ modifiers = bevent->state & gimp_get_all_modifiers_mask ();
+
+ if (modifiers == GDK_SHIFT_MASK)
+ gimp_item_toggle_exclusive (view->priv->lock_box_item,
+ data->is_locked,
+ data->lock,
+ data->can_lock,
+ NULL,
+ data->undo_push,
+ data->undo_exclusive_desc,
+ data->group_undo_type,
+ NULL);
+ else
+ return GDK_EVENT_PROPAGATE;
+
+ return GDK_EVENT_STOP;
+}
+
static void
gimp_item_tree_view_lock_toggled (GtkWidget *widget,
GimpItemTreeView *view)
@@ -1882,9 +1928,9 @@ gimp_item_tree_view_lock_toggled (GtkWidget *widget,
if (push_undo)
{
if (locked)
- undo_label = data->undo_lock_label;
+ undo_label = data->undo_lock_desc;
else
- undo_label = data->undo_unlock_label;
+ undo_label = data->undo_unlock_desc;
gimp_image_undo_group_start (image, data->group_undo_type,
undo_label);
@@ -1979,6 +2025,9 @@ gimp_item_tree_view_update_lock_box (GimpItemTreeView *view,
g_signal_handlers_block_by_func (data->toggle,
gimp_item_tree_view_lock_toggled,
view);
+ g_signal_handlers_block_by_func (data->toggle,
+ gimp_item_tree_view_lock_button_release,
+ view);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->toggle),
data->is_locked (item));
@@ -1986,6 +2035,9 @@ gimp_item_tree_view_update_lock_box (GimpItemTreeView *view,
g_signal_handlers_unblock_by_func (data->toggle,
gimp_item_tree_view_lock_toggled,
view);
+ g_signal_handlers_unblock_by_func (data->toggle,
+ gimp_item_tree_view_lock_button_release,
+ view);
}
gtk_widget_set_sensitive (data->toggle, data->can_lock (item));
}
diff --git a/app/widgets/gimpitemtreeview.h b/app/widgets/gimpitemtreeview.h
index 05319a7763..cee2bd552d 100644
--- a/app/widgets/gimpitemtreeview.h
+++ b/app/widgets/gimpitemtreeview.h
@@ -49,6 +49,9 @@ typedef gboolean (* GimpCanLockFunc) (GimpItem *item);
typedef void (* GimpSetLockFunc) (GimpItem *item,
gboolean lock,
gboolean push_undo);
+typedef GimpUndo * (*GimpUndoLockPush) (GimpImage *image,
+ const gchar *undo_desc,
+ GimpItem *item);
#define GIMP_TYPE_ITEM_TREE_VIEW (gimp_item_tree_view_get_type ())
@@ -142,11 +145,13 @@ void gimp_item_tree_view_add_lock (GimpItemTreeView *view,
GimpIsLockedFunc is_locked,
GimpCanLockFunc can_lock,
GimpSetLockFunc lock,
+ GimpUndoLockPush undo_push,
const gchar *signal_name,
GimpUndoType undo_type,
GimpUndoType group_undo_type,
const gchar *undo_lock_label,
const gchar *undo_unlock_label,
+ const gchar *undo_exclusive_desc,
const gchar *tooltip,
const gchar *help_id);
void gimp_item_tree_view_blink_lock (GimpItemTreeView *view,
diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c
index 1aa7262ded..b82b1e8d76 100644
--- a/app/widgets/gimplayertreeview.c
+++ b/app/widgets/gimplayertreeview.c
@@ -40,6 +40,7 @@
#include "core/gimpchannel.h"
#include "core/gimpcontainer.h"
#include "core/gimpimage-undo.h"
+#include "core/gimpimage-undo-push.h"
#include "core/gimpimage.h"
#include "core/gimpitemlist.h"
#include "core/gimpitemundo.h"
@@ -532,13 +533,15 @@ gimp_layer_tree_view_constructed (GObject *object)
gimp_item_tree_view_add_lock (GIMP_ITEM_TREE_VIEW (tree_view),
GIMP_ICON_TRANSPARENCY,
(GimpIsLockedFunc) gimp_layer_get_lock_alpha,
- (GimpCanLockFunc) gimp_layer_can_lock_alpha,
- (GimpSetLockFunc) gimp_layer_set_lock_alpha,
+ (GimpCanLockFunc) gimp_layer_can_lock_alpha,
+ (GimpSetLockFunc) gimp_layer_set_lock_alpha,
+ (GimpUndoLockPush) gimp_image_undo_push_layer_lock_alpha,
"lock-alpha-changed",
GIMP_UNDO_LAYER_LOCK_ALPHA,
GIMP_UNDO_GROUP_LAYER_LOCK_ALPHA,
_("Lock alpha channel"),
_("Unlock alpha channel"),
+ _("Set Item Exclusive Alpha Channel lock"),
_("Lock alpha channel"),
GIMP_HELP_LAYER_LOCK_ALPHA);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]