Commit f5d1686a authored by Ell's avatar Ell
Browse files

app: add GimpFilter::active property; move ::visible to GimpItem

Add an "active" property to GimpFilter, which replaces its
"visible" property.  The new property assumes the lower-level role
"visible" had -- controlling whether the filter has any effect as
part of its parent filter-stack.

Add a "visible" property to GimpItem, separate from the "active"
property, which assumes the higher-level role "visible" had --
controlling whether the item is considered "visible", as per the
GUI.  By default, the item's "visible" property is bound to the
filter's "active" property, so that changes in visibility directly
affect the filter's "activeness"; this binding can be controlled
using the new gimp_item_bind_visible_to_active() function.

This distinction is currently necessary for floating selections.
Floating selection layers must not be active in their parent stack,
regardless of their visibility, in particular, so that their mode
node doesn't hide the entire backdrop when their composite mode
excludes the backdrop (i.e., when it's dst-atop or src-in).
Instead, their visibility should affect the activeness of the
floating-selection filter of the drawable they're attached to.
This is handled by the next commit.
parent e02cb6ad
......@@ -61,7 +61,7 @@ gimp_drawable_has_filters (GimpDrawable *drawable)
{
GimpFilter *filter = list->data;
if (gimp_filter_is_visible (filter))
if (gimp_filter_get_active (filter))
return TRUE;
}
......
......@@ -55,7 +55,7 @@ static void gimp_drawable_stack_drawable_update (GimpItem *item,
gint width,
gint height,
GimpDrawableStack *stack);
static void gimp_drawable_stack_drawable_visible (GimpItem *item,
static void gimp_drawable_stack_drawable_active (GimpItem *item,
GimpDrawableStack *stack);
......@@ -110,8 +110,8 @@ gimp_drawable_stack_constructed (GObject *object)
gimp_container_add_handler (container, "update",
G_CALLBACK (gimp_drawable_stack_drawable_update),
container);
gimp_container_add_handler (container, "visibility-changed",
G_CALLBACK (gimp_drawable_stack_drawable_visible),
gimp_container_add_handler (container, "active-changed",
G_CALLBACK (gimp_drawable_stack_drawable_active),
container);
}
......@@ -123,8 +123,8 @@ gimp_drawable_stack_add (GimpContainer *container,
GIMP_CONTAINER_CLASS (parent_class)->add (container, object);
if (gimp_item_get_visible (GIMP_ITEM (object)))
gimp_drawable_stack_drawable_visible (GIMP_ITEM (object), stack);
if (gimp_filter_get_active (GIMP_FILTER (object)))
gimp_drawable_stack_drawable_active (GIMP_ITEM (object), stack);
}
static void
......@@ -135,8 +135,8 @@ gimp_drawable_stack_remove (GimpContainer *container,
GIMP_CONTAINER_CLASS (parent_class)->remove (container, object);
if (gimp_item_get_visible (GIMP_ITEM (object)))
gimp_drawable_stack_drawable_visible (GIMP_ITEM (object), stack);
if (gimp_filter_get_active (GIMP_FILTER (object)))
gimp_drawable_stack_drawable_active (GIMP_ITEM (object), stack);
}
static void
......@@ -148,8 +148,8 @@ gimp_drawable_stack_reorder (GimpContainer *container,
GIMP_CONTAINER_CLASS (parent_class)->reorder (container, object, new_index);
if (gimp_item_get_visible (GIMP_ITEM (object)))
gimp_drawable_stack_drawable_visible (GIMP_ITEM (object), stack);
if (gimp_filter_get_active (GIMP_FILTER (object)))
gimp_drawable_stack_drawable_active (GIMP_ITEM (object), stack);
}
......@@ -194,7 +194,7 @@ gimp_drawable_stack_drawable_update (GimpItem *item,
gint height,
GimpDrawableStack *stack)
{
if (gimp_item_get_visible (item))
if (gimp_filter_get_active (GIMP_FILTER (item)))
{
gint offset_x;
gint offset_y;
......@@ -208,8 +208,8 @@ gimp_drawable_stack_drawable_update (GimpItem *item,
}
static void
gimp_drawable_stack_drawable_visible (GimpItem *item,
GimpDrawableStack *stack)
gimp_drawable_stack_drawable_active (GimpItem *item,
GimpDrawableStack *stack)
{
gint offset_x;
gint offset_y;
......
......@@ -32,14 +32,14 @@
enum
{
VISIBILITY_CHANGED,
ACTIVE_CHANGED,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_VISIBLE,
PROP_ACTIVE,
PROP_IS_LAST_NODE
};
......@@ -50,7 +50,7 @@ struct _GimpFilterPrivate
{
GeglNode *node;
guint visible : 1;
guint active : 1;
guint is_last_node : 1;
GimpApplicator *applicator;
......@@ -92,11 +92,11 @@ gimp_filter_class_init (GimpFilterClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
gimp_filter_signals[VISIBILITY_CHANGED] =
g_signal_new ("visibility-changed",
gimp_filter_signals[ACTIVE_CHANGED] =
g_signal_new ("active-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpFilterClass, visibility_changed),
G_STRUCT_OFFSET (GimpFilterClass, active_changed),
NULL, NULL,
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
......@@ -107,11 +107,11 @@ gimp_filter_class_init (GimpFilterClass *klass)
gimp_object_class->get_memsize = gimp_filter_get_memsize;
klass->visibility_changed = NULL;
klass->active_changed = NULL;
klass->get_node = gimp_filter_real_get_node;
g_object_class_install_property (object_class, PROP_VISIBLE,
g_param_spec_boolean ("visible", NULL, NULL,
g_object_class_install_property (object_class, PROP_ACTIVE,
g_param_spec_boolean ("active", NULL, NULL,
TRUE,
GIMP_PARAM_READWRITE));
......@@ -129,7 +129,7 @@ gimp_filter_init (GimpFilter *filter)
{
GimpFilterPrivate *private = GET_PRIVATE (filter);
private->visible = TRUE;
private->active = TRUE;
}
static void
......@@ -152,8 +152,8 @@ gimp_filter_set_property (GObject *object,
switch (property_id)
{
case PROP_VISIBLE:
gimp_filter_set_visible (filter, g_value_get_boolean (value));
case PROP_ACTIVE:
gimp_filter_set_active (filter, g_value_get_boolean (value));
break;
case PROP_IS_LAST_NODE:
gimp_filter_set_is_last_node (filter, g_value_get_boolean (value));
......@@ -175,8 +175,8 @@ gimp_filter_get_property (GObject *object,
switch (property_id)
{
case PROP_VISIBLE:
g_value_set_boolean (value, private->visible);
case PROP_ACTIVE:
g_value_set_boolean (value, private->active);
break;
case PROP_IS_LAST_NODE:
g_value_set_boolean (value, private->is_last_node);
......@@ -248,49 +248,29 @@ gimp_filter_peek_node (GimpFilter *filter)
}
void
gimp_filter_set_visible (GimpFilter *filter,
gboolean visible)
gimp_filter_set_active (GimpFilter *filter,
gboolean active)
{
g_return_if_fail (GIMP_IS_FILTER (filter));
visible = visible ? TRUE : FALSE;
active = active ? TRUE : FALSE;
if (visible != gimp_filter_get_visible (filter))
if (active != gimp_filter_get_active (filter))
{
GET_PRIVATE (filter)->visible = visible;
GET_PRIVATE (filter)->active = active;
g_signal_emit (filter, gimp_filter_signals[VISIBILITY_CHANGED], 0);
g_signal_emit (filter, gimp_filter_signals[ACTIVE_CHANGED], 0);
g_object_notify (G_OBJECT (filter), "visible");
g_object_notify (G_OBJECT (filter), "active");
}
}
gboolean
gimp_filter_get_visible (GimpFilter *filter)
gimp_filter_get_active (GimpFilter *filter)
{
g_return_val_if_fail (GIMP_IS_FILTER (filter), FALSE);
return GET_PRIVATE (filter)->visible;
}
gboolean
gimp_filter_is_visible (GimpFilter *filter)
{
g_return_val_if_fail (GIMP_IS_FILTER (filter), FALSE);
if (gimp_filter_get_visible (filter))
{
GimpFilter *parent;
parent = GIMP_FILTER (gimp_viewable_get_parent (GIMP_VIEWABLE (filter)));
if (parent)
return gimp_filter_is_visible (parent);
return TRUE;
}
return FALSE;
return GET_PRIVATE (filter)->active;
}
void
......
......@@ -44,10 +44,10 @@ struct _GimpFilterClass
GimpViewableClass parent_class;
/* signals */
void (* visibility_changed) (GimpFilter *filter);
void (* active_changed) (GimpFilter *filter);
/* virtual functions */
GeglNode * (* get_node) (GimpFilter *filter);
GeglNode * (* get_node) (GimpFilter *filter);
};
......@@ -57,10 +57,10 @@ GimpFilter * gimp_filter_new (const gchar *name);
GeglNode * gimp_filter_get_node (GimpFilter *filter);
GeglNode * gimp_filter_peek_node (GimpFilter *filter);
void gimp_filter_set_visible (GimpFilter *filter,
gboolean visible);
gboolean gimp_filter_get_visible (GimpFilter *filter);
gboolean gimp_filter_is_visible (GimpFilter *filter);
void gimp_filter_set_active (GimpFilter *filter,
gboolean active);
gboolean gimp_filter_get_active (GimpFilter *filter);
gboolean gimp_filter_is_active (GimpFilter *filter);
void gimp_filter_set_is_last_node (GimpFilter *filter,
gboolean is_last_node);
......
......@@ -48,7 +48,7 @@ static void gimp_filter_stack_remove_node (GimpFilterStack *stack,
GimpFilter *filter);
static void gimp_filter_stack_update_last_node (GimpFilterStack *stack);
static void gimp_filter_stack_filter_visible (GimpFilter *filter,
static void gimp_filter_stack_filter_active (GimpFilter *filter,
GimpFilterStack *stack);
......@@ -86,8 +86,8 @@ gimp_filter_stack_constructed (GObject *object)
g_assert (g_type_is_a (gimp_container_get_children_type (container),
GIMP_TYPE_FILTER));
gimp_container_add_handler (container, "visibility-changed",
G_CALLBACK (gimp_filter_stack_filter_visible),
gimp_container_add_handler (container, "active-changed",
G_CALLBACK (gimp_filter_stack_filter_active),
container);
}
......@@ -110,7 +110,7 @@ gimp_filter_stack_add (GimpContainer *container,
GIMP_CONTAINER_CLASS (parent_class)->add (container, object);
if (gimp_filter_get_visible (filter))
if (gimp_filter_get_active (filter))
{
if (stack->graph)
{
......@@ -129,7 +129,7 @@ gimp_filter_stack_remove (GimpContainer *container,
GimpFilterStack *stack = GIMP_FILTER_STACK (container);
GimpFilter *filter = GIMP_FILTER (object);
if (stack->graph && gimp_filter_get_visible (filter))
if (stack->graph && gimp_filter_get_active (filter))
{
gimp_filter_stack_remove_node (stack, filter);
gegl_node_remove_child (stack->graph, gimp_filter_get_node (filter));
......@@ -137,7 +137,7 @@ gimp_filter_stack_remove (GimpContainer *container,
GIMP_CONTAINER_CLASS (parent_class)->remove (container, object);
if (gimp_filter_get_visible (filter))
if (gimp_filter_get_active (filter))
{
gimp_filter_set_is_last_node (filter, FALSE);
gimp_filter_stack_update_last_node (stack);
......@@ -152,12 +152,12 @@ gimp_filter_stack_reorder (GimpContainer *container,
GimpFilterStack *stack = GIMP_FILTER_STACK (container);
GimpFilter *filter = GIMP_FILTER (object);
if (stack->graph && gimp_filter_get_visible (filter))
if (stack->graph && gimp_filter_get_active (filter))
gimp_filter_stack_remove_node (stack, filter);
GIMP_CONTAINER_CLASS (parent_class)->reorder (container, object, new_index);
if (gimp_filter_get_visible (filter))
if (gimp_filter_get_active (filter))
{
gimp_filter_stack_update_last_node (stack);
......@@ -204,7 +204,7 @@ gimp_filter_stack_get_graph (GimpFilterStack *stack)
GimpFilter *filter = list->data;
GeglNode *node;
if (! gimp_filter_get_visible (filter))
if (! gimp_filter_get_active (filter))
continue;
node = gimp_filter_get_node (filter);
......@@ -246,7 +246,7 @@ gimp_filter_stack_add_node (GimpFilterStack *stack,
{
GimpFilter *filter_above = iter->data;
if (gimp_filter_get_visible (filter_above))
if (gimp_filter_get_active (filter_above))
{
node_above = gimp_filter_get_node (filter_above);
......@@ -282,7 +282,7 @@ gimp_filter_stack_remove_node (GimpFilterStack *stack,
{
GimpFilter *filter_above = iter->data;
if (gimp_filter_get_visible (filter_above))
if (gimp_filter_get_active (filter_above))
{
node_above = gimp_filter_get_node (filter_above);
......@@ -313,7 +313,7 @@ gimp_filter_stack_update_last_node (GimpFilterStack *stack)
{
GimpFilter *filter = list->data;
if (! found_last && gimp_filter_get_visible (filter))
if (! found_last && gimp_filter_get_active (filter))
{
gimp_filter_set_is_last_node (filter, TRUE);
found_last = TRUE;
......@@ -326,12 +326,12 @@ gimp_filter_stack_update_last_node (GimpFilterStack *stack)
}
static void
gimp_filter_stack_filter_visible (GimpFilter *filter,
GimpFilterStack *stack)
gimp_filter_stack_filter_active (GimpFilter *filter,
GimpFilterStack *stack)
{
if (stack->graph)
{
if (gimp_filter_get_visible (filter))
if (gimp_filter_get_active (filter))
{
gegl_node_add_child (stack->graph, gimp_filter_get_node (filter));
gimp_filter_stack_add_node (stack, filter);
......@@ -345,6 +345,6 @@ gimp_filter_stack_filter_visible (GimpFilter *filter,
gimp_filter_stack_update_last_node (stack);
if (! gimp_filter_get_visible (filter))
if (! gimp_filter_get_active (filter))
gimp_filter_set_is_last_node (filter, FALSE);
}
......@@ -178,8 +178,7 @@ static void gimp_group_layer_child_move (GimpLayer *child,
GimpGroupLayer *group);
static void gimp_group_layer_child_resize (GimpLayer *child,
GimpGroupLayer *group);
static void
gimp_group_layer_child_visibility_changed (GimpLayer *child,
static void gimp_group_layer_child_active_changed (GimpLayer *child,
GimpGroupLayer *group);
static void
gimp_group_layer_child_excludes_backdrop_changed (GimpLayer *child,
......@@ -312,8 +311,8 @@ gimp_group_layer_init (GimpGroupLayer *group)
gimp_container_add_handler (private->children, "size-changed",
G_CALLBACK (gimp_group_layer_child_resize),
group);
gimp_container_add_handler (private->children, "visibility-changed",
G_CALLBACK (gimp_group_layer_child_visibility_changed),
gimp_container_add_handler (private->children, "active-changed",
G_CALLBACK (gimp_group_layer_child_active_changed),
group);
gimp_container_add_handler (private->children, "excludes-backdrop-changed",
G_CALLBACK (gimp_group_layer_child_excludes_backdrop_changed),
......@@ -1017,9 +1016,9 @@ gimp_group_layer_get_excludes_backdrop (GimpLayer *layer)
list;
list = g_list_next (list))
{
GimpItem *child = list->data;
GimpFilter *child = list->data;
if (gimp_item_get_visible (child) &&
if (gimp_filter_get_active (child) &&
gimp_layer_get_excludes_backdrop (GIMP_LAYER (child)))
return TRUE;
}
......@@ -1221,7 +1220,7 @@ gimp_group_layer_child_add (GimpContainer *container,
{
gimp_group_layer_update (group);
if (gimp_item_get_visible (GIMP_ITEM (child)) &&
if (gimp_filter_get_active (GIMP_FILTER (child)) &&
gimp_layer_get_excludes_backdrop (child))
{
gimp_layer_update_excludes_backdrop (GIMP_LAYER (group));
......@@ -1235,7 +1234,7 @@ gimp_group_layer_child_remove (GimpContainer *container,
{
gimp_group_layer_update (group);
if (gimp_item_get_visible (GIMP_ITEM (child)) &&
if (gimp_filter_get_active (GIMP_FILTER (child)) &&
gimp_layer_get_excludes_backdrop (child))
{
gimp_layer_update_excludes_backdrop (GIMP_LAYER (group));
......@@ -1258,8 +1257,8 @@ gimp_group_layer_child_resize (GimpLayer *child,
}
static void
gimp_group_layer_child_visibility_changed (GimpLayer *child,
GimpGroupLayer *group)
gimp_group_layer_child_active_changed (GimpLayer *child,
GimpGroupLayer *group)
{
if (gimp_layer_get_excludes_backdrop (child))
gimp_layer_update_excludes_backdrop (GIMP_LAYER (group));
......@@ -1269,7 +1268,7 @@ static void
gimp_group_layer_child_excludes_backdrop_changed (GimpLayer *child,
GimpGroupLayer *group)
{
if (gimp_item_get_visible (GIMP_ITEM (child)))
if (gimp_filter_get_active (GIMP_FILTER (child)))
gimp_layer_update_excludes_backdrop (GIMP_LAYER (group));
}
......
......@@ -53,6 +53,7 @@
enum
{
REMOVED,
VISIBILITY_CHANGED,
LINKED_CHANGED,
COLOR_TAG_CHANGED,
LOCK_CONTENT_CHANGED,
......@@ -69,6 +70,7 @@ enum
PROP_HEIGHT,
PROP_OFFSET_X,
PROP_OFFSET_Y,
PROP_VISIBLE,
PROP_LINKED,
PROP_COLOR_TAG,
PROP_LOCK_CONTENT,
......@@ -80,25 +82,28 @@ typedef struct _GimpItemPrivate GimpItemPrivate;
struct _GimpItemPrivate
{
gint ID; /* provides a unique ID */
guint32 tattoo; /* provides a permanent ID */
gint ID; /* provides a unique ID */
guint32 tattoo; /* provides a permanent ID */
GimpImage *image; /* item owner */
GimpImage *image; /* item owner */
GimpParasiteList *parasites; /* Plug-in parasite data */
GimpParasiteList *parasites; /* Plug-in parasite data */
gint width, height; /* size in pixels */
gint offset_x, offset_y; /* pixel offset in image */
gint width, height; /* size in pixels */
gint offset_x, offset_y; /* pixel offset in image */
guint linked : 1; /* control linkage */
guint lock_content : 1; /* content editability */
guint lock_position : 1; /* content movability */
guint visible : 1; /* item visibility */
guint bind_visible_to_active : 1; /* visibility bound to active */
guint removed : 1; /* removed from the image? */
guint linked : 1; /* control linkage */
guint lock_content : 1; /* content editability */
guint lock_position : 1; /* content movability */
GimpColorTag color_tag; /* color tag */
guint removed : 1; /* removed from the image? */
GList *offset_nodes; /* offset nodes to manage */
GimpColorTag color_tag; /* color tag */
GList *offset_nodes; /* offset nodes to manage */
};
#define GET_PRIVATE(item) G_TYPE_INSTANCE_GET_PRIVATE (item, \
......@@ -182,6 +187,15 @@ gimp_item_class_init (GimpItemClass *klass)
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_item_signals[VISIBILITY_CHANGED] =
g_signal_new ("visibility-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpItemClass, visibility_changed),
NULL, NULL,
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_item_signals[LINKED_CHANGED] =
g_signal_new ("linked-changed",
G_TYPE_FROM_CLASS (klass),
......@@ -230,6 +244,7 @@ gimp_item_class_init (GimpItemClass *klass)
viewable_class->get_popup_size = gimp_item_get_popup_size;
klass->removed = NULL;
klass->visibility_changed = NULL;
klass->linked_changed = NULL;
klass->color_tag_changed = NULL;
klass->lock_content_changed = NULL;
......@@ -297,6 +312,11 @@ gimp_item_class_init (GimpItemClass *klass)
GIMP_MAX_IMAGE_SIZE, 0,
GIMP_PARAM_READABLE));
g_object_class_install_property (object_class, PROP_VISIBLE,
g_param_spec_boolean ("visible", NULL, NULL,
TRUE,
GIMP_PARAM_READABLE));
g_object_class_install_property (object_class, PROP_LINKED,
g_param_spec_boolean ("linked", NULL, NULL,
FALSE,
......@@ -330,7 +350,9 @@ gimp_item_init (GimpItem *item)
g_object_force_floating (G_OBJECT (item));
private->parasites = gimp_parasite_list_new ();
private->parasites = gimp_parasite_list_new ();
private->visible = TRUE;
private->bind_visible_to_active = TRUE;
}
static void
......@@ -415,6 +437,9 @@ gimp_item_get_property (GObject *object,
case PROP_OFFSET_Y:
g_value_set_int (value, private->offset_y);
break;
case PROP_VISIBLE:
g_value_set_boolean (value, private->visible);
break;
case PROP_LINKED:
g_value_set_boolean (value, private->linked);
break;
......@@ -2059,7 +2084,14 @@ gimp_item_set_visible (GimpItem *item,
gimp_image_undo_push_item_visibility (image, NULL, item);
}
gimp_filter_set_visible (GIMP_FILTER (item), visible);
GET_PRIVATE (item)->visible = visible;
if (GET_PRIVATE (item)->bind_visible_to_active)
gimp_filter_set_active (GIMP_FILTER (item), visible);
g_signal_emit (item, gimp_item_signals[VISIBILITY_CHANGED], 0);
g_object_notify (G_OBJECT (item), "visible");
}
}
......@@ -2068,7 +2100,7 @@ gimp_item_get_visible (GimpItem *item)
{
g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
return gimp_filter_get_visible (GIMP_FILTER (item));
return GET_PRIVATE (item)->visible;
}
gboolean
......@@ -2076,7 +2108,31 @@ gimp_item_is_visible (GimpItem *item)
{
g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
return gimp_filter_is_visible (GIMP_FILTER (item));
if (gimp_item_get_visible (item))
{
GimpItem *parent;
parent = GIMP_ITEM (gimp_viewable_get_parent (GIMP_VIEWABLE (item)));
if (parent)
return gimp_item_is_visible (parent);
return TRUE;
}
return FALSE;
}
void
gimp_item_bind_visible_to_active (GimpItem *item,
gboolean bind)
{
g_return_if_fail (GIMP_IS_ITEM (item));
GET_PRIVATE (item)->bind_visible_to_active = bind;
if (bind)
gimp_filter_set_active (GIMP_FILTER (item), gimp_item_get_visible (item));
}
void
......
......@@ -43,6 +43,7 @@ struct _GimpItemClass
/* signals */
void (* removed) (GimpItem *item);
void (* visibility_changed) (GimpItem *item);
void (* linked_changed) (GimpItem *item);
void (* color_tag_changed) (GimpItem *item);
void (* lock_content_changed) (GimpItem *item);
......@@ -326,6 +327,9 @@ void gimp_item_set_visible (GimpItem *item,
gboolean gimp_item_get_visible (GimpItem *item);
gboolean gimp_item_is_visible (GimpItem *item);
void gimp_item_bind_visible_to_active (GimpItem *item,
gboolean bind);
void gimp_item_set_linked (GimpItem *item,
gboolean linked,
gboolean push_undo);
......
......@@ -41,14 +41,14 @@ static void gimp_layer_stack_reorder (GimpContainer *container
GimpObject *object,
gint new_index);