[gimp/wip/Jehan/layers-dockable-refresh: 13/74] app: improve item lock management with gimp_item_tree_view_add_lock().
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/Jehan/layers-dockable-refresh: 13/74] app: improve item lock management with gimp_item_tree_view_add_lock().
- Date: Sun, 7 Nov 2021 17:00:41 +0000 (UTC)
commit 44c7663e6decd63c4f4a394a047b976d84c15586
Author: Jehan <jehan girinstud io>
Date: Tue Feb 9 02:39:37 2021 +0100
app: improve item lock management with gimp_item_tree_view_add_lock().
Use this for the alpha lock brought by GimpLayerTreeView.
Also use the new gimp_widget_blink_rect() to only blink the appropriate
cell when a lock is preventing you from doing something.
app/tools/gimptools-utils.c | 23 ++-
app/widgets/gimpitemtreeview.c | 321 +++++++++++++++++++++++++++++++++-------
app/widgets/gimpitemtreeview.h | 20 ++-
app/widgets/gimplayertreeview.c | 142 ++----------------
4 files changed, 320 insertions(+), 186 deletions(-)
---
diff --git a/app/tools/gimptools-utils.c b/app/tools/gimptools-utils.c
index 8aa9188b1a..db078c48bf 100644
--- a/app/tools/gimptools-utils.c
+++ b/app/tools/gimptools-utils.c
@@ -30,6 +30,7 @@
#include "vectors/gimpvectors.h"
+#include "widgets/gimpcontainerview.h"
#include "widgets/gimpdialogfactory.h"
#include "widgets/gimpitemtreeview.h"
#include "widgets/gimpwidgets-utils.h"
@@ -49,6 +50,10 @@ gimp_tools_blink_lock_box (Gimp *gimp,
GdkMonitor *monitor;
const gchar *identifier;
+ GtkTreeIter *iter;
+ GtkTreePath *path;
+ GdkRectangle rect;
+
g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (GIMP_IS_ITEM (item));
@@ -75,5 +80,21 @@ gimp_tools_blink_lock_box (Gimp *gimp,
view = GIMP_ITEM_TREE_VIEW (gtk_bin_get_child (GTK_BIN (dockable)));
- gimp_widget_blink (gimp_item_tree_view_get_lock_box (view));
+ /* Find the item in the tree view. */
+ iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view),
+ (GimpViewable *) item);
+ path = gtk_tree_model_get_path (GIMP_CONTAINER_TREE_VIEW (view)->model, iter);
+
+ /* Scroll dockable to make sure the cell is showing. */
+ gtk_tree_view_scroll_to_cell (GIMP_CONTAINER_TREE_VIEW (view)->view, path,
+ gtk_tree_view_get_column (GIMP_CONTAINER_TREE_VIEW (view)->view, 1),
+ FALSE, 0.0, 0.0);
+
+ /* Now blink the lock cell of the specified item. */
+ gtk_tree_view_get_cell_area (GIMP_CONTAINER_TREE_VIEW (view)->view, path,
+ gtk_tree_view_get_column (GIMP_CONTAINER_TREE_VIEW (view)->view, 1),
+ &rect);
+ gimp_widget_blink_rect (GTK_WIDGET (GIMP_CONTAINER_TREE_VIEW (view)->view), &rect);
+
+ gtk_tree_path_free (path);
}
diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c
index a791812276..47afa19340 100644
--- a/app/widgets/gimpitemtreeview.c
+++ b/app/widgets/gimpitemtreeview.c
@@ -80,6 +80,8 @@ struct _GimpItemTreeViewPrivate
GtkWidget *lock_position_toggle;
GtkWidget *lock_visibility_toggle;
+ GList *additional_locks;
+
GtkWidget *new_button;
GtkWidget *raise_button;
GtkWidget *lower_button;
@@ -103,6 +105,29 @@ struct _GimpItemTreeViewPrivate
gboolean inserting_item; /* EEK */
};
+typedef struct
+{
+ GtkWidget *toggle;
+ const gchar *icon_name;
+
+ GimpIsLockedFunc is_locked;
+ GimpCanLockFunc can_lock;
+ GimpSetLockFunc lock;
+
+ const gchar *tooltip;
+ const gchar *help_id;
+
+ /* Signal handling when lock is changed from core. */
+ const gchar *signal_name;
+ GimpTreeHandler *changed_handler;
+
+ /* Undo types and labels. */
+ GimpUndoType undo_type;
+ GimpUndoType group_undo_type;
+ const gchar *undo_lock_label;
+ const gchar *undo_unlock_label;
+} LockToggle;
+
static void gimp_item_tree_view_view_iface_init (GimpContainerViewInterface *view_iface);
static void gimp_item_tree_view_docked_iface_init (GimpDockedInterface *docked_iface);
@@ -191,6 +216,8 @@ static void gimp_item_tree_view_lock_clicked (GtkCellRendererToggle *togg
gchar *path,
GdkModifierType state,
GimpItemTreeView *view);
+static void gimp_item_tree_view_lock_toggled (GtkWidget *widget,
+ GimpItemTreeView *view);
static void gimp_item_tree_view_lock_content_toggled
(GtkWidget *widget,
GimpItemTreeView *view);
@@ -217,6 +244,11 @@ static void gimp_item_tree_view_row_expanded (GtkTreeView *tree_vie
GtkTreePath *path,
GimpItemTreeView *item_view);
+static gint gimp_item_tree_view_get_n_locks (GimpItemTreeView *view,
+ GimpItem *item,
+ const gchar **icon_name);
+
+
G_DEFINE_TYPE_WITH_CODE (GimpItemTreeView, gimp_item_tree_view,
GIMP_TYPE_CONTAINER_TREE_VIEW,
G_ADD_PRIVATE (GimpItemTreeView)
@@ -361,9 +393,9 @@ gimp_item_tree_view_constructed (GObject *object)
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (object);
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (object);
GtkTreeViewColumn *column;
- GtkWidget *hbox;
GtkWidget *image;
GtkIconSize icon_size;
+ gint button_spacing;
G_OBJECT_CLASS (parent_class)->constructed (object);
@@ -492,13 +524,18 @@ gimp_item_tree_view_constructed (GObject *object)
gtk_widget_get_parent (item_view->priv->multi_selection_label),
FALSE, FALSE, 0, GTK_PACK_END);
- hbox = gimp_item_tree_view_get_lock_box (item_view);
+ /* Lock box. */
+ gtk_widget_style_get (GTK_WIDGET (item_view),
+ "button-spacing", &button_spacing,
+ NULL);
+
+ item_view->priv->lock_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, button_spacing);
- /* Lock content toggle */
+ /* Lock box: content toggle */
item_view->priv->lock_content_toggle = gtk_toggle_button_new ();
- gtk_box_pack_start (GTK_BOX (hbox), item_view->priv->lock_content_toggle,
+ gtk_box_pack_start (GTK_BOX (item_view->priv->lock_box), item_view->priv->lock_content_toggle,
FALSE, FALSE, 0);
- gtk_box_reorder_child (GTK_BOX (hbox),
+ gtk_box_reorder_child (GTK_BOX (item_view->priv->lock_box),
item_view->priv->lock_content_toggle, 0);
gtk_widget_show (item_view->priv->lock_content_toggle);
@@ -520,11 +557,11 @@ gimp_item_tree_view_constructed (GObject *object)
image);
gtk_widget_show (image);
- /* Lock position toggle */
+ /* Lock box: position toggle */
item_view->priv->lock_position_toggle = gtk_toggle_button_new ();
- gtk_box_pack_start (GTK_BOX (hbox), item_view->priv->lock_position_toggle,
+ gtk_box_pack_start (GTK_BOX (item_view->priv->lock_box), item_view->priv->lock_position_toggle,
FALSE, FALSE, 0);
- gtk_box_reorder_child (GTK_BOX (hbox),
+ gtk_box_reorder_child (GTK_BOX (item_view->priv->lock_box),
item_view->priv->lock_position_toggle, 1);
gtk_widget_show (item_view->priv->lock_position_toggle);
@@ -542,11 +579,11 @@ gimp_item_tree_view_constructed (GObject *object)
image);
gtk_widget_show (image);
- /* Lock visibility toggle */
+ /* Lock box: visibility toggle */
item_view->priv->lock_visibility_toggle = gtk_toggle_button_new ();
- gtk_box_pack_start (GTK_BOX (hbox), item_view->priv->lock_visibility_toggle,
+ gtk_box_pack_start (GTK_BOX (item_view->priv->lock_box), item_view->priv->lock_visibility_toggle,
FALSE, FALSE, 0);
- gtk_box_reorder_child (GTK_BOX (hbox),
+ gtk_box_reorder_child (GTK_BOX (item_view->priv->lock_box),
item_view->priv->lock_visibility_toggle, 2);
gtk_widget_show (item_view->priv->lock_visibility_toggle);
@@ -567,8 +604,8 @@ gimp_item_tree_view_constructed (GObject *object)
/* Lock popover. */
item_view->priv->lock_popover = gtk_popover_new (GTK_WIDGET (tree_view->view));
gtk_popover_set_modal (GTK_POPOVER (item_view->priv->lock_popover), TRUE);
- gtk_container_add (GTK_CONTAINER (item_view->priv->lock_popover), hbox);
- gtk_widget_show (hbox);
+ gtk_container_add (GTK_CONTAINER (item_view->priv->lock_popover), item_view->priv->lock_box);
+ gtk_widget_show (item_view->priv->lock_box);
}
static void
@@ -585,6 +622,13 @@ gimp_item_tree_view_dispose (GObject *object)
view->priv->lock_popover = NULL;
}
+ if (view->priv->additional_locks)
+ {
+ g_list_free_full (view->priv->additional_locks,
+ (GDestroyNotify) g_free);
+ view->priv->additional_locks = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -803,23 +847,61 @@ gimp_item_tree_view_add_options (GimpItemTreeView *view,
}
}
-GtkWidget *
-gimp_item_tree_view_get_lock_box (GimpItemTreeView *view)
+void
+gimp_item_tree_view_add_lock (GimpItemTreeView *view,
+ const gchar *icon_name,
+ GimpIsLockedFunc is_locked,
+ GimpCanLockFunc can_lock,
+ GimpSetLockFunc lock,
+ const gchar *signal_name,
+ GimpUndoType undo_type,
+ GimpUndoType group_undo_type,
+ const gchar *undo_lock_label,
+ const gchar *undo_unlock_label,
+ const gchar *tooltip,
+ const gchar *help_id)
{
- g_return_val_if_fail (GIMP_IS_ITEM_TREE_VIEW (view), NULL);
+ LockToggle *data;
+ GtkWidget *toggle = gtk_toggle_button_new ();
+ GtkWidget *image;
+ GtkIconSize icon_size;
+
+ data = g_new0 (LockToggle, 1);
+ data->toggle = toggle;
+ data->icon_name = icon_name;
+ data->is_locked = is_locked;
+ data->can_lock = can_lock;
+ data->lock = lock;
+ 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;
+
+ view->priv->additional_locks = g_list_prepend (view->priv->additional_locks,
+ data);
+
+ gtk_box_pack_end (GTK_BOX (view->priv->lock_box), toggle, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (view->priv->lock_box), toggle, 0);
+ gtk_widget_show (toggle);
+
+ g_object_set_data (G_OBJECT (toggle), "lock-data", data);
+ g_signal_connect (toggle, "toggled",
+ G_CALLBACK (gimp_item_tree_view_lock_toggled),
+ view);
+
+ gimp_help_set_help_data (toggle, tooltip, help_id);
- if (! view->priv->lock_box)
- {
- gint button_spacing;
-
- gtk_widget_style_get (GTK_WIDGET (view),
- "button-spacing", &button_spacing,
- NULL);
-
- view->priv->lock_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, button_spacing);
- }
+ gtk_widget_style_get (GTK_WIDGET (view),
+ "button-icon-size", &icon_size,
+ NULL);
- return view->priv->lock_box;
+ image = gtk_image_new_from_icon_name (icon_name, icon_size);
+ gtk_container_add (GTK_CONTAINER (toggle), image);
+ gtk_widget_show (image);
}
GtkWidget *
@@ -948,6 +1030,7 @@ gimp_item_tree_view_set_container (GimpContainerView *view,
{
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view);
GimpContainer *old_container;
+ GList *list;
old_container = gimp_container_view_get_container (view);
@@ -967,6 +1050,14 @@ gimp_item_tree_view_set_container (GimpContainerView *view,
gimp_tree_handler_disconnect (item_view->priv->lock_visibility_changed_handler);
item_view->priv->lock_visibility_changed_handler = NULL;
+
+ for (list = item_view->priv->additional_locks; list; list = list->next)
+ {
+ LockToggle *data = list->data;
+
+ gimp_tree_handler_disconnect (data->changed_handler);
+ data->changed_handler = NULL;
+ }
}
parent_view_iface->set_container (view, container);
@@ -997,6 +1088,16 @@ gimp_item_tree_view_set_container (GimpContainerView *view,
gimp_tree_handler_connect (container, "lock-visibility-changed",
G_CALLBACK (gimp_item_tree_view_lock_changed),
view);
+
+ for (list = item_view->priv->additional_locks; list; list = list->next)
+ {
+ LockToggle *data = list->data;
+
+ data->changed_handler = gimp_tree_handler_connect (container,
+ data->signal_name,
+ G_CALLBACK (gimp_item_tree_view_lock_changed),
+ view);
+ }
}
}
@@ -1041,7 +1142,6 @@ gimp_item_tree_view_insert_item (GimpContainerView *view,
gpointer parent_insert_data,
gint index)
{
- GimpItemTreeViewClass *item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view);
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view);
GimpItem *item = GIMP_ITEM (viewable);
@@ -1049,6 +1149,7 @@ gimp_item_tree_view_insert_item (GimpContainerView *view,
GimpRGB color;
gboolean has_color;
const gchar *icon_name = "system-lock-screen";
+ gint n_locks;
item_view->priv->inserting_item = TRUE;
@@ -1062,14 +1163,7 @@ gimp_item_tree_view_insert_item (GimpContainerView *view,
gimp_item_get_color_tag (item) ==
GIMP_COLOR_TAG_NONE);
- if ((gint) gimp_item_is_content_locked (item) +
- (gint) gimp_item_is_position_locked (item) +
- (gint) gimp_item_is_visibility_locked (item) == 1)
- icon_name = gimp_item_is_content_locked (item) ?
- item_view_class->lock_content_icon_name :
- (gimp_item_is_position_locked (item) ?
- item_view_class->lock_position_icon_name :
- item_view_class->lock_visibility_icon_name);
+ n_locks = gimp_item_tree_view_get_n_locks (item_view, item, &icon_name);
gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter,
@@ -1081,9 +1175,7 @@ gimp_item_tree_view_insert_item (GimpContainerView *view,
! gimp_item_is_visible (item),
item_view->priv->model_column_locked,
- gimp_item_is_content_locked (item) ||
- gimp_item_is_position_locked (item) ||
- gimp_item_is_visibility_locked (item),
+ n_locks > 0,
item_view->priv->model_column_lock_icon,
icon_name,
@@ -1748,31 +1840,22 @@ static void
gimp_item_tree_view_lock_changed (GimpItem *item,
GimpItemTreeView *view)
{
- GimpItemTreeViewClass *item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view);
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (view);
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
GtkTreeIter *iter;
const gchar *icon_name = "system-lock-screen";
+ gint n_locks;
iter = gimp_container_view_lookup (container_view,
(GimpViewable *) item);
- if ((gint) gimp_item_is_content_locked (item) +
- (gint) gimp_item_is_position_locked (item) +
- (gint) gimp_item_is_visibility_locked (item) == 1)
- icon_name = gimp_item_is_content_locked (item) ?
- item_view_class->lock_content_icon_name :
- (gimp_item_is_position_locked (item) ?
- item_view_class->lock_position_icon_name :
- item_view_class->lock_visibility_icon_name);
+ n_locks = gimp_item_tree_view_get_n_locks (view, item, &icon_name);
if (iter)
gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter,
view->priv->model_column_locked,
- gimp_item_is_content_locked (item) ||
- gimp_item_is_position_locked (item) ||
- gimp_item_is_visibility_locked (item),
+ n_locks > 0,
view->priv->model_column_lock_icon,
icon_name,
@@ -1783,6 +1866,52 @@ gimp_item_tree_view_lock_changed (GimpItem *item,
gimp_item_tree_view_update_lock_box (view, item);
}
+static void
+gimp_item_tree_view_lock_toggled (GtkWidget *widget,
+ GimpItemTreeView *view)
+{
+ GimpImage *image = view->priv->image;
+ LockToggle *data;
+ GimpUndo *undo;
+ const gchar *undo_label;
+ gboolean push_undo = TRUE;
+ gboolean locked;
+
+ locked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ data = g_object_get_data (G_OBJECT (widget), "lock-data");
+
+ if (! data->can_lock (view->priv->lock_box_item) ||
+ locked == data->is_locked (view->priv->lock_box_item))
+ return;
+
+ undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO,
+ data->undo_type);
+
+ if (undo && GIMP_ITEM_UNDO (undo)->item == view->priv->lock_box_item)
+ push_undo = FALSE;
+
+ if (push_undo)
+ {
+ if (locked)
+ undo_label = data->undo_lock_label;
+ else
+ undo_label = data->undo_unlock_label;
+
+ gimp_image_undo_group_start (image, data->group_undo_type,
+ undo_label);
+ }
+
+ /* TODO: maybe we should also have a modifier-interaction where we can
+ * lock all same-level items (Shift-click for instance like eye click)
+ * and maybe another modifier for all selected items at once.
+ */
+ data->lock (view->priv->lock_box_item, locked, push_undo);
+
+ gimp_image_flush (image);
+ if (push_undo)
+ gimp_image_undo_group_end (image);
+}
+
static void
gimp_item_tree_view_lock_content_toggled (GtkWidget *widget,
GimpItemTreeView *view)
@@ -1977,12 +2106,13 @@ static void
gimp_item_tree_view_update_lock_box (GimpItemTreeView *view,
GimpItem *item)
{
- gboolean have_lock_content;
- gboolean can_lock_content;
- gboolean have_lock_position;
- gboolean can_lock_position;
- gboolean have_lock_visibility;
- gboolean can_lock_visibility;
+ GList *list;
+ gboolean have_lock_content;
+ gboolean can_lock_content;
+ gboolean have_lock_position;
+ gboolean can_lock_position;
+ gboolean have_lock_visibility;
+ gboolean can_lock_visibility;
have_lock_content = gimp_item_get_lock_content (item);
can_lock_content = gimp_item_can_lock_content (item);
@@ -2040,6 +2170,26 @@ gimp_item_tree_view_update_lock_box (GimpItemTreeView *view,
gtk_widget_set_sensitive (view->priv->lock_position_toggle, can_lock_position);
gtk_widget_set_sensitive (view->priv->lock_position_toggle, can_lock_visibility);
+ for (list = view->priv->additional_locks; list; list = list->next)
+ {
+ LockToggle *data = list->data;
+
+ if (data->is_locked (item) !=
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->toggle)))
+ {
+ g_signal_handlers_block_by_func (data->toggle,
+ gimp_item_tree_view_lock_toggled,
+ view);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->toggle),
+ data->is_locked (item));
+
+ g_signal_handlers_unblock_by_func (data->toggle,
+ gimp_item_tree_view_lock_toggled,
+ view);
+ }
+ gtk_widget_set_sensitive (data->toggle, data->can_lock (item));
+ }
view->priv->lock_box_item = item;
}
@@ -2081,3 +2231,60 @@ gimp_item_tree_view_row_expanded (GtkTreeView *tree_view,
}
}
}
+
+
+/* Helper functions. */
+
+static gint
+gimp_item_tree_view_get_n_locks (GimpItemTreeView *view,
+ GimpItem *item,
+ const gchar **icon_name)
+{
+ GimpItemTreeViewClass *item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view);
+ GList *list;
+ gint n_locks;
+
+ *icon_name = "system-lock-screen";
+
+ n_locks = (gint) gimp_item_is_content_locked (item) +
+ (gint) gimp_item_is_position_locked (item) +
+ (gint) gimp_item_is_visibility_locked (item);
+
+ for (list = view->priv->additional_locks; list; list = list->next)
+ {
+ LockToggle *data = list->data;
+
+ n_locks += (gint) data->is_locked (item);
+ }
+
+ if (n_locks == 1)
+ {
+ if (gimp_item_is_content_locked (item))
+ {
+ *icon_name = item_view_class->lock_content_icon_name;
+ }
+ else if (gimp_item_is_position_locked (item))
+ {
+ *icon_name = item_view_class->lock_position_icon_name;
+ }
+ else if (gimp_item_is_visibility_locked (item))
+ {
+ *icon_name = item_view_class->lock_visibility_icon_name;
+ }
+ else
+ {
+ for (list = view->priv->additional_locks; list; list = list->next)
+ {
+ LockToggle *data = list->data;
+
+ if (data->is_locked (item))
+ {
+ *icon_name = data->icon_name;
+ break;
+ }
+ }
+ }
+ }
+
+ return n_locks;
+}
diff --git a/app/widgets/gimpitemtreeview.h b/app/widgets/gimpitemtreeview.h
index 951d6b4b8f..680ac056a3 100644
--- a/app/widgets/gimpitemtreeview.h
+++ b/app/widgets/gimpitemtreeview.h
@@ -44,6 +44,13 @@ typedef void (* GimpRemoveItemFunc) (GimpImage *image,
typedef GimpItem * (* GimpNewItemFunc) (GimpImage *image);
+typedef gboolean (* GimpIsLockedFunc) (GimpItem *item);
+typedef gboolean (* GimpCanLockFunc) (GimpItem *item);
+typedef void (* GimpSetLockFunc) (GimpItem *item,
+ gboolean lock,
+ gboolean push_undo);
+
+
#define GIMP_TYPE_ITEM_TREE_VIEW (gimp_item_tree_view_get_type ())
#define GIMP_ITEM_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ITEM_TREE_VIEW,
GimpItemTreeView))
#define GIMP_ITEM_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ITEM_TREE_VIEW,
GimpItemTreeViewClass))
@@ -130,7 +137,18 @@ GimpImage * gimp_item_tree_view_get_image (GimpItemTreeView *view);
void gimp_item_tree_view_add_options (GimpItemTreeView *view,
const gchar *label,
GtkWidget *options);
-GtkWidget * gimp_item_tree_view_get_lock_box (GimpItemTreeView *view);
+void gimp_item_tree_view_add_lock (GimpItemTreeView *view,
+ const gchar *icon_name,
+ GimpIsLockedFunc is_locked,
+ GimpCanLockFunc can_lock,
+ GimpSetLockFunc lock,
+ const gchar *signal_name,
+ GimpUndoType undo_type,
+ GimpUndoType group_undo_type,
+ const gchar *undo_lock_label,
+ const gchar *undo_unlock_label,
+ const gchar *tooltip,
+ const gchar *help_id);
GtkWidget * gimp_item_tree_view_get_new_button (GimpItemTreeView *view);
GtkWidget * gimp_item_tree_view_get_delete_button (GimpItemTreeView *view);
diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c
index f53fe33366..ba7fbbf852 100644
--- a/app/widgets/gimplayertreeview.c
+++ b/app/widgets/gimplayertreeview.c
@@ -73,7 +73,6 @@ struct _GimpLayerTreeViewPrivate
{
GtkWidget *layer_mode_box;
GtkAdjustment *opacity_adjustment;
- GtkWidget *lock_alpha_toggle;
GtkWidget *anchor_button;
GtkWidget *link_button;
@@ -93,7 +92,6 @@ struct _GimpLayerTreeViewPrivate
GimpTreeHandler *mode_changed_handler;
GimpTreeHandler *opacity_changed_handler;
- GimpTreeHandler *lock_alpha_changed_handler;
GimpTreeHandler *mask_changed_handler;
GimpTreeHandler *alpha_changed_handler;
};
@@ -169,8 +167,6 @@ static void gimp_layer_tree_view_layer_mode_box_callback (GtkWidget
GimpLayerTreeView *view);
static void gimp_layer_tree_view_opacity_scale_changed (GtkAdjustment *adj,
GimpLayerTreeView *view);
-static void gimp_layer_tree_view_lock_alpha_button_toggled (GtkWidget *widget,
- GimpLayerTreeView *view);
static void gimp_layer_tree_view_layer_signal_handler (GimpLayer *layer,
GimpLayerTreeView *view);
static void gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
@@ -281,9 +277,6 @@ gimp_layer_tree_view_init (GimpLayerTreeView *view)
{
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
GtkWidget *scale;
- GtkWidget *hbox;
- GtkWidget *image;
- GtkIconSize icon_size;
PangoAttribute *attr;
view->priv = gimp_layer_tree_view_get_instance_private (view);
@@ -330,31 +323,6 @@ gimp_layer_tree_view_init (GimpLayerTreeView *view)
G_CALLBACK (gimp_layer_tree_view_opacity_scale_changed),
view);
- /* Lock alpha toggle */
-
- hbox = gimp_item_tree_view_get_lock_box (GIMP_ITEM_TREE_VIEW (view));
-
- view->priv->lock_alpha_toggle = gtk_toggle_button_new ();
- gtk_box_pack_start (GTK_BOX (hbox), view->priv->lock_alpha_toggle,
- FALSE, FALSE, 0);
- gtk_widget_show (view->priv->lock_alpha_toggle);
-
- g_signal_connect (view->priv->lock_alpha_toggle, "toggled",
- G_CALLBACK (gimp_layer_tree_view_lock_alpha_button_toggled),
- view);
-
- gimp_help_set_help_data (view->priv->lock_alpha_toggle,
- _("Lock alpha channel"),
- GIMP_HELP_LAYER_LOCK_ALPHA);
-
- gtk_widget_style_get (GTK_WIDGET (view),
- "button-icon-size", &icon_size,
- NULL);
-
- image = gtk_image_new_from_icon_name (GIMP_ICON_TRANSPARENCY, icon_size);
- gtk_container_add (GTK_CONTAINER (view->priv->lock_alpha_toggle), image);
- gtk_widget_show (image);
-
view->priv->italic_attrs = pango_attr_list_new ();
attr = pango_attr_style_new (PANGO_STYLE_ITALIC);
attr->start_index = 0;
@@ -555,6 +523,21 @@ gimp_layer_tree_view_constructed (GObject *object)
gtk_container_add (GTK_CONTAINER (layer_view->priv->link_popover), grid);
gtk_widget_show (grid);
+
+ /* Lock alpha toggle */
+
+ 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,
+ "lock-alpha-changed",
+ GIMP_UNDO_LAYER_LOCK_ALPHA,
+ GIMP_UNDO_GROUP_LAYER_LOCK_ALPHA,
+ _("Lock alpha channel"),
+ _("Unlock alpha channel"),
+ _("Lock alpha channel"),
+ GIMP_HELP_LAYER_LOCK_ALPHA);
}
static void
@@ -597,9 +580,6 @@ gimp_layer_tree_view_set_container (GimpContainerView *view,
gimp_tree_handler_disconnect (layer_view->priv->opacity_changed_handler);
layer_view->priv->opacity_changed_handler = NULL;
- gimp_tree_handler_disconnect (layer_view->priv->lock_alpha_changed_handler);
- layer_view->priv->lock_alpha_changed_handler = NULL;
-
gimp_tree_handler_disconnect (layer_view->priv->mask_changed_handler);
layer_view->priv->mask_changed_handler = NULL;
@@ -621,11 +601,6 @@ gimp_layer_tree_view_set_container (GimpContainerView *view,
G_CALLBACK (gimp_layer_tree_view_layer_signal_handler),
view);
- layer_view->priv->lock_alpha_changed_handler =
- gimp_tree_handler_connect (container, "lock-alpha-changed",
- G_CALLBACK (gimp_layer_tree_view_layer_signal_handler),
- view);
-
layer_view->priv->mask_changed_handler =
gimp_tree_handler_connect (container, "mask-changed",
G_CALLBACK (gimp_layer_tree_view_mask_changed),
@@ -1478,63 +1453,6 @@ gimp_layer_tree_view_layer_mode_box_callback (GtkWidget *widget,
gimp_image_undo_group_end (image);
}
-static void
-gimp_layer_tree_view_lock_alpha_button_toggled (GtkWidget *widget,
- GimpLayerTreeView *view)
-{
- GimpImage *image;
- GList *layers;
- GList *iter;
- GimpUndo *undo;
- gboolean push_undo = TRUE;
- gboolean lock_alpha;
- gint n_layers = 0;
-
- lock_alpha = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
- image = gimp_item_tree_view_get_image (GIMP_ITEM_TREE_VIEW (view));
- layers = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->get_selected_items (image);
- undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO,
- GIMP_UNDO_LAYER_LOCK_ALPHA);
-
- for (iter = layers; iter; iter = iter->next)
- {
- if (gimp_layer_can_lock_alpha (iter->data) &&
- gimp_layer_get_lock_alpha (iter->data) != lock_alpha)
- {
- n_layers++;
-
- if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (iter->data))
- push_undo = FALSE;
- }
- }
-
- if (n_layers > 1)
- {
- /* Don't compress mode undos with more than 1 layer changed. */
- push_undo = TRUE;
-
- gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_LAYER_LOCK_ALPHA,
- lock_alpha ? _("Lock alpha channels") : _("Unlock alpha channels"));
- }
-
- for (iter = layers; iter; iter = iter->next)
- {
- GimpLayer *layer = iter->data;
-
- if (gimp_layer_can_lock_alpha (layer) &&
- gimp_layer_get_lock_alpha (layer) != lock_alpha)
- {
- BLOCK();
- gimp_layer_set_lock_alpha (layer, lock_alpha, push_undo);
- UNBLOCK();
- }
- }
- gimp_image_flush (image);
-
- if (n_layers > 1)
- gimp_image_undo_group_end (image);
-}
-
static void
gimp_layer_tree_view_opacity_scale_changed (GtkAdjustment *adjustment,
GimpLayerTreeView *view)
@@ -1624,23 +1542,12 @@ gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
GList *iter;
GimpLayerMode mode = GIMP_LAYER_MODE_SEPARATOR;
GimpLayerModeContext context = 0;
- gboolean all_have_lock_alpha = TRUE;
- gboolean some_can_lock_alpha = FALSE;
- gboolean inconsistent_lock_alpha = FALSE;
/*gboolean inconsistent_opacity = FALSE;*/
gboolean inconsistent_mode = FALSE;
gdouble opacity = -1.0;
for (iter = layers; iter; iter = iter->next)
{
- if (! gimp_layer_get_lock_alpha (iter->data))
- all_have_lock_alpha = FALSE;
- else
- inconsistent_lock_alpha = TRUE;
-
- if (gimp_layer_can_lock_alpha (iter->data))
- some_can_lock_alpha = TRUE;
-
#if 0
if (opacity != -1.0 &&
opacity != gimp_layer_get_opacity (iter->data))
@@ -1672,8 +1579,6 @@ gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
if (! context)
context = GIMP_LAYER_MODE_CONTEXT_LAYER;
- inconsistent_lock_alpha = (! all_have_lock_alpha && inconsistent_lock_alpha);
-
BLOCK (view->priv->layer_mode_box,
gimp_layer_tree_view_layer_mode_box_callback);
@@ -1685,23 +1590,6 @@ gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
UNBLOCK (view->priv->layer_mode_box,
gimp_layer_tree_view_layer_mode_box_callback);
- if (all_have_lock_alpha !=
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->lock_alpha_toggle)))
- {
- BLOCK (view->priv->lock_alpha_toggle,
- gimp_layer_tree_view_lock_alpha_button_toggled);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->lock_alpha_toggle),
- all_have_lock_alpha);
-
- UNBLOCK (view->priv->lock_alpha_toggle,
- gimp_layer_tree_view_lock_alpha_button_toggled);
- }
- gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (view->priv->lock_alpha_toggle),
- inconsistent_lock_alpha);
-
- gtk_widget_set_sensitive (view->priv->lock_alpha_toggle, some_can_lock_alpha);
-
if (opacity * 100.0 !=
gtk_adjustment_get_value (view->priv->opacity_adjustment))
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]