Bug 675747 - Layers with some modes get hidden in layer groups

Add a boolean "is-last-node" property to GimpDrawable and set it from
GimpDrawableStack, which is the place that easily has the information.
In GimpLayer, connect to "notify" and make sure we use NORMAL mode
unless the layer is in NORMAL or DISSOLVE mode.
This commit is contained in:
Michael Natterer 2012-11-12 10:55:41 +01:00
parent 3ef2baea67
commit c914aa805d
5 changed files with 150 additions and 7 deletions

View File

@ -32,6 +32,8 @@ struct _GimpDrawablePrivate
GeglNode *fs_mode_node;
GeglNode *mode_node;
gboolean is_last_node;
};
#endif /* __GIMP_DRAWABLE_PRIVATE_H__ */

View File

@ -61,6 +61,12 @@ enum
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_IS_LAST_NODE
};
/* local function prototypes */
@ -68,6 +74,14 @@ static void gimp_drawable_pickable_iface_init (GimpPickableInterface *iface);
static void gimp_drawable_dispose (GObject *object);
static void gimp_drawable_finalize (GObject *object);
static void gimp_drawable_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_drawable_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gint64 gimp_drawable_get_memsize (GimpObject *object,
gint64 *gui_size);
@ -212,6 +226,8 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
object_class->dispose = gimp_drawable_dispose;
object_class->finalize = gimp_drawable_finalize;
object_class->set_property = gimp_drawable_set_property;
object_class->get_property = gimp_drawable_get_property;
gimp_object_class->get_memsize = gimp_drawable_get_memsize;
@ -242,6 +258,12 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
klass->push_undo = gimp_drawable_real_push_undo;
klass->swap_pixels = gimp_drawable_real_swap_pixels;
g_object_class_install_property (object_class, PROP_IS_LAST_NODE,
g_param_spec_boolean ("is-last-node",
NULL, NULL,
FALSE,
GIMP_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (GimpDrawablePrivate));
}
@ -298,6 +320,46 @@ gimp_drawable_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_drawable_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpDrawable *drawable = GIMP_DRAWABLE (object);
switch (property_id)
{
case PROP_IS_LAST_NODE:
drawable->private->is_last_node = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_drawable_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpDrawable *drawable = GIMP_DRAWABLE (object);
switch (property_id)
{
case PROP_IS_LAST_NODE:
g_value_set_boolean (value, drawable->private->is_last_node);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gint64
gimp_drawable_get_memsize (GimpObject *object,
gint64 *gui_size)
@ -1318,6 +1380,28 @@ gimp_drawable_get_mode_node (GimpDrawable *drawable)
return drawable->private->mode_node;
}
void
gimp_drawable_set_is_last_node (GimpDrawable *drawable,
gboolean last_node)
{
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
if (last_node != drawable->private->is_last_node)
{
g_object_set (drawable,
"is-last-node", last_node ? TRUE : FALSE,
NULL);
}
}
gboolean
gimp_drawable_get_is_last_node (GimpDrawable *drawable)
{
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
return drawable->private->is_last_node;
}
void
gimp_drawable_swap_pixels (GimpDrawable *drawable,
GeglBuffer *buffer,

View File

@ -180,6 +180,10 @@ void gimp_drawable_set_buffer_full (GimpDrawable *drawable,
GeglNode * gimp_drawable_get_source_node (GimpDrawable *drawable);
GeglNode * gimp_drawable_get_mode_node (GimpDrawable *drawable);
void gimp_drawable_set_is_last_node (GimpDrawable *drawable,
gboolean last_node);
gboolean gimp_drawable_get_is_last_node (GimpDrawable *drawable);
void gimp_drawable_swap_pixels (GimpDrawable *drawable,
GeglBuffer *buffer,
gint x,

View File

@ -235,6 +235,9 @@ gimp_drawable_stack_get_graph (GimpDrawableStack *stack)
GimpDrawable *drawable = list->data;
reverse_list = g_list_prepend (reverse_list, drawable);
if (! g_list_next (list))
gimp_drawable_set_is_last_node (drawable, TRUE);
}
stack->graph = gegl_node_new ();
@ -271,6 +274,7 @@ static void
gimp_drawable_stack_add_node (GimpDrawableStack *stack,
GimpDrawable *drawable)
{
GimpDrawable *drawable_above = NULL;
GimpDrawable *drawable_below;
GeglNode *node_above;
GeglNode *node;
@ -287,8 +291,6 @@ gimp_drawable_stack_add_node (GimpDrawableStack *stack,
}
else
{
GimpDrawable *drawable_above;
drawable_above = (GimpDrawable *)
gimp_container_get_child_by_index (GIMP_CONTAINER (stack), index - 1);
@ -308,12 +310,20 @@ gimp_drawable_stack_add_node (GimpDrawableStack *stack,
gegl_node_connect_to (node_below, "output",
node, "input");
}
else
{
if (drawable_above)
gimp_drawable_set_is_last_node (drawable_above, FALSE);
gimp_drawable_set_is_last_node (drawable, TRUE);
}
}
static void
gimp_drawable_stack_remove_node (GimpDrawableStack *stack,
GimpDrawable *drawable)
{
GimpDrawable *drawable_above = NULL;
GimpDrawable *drawable_below;
GeglNode *node_above;
GeglNode *node;
@ -330,8 +340,6 @@ gimp_drawable_stack_remove_node (GimpDrawableStack *stack,
}
else
{
GimpDrawable *drawable_above;
drawable_above = (GimpDrawable *)
gimp_container_get_child_by_index (GIMP_CONTAINER (stack), index - 1);
@ -352,6 +360,11 @@ gimp_drawable_stack_remove_node (GimpDrawableStack *stack,
else
{
gegl_node_disconnect (node_above, "input");
gimp_drawable_set_is_last_node (drawable, FALSE);
if (drawable_above)
gimp_drawable_set_is_last_node (drawable_above, TRUE);
}
}

View File

@ -85,6 +85,8 @@ static void gimp_layer_get_property (GObject *object,
GParamSpec *pspec);
static void gimp_layer_dispose (GObject *object);
static void gimp_layer_finalize (GObject *object);
static void gimp_layer_notify (GObject *object,
GParamSpec *pspec);
static void gimp_layer_name_changed (GimpObject *object);
static gint64 gimp_layer_get_memsize (GimpObject *object,
@ -264,6 +266,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
object_class->get_property = gimp_layer_get_property;
object_class->dispose = gimp_layer_dispose;
object_class->finalize = gimp_layer_finalize;
object_class->notify = gimp_layer_notify;
gimp_object_class->name_changed = gimp_layer_name_changed;
gimp_object_class->get_memsize = gimp_layer_get_memsize;
@ -466,6 +469,39 @@ gimp_layer_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GimpLayerModeEffects
gimp_layer_get_visible_mode (GimpLayer *layer)
{
if (layer->mode != GIMP_DISSOLVE_MODE &&
gimp_drawable_get_is_last_node (GIMP_DRAWABLE (layer)))
return GIMP_NORMAL_MODE;
return layer->mode;
}
static void
gimp_layer_notify (GObject *object,
GParamSpec *pspec)
{
if (! strcmp (pspec->name, "is-last-node") &&
gimp_item_peek_node (GIMP_ITEM (object)))
{
GimpLayer *layer = GIMP_LAYER (object);
GeglNode *mode_node;
mode_node = gimp_drawable_get_mode_node (GIMP_DRAWABLE (layer));
gimp_gegl_mode_node_set (mode_node,
gimp_layer_get_visible_mode (layer),
layer->opacity, FALSE);
gimp_drawable_update (GIMP_DRAWABLE (layer),
0, 0,
gimp_item_get_width (GIMP_ITEM (layer)),
gimp_item_get_height (GIMP_ITEM (layer)));
}
}
static void
gimp_layer_name_changed (GimpObject *object)
{
@ -880,7 +916,9 @@ gimp_layer_get_node (GimpItem *item)
*/
mode_node = gimp_drawable_get_mode_node (drawable);
gimp_gegl_mode_node_set (mode_node, layer->mode, layer->opacity, FALSE);
gimp_gegl_mode_node_set (mode_node,
gimp_layer_get_visible_mode (layer),
layer->opacity, FALSE);
/* the layer's offset node */
layer->layer_offset_node = gegl_node_new_child (node,
@ -1944,7 +1982,8 @@ gimp_layer_set_opacity (GimpLayer *layer,
mode_node = gimp_drawable_get_mode_node (GIMP_DRAWABLE (layer));
gimp_gegl_mode_node_set (mode_node,
layer->mode, layer->opacity, FALSE);
gimp_layer_get_visible_mode (layer),
layer->opacity, FALSE);
}
gimp_drawable_update (GIMP_DRAWABLE (layer),
@ -1990,7 +2029,8 @@ gimp_layer_set_mode (GimpLayer *layer,
mode_node = gimp_drawable_get_mode_node (GIMP_DRAWABLE (layer));
gimp_gegl_mode_node_set (mode_node,
layer->mode, layer->opacity, FALSE);
gimp_layer_get_visible_mode (layer),
layer->opacity, FALSE);
}
gimp_drawable_update (GIMP_DRAWABLE (layer),