Add "active-item" property and API to GimpItemTree

and use it to store the image's active layer, channel and vectors.
This commit is contained in:
Michael Natterer 2010-02-07 14:52:34 +01:00
parent 78375e0ec5
commit c9645cc0d3
4 changed files with 110 additions and 51 deletions

View File

@ -78,10 +78,6 @@ struct _GimpImagePrivate
GQuark channel_name_changed_handler; GQuark channel_name_changed_handler;
GQuark channel_color_changed_handler; GQuark channel_color_changed_handler;
GimpLayer *active_layer; /* the active layer */
GimpChannel *active_channel; /* the active channel */
GimpVectors *active_vectors; /* the active vectors */
GimpLayer *floating_sel; /* the FS layer */ GimpLayer *floating_sel; /* the FS layer */
GimpChannel *selection_mask; /* the selection mask channel */ GimpChannel *selection_mask; /* the selection mask channel */

View File

@ -659,10 +659,6 @@ gimp_image_init (GimpImage *image)
G_CALLBACK (gimp_image_channel_remove), G_CALLBACK (gimp_image_channel_remove),
image); image);
private->active_layer = NULL;
private->active_channel = NULL;
private->active_vectors = NULL;
private->floating_sel = NULL; private->floating_sel = NULL;
private->selection_mask = NULL; private->selection_mask = NULL;
@ -2985,21 +2981,26 @@ GimpDrawable *
gimp_image_get_active_drawable (const GimpImage *image) gimp_image_get_active_drawable (const GimpImage *image)
{ {
GimpImagePrivate *private; GimpImagePrivate *private;
GimpItem *active_channel;
GimpItem *active_layer;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
private = GIMP_IMAGE_GET_PRIVATE (image); private = GIMP_IMAGE_GET_PRIVATE (image);
active_channel = gimp_item_tree_get_active_item (private->channels);
active_layer = gimp_item_tree_get_active_item (private->layers);
/* If there is an active channel (a saved selection, etc.), /* If there is an active channel (a saved selection, etc.),
* we ignore the active layer * we ignore the active layer
*/ */
if (private->active_channel) if (active_channel)
{ {
return GIMP_DRAWABLE (private->active_channel); return GIMP_DRAWABLE (active_channel);
} }
else if (private->active_layer) else if (active_layer)
{ {
GimpLayer *layer = private->active_layer; GimpLayer *layer = GIMP_LAYER (active_layer);
GimpLayerMask *mask = gimp_layer_get_mask (layer); GimpLayerMask *mask = gimp_layer_get_mask (layer);
if (mask && gimp_layer_mask_get_edit (mask)) if (mask && gimp_layer_mask_get_edit (mask))
@ -3016,7 +3017,7 @@ gimp_image_get_active_layer (const GimpImage *image)
{ {
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
return GIMP_IMAGE_GET_PRIVATE (image)->active_layer; return GIMP_LAYER (gimp_item_tree_get_active_item (GIMP_IMAGE_GET_PRIVATE (image)->layers));
} }
GimpChannel * GimpChannel *
@ -3024,7 +3025,7 @@ gimp_image_get_active_channel (const GimpImage *image)
{ {
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
return GIMP_IMAGE_GET_PRIVATE (image)->active_channel; return GIMP_CHANNEL (gimp_item_tree_get_active_item (GIMP_IMAGE_GET_PRIVATE (image)->channels));
} }
GimpVectors * GimpVectors *
@ -3032,7 +3033,7 @@ gimp_image_get_active_vectors (const GimpImage *image)
{ {
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
return GIMP_IMAGE_GET_PRIVATE (image)->active_vectors; return GIMP_VECTORS (gimp_item_tree_get_active_item (GIMP_IMAGE_GET_PRIVATE (image)->vectors));
} }
GimpLayer * GimpLayer *
@ -3041,6 +3042,7 @@ gimp_image_set_active_layer (GimpImage *image,
{ {
GimpImagePrivate *private; GimpImagePrivate *private;
GimpLayer *floating_sel; GimpLayer *floating_sel;
GimpLayer *active_layer;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (layer == NULL || GIMP_IS_LAYER (layer), NULL); g_return_val_if_fail (layer == NULL || GIMP_IS_LAYER (layer), NULL);
@ -3057,7 +3059,9 @@ gimp_image_set_active_layer (GimpImage *image,
if (floating_sel && layer != floating_sel) if (floating_sel && layer != floating_sel)
return floating_sel; return floating_sel;
if (layer != private->active_layer) active_layer = gimp_image_get_active_layer (image);
if (layer != active_layer)
{ {
if (layer) if (layer)
{ {
@ -3067,18 +3071,18 @@ gimp_image_set_active_layer (GimpImage *image,
} }
/* Don't cache selection info for the previous active layer */ /* Don't cache selection info for the previous active layer */
if (private->active_layer) if (active_layer)
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (private->active_layer)); gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (active_layer));
private->active_layer = layer; gimp_item_tree_set_active_item (private->layers, GIMP_ITEM (layer));
g_signal_emit (image, gimp_image_signals[ACTIVE_LAYER_CHANGED], 0); g_signal_emit (image, gimp_image_signals[ACTIVE_LAYER_CHANGED], 0);
if (layer && private->active_channel) if (layer && gimp_image_get_active_channel (image))
gimp_image_set_active_channel (image, NULL); gimp_image_set_active_channel (image, NULL);
} }
return private->active_layer; return gimp_image_get_active_layer (image);
} }
GimpChannel * GimpChannel *
@ -3086,6 +3090,7 @@ gimp_image_set_active_channel (GimpImage *image,
GimpChannel *channel) GimpChannel *channel)
{ {
GimpImagePrivate *private; GimpImagePrivate *private;
GimpChannel *active_channel;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (channel == NULL || GIMP_IS_CHANNEL (channel), NULL); g_return_val_if_fail (channel == NULL || GIMP_IS_CHANNEL (channel), NULL);
@ -3100,17 +3105,19 @@ gimp_image_set_active_channel (GimpImage *image,
if (channel && gimp_image_get_floating_selection (image)) if (channel && gimp_image_get_floating_selection (image))
return NULL; return NULL;
if (channel != private->active_channel) active_channel = gimp_image_get_active_channel (image);
if (channel != active_channel)
{ {
private->active_channel = channel; gimp_item_tree_set_active_item (private->channels, GIMP_ITEM (channel));
g_signal_emit (image, gimp_image_signals[ACTIVE_CHANNEL_CHANGED], 0); g_signal_emit (image, gimp_image_signals[ACTIVE_CHANNEL_CHANGED], 0);
if (channel && private->active_layer) if (channel && gimp_image_get_active_layer (image))
gimp_image_set_active_layer (image, NULL); gimp_image_set_active_layer (image, NULL);
} }
return private->active_channel; return gimp_image_get_active_channel (image);
} }
GimpChannel * GimpChannel *
@ -3122,6 +3129,7 @@ gimp_image_unset_active_channel (GimpImage *image)
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
private = GIMP_IMAGE_GET_PRIVATE (image); private = GIMP_IMAGE_GET_PRIVATE (image);
channel = gimp_image_get_active_channel (image); channel = gimp_image_get_active_channel (image);
if (channel) if (channel)
@ -3140,6 +3148,7 @@ gimp_image_set_active_vectors (GimpImage *image,
GimpVectors *vectors) GimpVectors *vectors)
{ {
GimpImagePrivate *private; GimpImagePrivate *private;
GimpVectors *active_vectors;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors), NULL); g_return_val_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors), NULL);
@ -3150,14 +3159,16 @@ gimp_image_set_active_vectors (GimpImage *image,
private = GIMP_IMAGE_GET_PRIVATE (image); private = GIMP_IMAGE_GET_PRIVATE (image);
if (vectors != private->active_vectors) active_vectors = gimp_image_get_active_vectors (image);
if (vectors != active_vectors)
{ {
private->active_vectors = vectors; gimp_item_tree_set_active_item (private->vectors, GIMP_ITEM (vectors));
g_signal_emit (image, gimp_image_signals[ACTIVE_VECTORS_CHANGED], 0); g_signal_emit (image, gimp_image_signals[ACTIVE_VECTORS_CHANGED], 0);
} }
return private->active_vectors; return gimp_image_get_active_vectors (image);
} }
GimpLayer * GimpLayer *

View File

@ -38,7 +38,8 @@ enum
PROP_0, PROP_0,
PROP_IMAGE, PROP_IMAGE,
PROP_CONTAINER_TYPE, PROP_CONTAINER_TYPE,
PROP_ITEM_TYPE PROP_ITEM_TYPE,
PROP_ACTIVE_ITEM
}; };
@ -47,8 +48,11 @@ typedef struct _GimpItemTreePrivate GimpItemTreePrivate;
struct _GimpItemTreePrivate struct _GimpItemTreePrivate
{ {
GimpImage *image; GimpImage *image;
GType container_type; GType container_type;
GType item_type; GType item_type;
GimpItem *active_item;
}; };
#define GIMP_ITEM_TREE_GET_PRIVATE(object) \ #define GIMP_ITEM_TREE_GET_PRIVATE(object) \
@ -115,6 +119,12 @@ gimp_item_tree_class_init (GimpItemTreeClass *klass)
GIMP_PARAM_READWRITE | GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY)); G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_ACTIVE_ITEM,
g_param_spec_object ("active-item",
NULL, NULL,
GIMP_TYPE_ITEM,
GIMP_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (GimpItemTreePrivate)); g_type_class_add_private (klass, sizeof (GimpItemTreePrivate));
} }
@ -185,6 +195,9 @@ gimp_item_tree_set_property (GObject *object,
case PROP_ITEM_TYPE: case PROP_ITEM_TYPE:
private->item_type = g_value_get_gtype (value); private->item_type = g_value_get_gtype (value);
break; break;
case PROP_ACTIVE_ITEM:
private->active_item = g_value_get_object (value); /* don't ref */
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -211,6 +224,9 @@ gimp_item_tree_get_property (GObject *object,
case PROP_ITEM_TYPE: case PROP_ITEM_TYPE:
g_value_set_gtype (value, private->item_type); g_value_set_gtype (value, private->item_type);
break; break;
case PROP_ACTIVE_ITEM:
g_value_set_object (value, private->active_item);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -250,6 +266,37 @@ gimp_item_tree_new (GimpImage *image,
NULL); NULL);
} }
GimpItem *
gimp_item_tree_get_active_item (GimpItemTree *tree)
{
g_return_val_if_fail (GIMP_IS_ITEM_TREE (tree), NULL);
return GIMP_ITEM_TREE_GET_PRIVATE (tree)->active_item;
}
void
gimp_item_tree_set_active_item (GimpItemTree *tree,
GimpItem *item)
{
GimpItemTreePrivate *private;
g_return_if_fail (GIMP_IS_ITEM_TREE (tree));
g_return_if_fail (item == NULL || GIMP_IS_ITEM (item));
private = GIMP_ITEM_TREE_GET_PRIVATE (tree);
g_return_if_fail (item == NULL ||
(gimp_item_is_attached (item) &&
gimp_item_get_image (item) == private->image));
if (item != private->active_item)
{
private->active_item = item;
g_object_notify (G_OBJECT (tree), "active-item");
}
}
GimpItem * GimpItem *
gimp_item_tree_get_insert_pos (GimpItemTree *tree, gimp_item_tree_get_insert_pos (GimpItemTree *tree,
GimpItem *parent, GimpItem *parent,

View File

@ -47,30 +47,35 @@ struct _GimpItemTreeClass
}; };
GType gimp_item_tree_get_type (void) G_GNUC_CONST; GType gimp_item_tree_get_type (void) G_GNUC_CONST;
GimpItemTree * gimp_item_tree_new (GimpImage *image, GimpItemTree * gimp_item_tree_new (GimpImage *image,
GType container_type, GType container_type,
GType item_type); GType item_type);
GimpItem * gimp_item_tree_get_insert_pos (GimpItemTree *tree, GimpItem * gimp_item_tree_get_active_item (GimpItemTree *tree);
GimpItem *parent, void gimp_item_tree_set_active_item (GimpItemTree *tree,
gint *position, GimpItem *item);
GimpItem *active_item);
void gimp_item_tree_add_item (GimpItemTree *tree, GimpItem * gimp_item_tree_get_insert_pos (GimpItemTree *tree,
GimpItem *item, GimpItem *parent,
GimpItem *parent, gint *position,
gint position); GimpItem *active_item);
GimpItem * gimp_item_tree_remove_item (GimpItemTree *tree,
GimpItem *item, void gimp_item_tree_add_item (GimpItemTree *tree,
GimpItem *current_active, GimpItem *item,
GimpItem *new_active); GimpItem *parent,
gint position);
GimpItem * gimp_item_tree_remove_item (GimpItemTree *tree,
GimpItem *item,
GimpItem *current_active,
GimpItem *new_active);
gboolean gimp_item_tree_reorder_item (GimpItemTree *tree,
GimpItem *item,
GimpItem *new_parent,
gint new_index,
gboolean push_undo,
const gchar *undo_desc);
gboolean gimp_item_tree_reorder_item (GimpItemTree *tree,
GimpItem *item,
GimpItem *new_parent,
gint new_index,
gboolean push_undo,
const gchar *undo_desc);
#endif /* __GIMP_ITEM_TREE_H__ */ #endif /* __GIMP_ITEM_TREE_H__ */