gimp r27961 - in trunk: . app/core
- From: mitch svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r27961 - in trunk: . app/core
- Date: Mon, 26 Jan 2009 22:05:07 +0000 (UTC)
Author: mitch
Date: Mon Jan 26 22:05:07 2009
New Revision: 27961
URL: http://svn.gnome.org/viewvc/gimp?rev=27961&view=rev
Log:
2009-01-26 Michael Natterer <mitch gimp org>
The GEGL projection does floating selections now:
* app/core/gimpdrawable.[ch] (struct GimpDrawable): add a couple
of GeglNodes which are used to create a sub-graph for this
drawable's floating selection.
(gimp_drawable_detach_floating_sel)
(gimp_drawable_attach_floating_sel): new functions to call
whenever a floating selection gets attached or detached.
Change the role of the drawable's "source_node": it's no longer a
direct tile source but an arbitrary graph. Add new internal
function gimp_drawable_sync_source_node() which creates a
sub-graph for the floating selection within the source node, and
uses the new "tile_source_node" directly otherwise. Connect to
"notify" of the floating selection and reconfigure its sub-graph
when its properties change. This is also one more refactoring in
the direction of layer trees.
* app/core/gimpfloatingselundo.c
* app/core/gimpimage.c
* app/core/gimplayer-floating-sel.c: call the new attach/detach
API whenever a floating selection is attached or detached from a
drawable. This will need more refactoring i guess...
Modified:
trunk/ChangeLog
trunk/app/core/gimpdrawable.c
trunk/app/core/gimpdrawable.h
trunk/app/core/gimpfloatingselundo.c
trunk/app/core/gimpimage.c
trunk/app/core/gimplayer-floating-sel.c
Modified: trunk/app/core/gimpdrawable.c
==============================================================================
--- trunk/app/core/gimpdrawable.c (original)
+++ trunk/app/core/gimpdrawable.c Mon Jan 26 22:05:07 2009
@@ -150,6 +150,12 @@
gint width,
gint height);
+static void gimp_drawable_sync_source_node (GimpDrawable *drawable,
+ gboolean detach_fs);
+static void gimp_drawable_fs_notify (GimpLayer *fs,
+ const GParamSpec *pspec,
+ GimpDrawable *drawable);
+
G_DEFINE_TYPE_WITH_CODE (GimpDrawable, gimp_drawable, GIMP_TYPE_ITEM,
G_IMPLEMENT_INTERFACE (GIMP_TYPE_PICKABLE,
@@ -250,6 +256,9 @@
{
GimpDrawable *drawable = GIMP_DRAWABLE (object);
+ if (drawable->fs_opacity_node)
+ gimp_drawable_sync_source_node (drawable, TRUE);
+
if (drawable->tiles)
{
tile_manager_unref (drawable->tiles);
@@ -672,12 +681,12 @@
gint width,
gint height)
{
- if (drawable->source_node)
+ if (drawable->tile_source_node)
{
GObject *operation;
GeglRectangle rect;
- g_object_get (drawable->source_node,
+ g_object_get (drawable->tile_source_node,
"gegl-operation", &operation,
NULL);
@@ -757,8 +766,8 @@
if (old_has_alpha != gimp_drawable_has_alpha (drawable))
gimp_drawable_alpha_changed (drawable);
- if (drawable->source_node)
- gegl_node_set (drawable->source_node,
+ if (drawable->tile_source_node)
+ gegl_node_set (drawable->tile_source_node,
"tile-manager", drawable->tiles,
NULL);
}
@@ -888,6 +897,133 @@
gimp_drawable_update (drawable, x, y, width, height);
}
+static void
+gimp_drawable_sync_source_node (GimpDrawable *drawable,
+ gboolean detach_fs)
+{
+ GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
+ GimpLayer *fs = gimp_image_get_floating_selection (image);
+ GeglNode *output;
+
+ if (! drawable->source_node)
+ return;
+
+ output = gegl_node_get_output_proxy (drawable->source_node, "output");
+
+ if (gimp_drawable_has_floating_sel (drawable) && ! detach_fs)
+ {
+ gint off_x, off_y;
+ gint fs_off_x, fs_off_y;
+
+ if (! drawable->fs_opacity_node)
+ {
+ GeglNode *fs_source;
+
+ fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs));
+ gegl_node_add_child (drawable->source_node, fs_source);
+
+ drawable->fs_opacity_node =
+ gegl_node_new_child (drawable->source_node,
+ "operation", "gegl:opacity",
+ NULL);
+
+ gegl_node_connect_to (fs_source, "output",
+ drawable->fs_opacity_node, "input");
+
+ drawable->fs_offset_node =
+ gegl_node_new_child (drawable->source_node,
+ "operation", "gegl:translate",
+ NULL);
+
+ gegl_node_connect_to (drawable->fs_opacity_node, "output",
+ drawable->fs_offset_node, "input");
+
+ drawable->fs_mode_node =
+ gegl_node_new_child (drawable->source_node,
+ "operation", "gimp:point-layer-mode",
+ NULL);
+
+ gegl_node_connect_to (drawable->tile_source_node, "output",
+ drawable->fs_mode_node, "input");
+ gegl_node_connect_to (drawable->fs_offset_node, "output",
+ drawable->fs_mode_node, "aux");
+
+ gegl_node_connect_to (drawable->fs_mode_node, "output",
+ output, "input");
+
+ g_signal_connect (fs, "notify",
+ G_CALLBACK (gimp_drawable_fs_notify),
+ drawable);
+ }
+
+ gegl_node_set (drawable->fs_opacity_node,
+ "value", gimp_layer_get_opacity (fs),
+ NULL);
+
+ gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+ gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y);
+
+ gegl_node_set (drawable->fs_offset_node,
+ "x", (gdouble) (fs_off_x - off_x),
+ "y", (gdouble) (fs_off_y - off_y),
+ NULL);
+
+ gegl_node_set (drawable->fs_mode_node,
+ "blend-mode", gimp_layer_get_mode (fs),
+ NULL);
+ }
+ else
+ {
+ if (drawable->fs_opacity_node)
+ {
+ GeglNode *fs_source;
+
+ gegl_node_disconnect (drawable->fs_opacity_node, "input");
+ gegl_node_disconnect (drawable->fs_offset_node, "input");
+ gegl_node_disconnect (drawable->fs_mode_node, "input");
+ gegl_node_disconnect (drawable->fs_mode_node, "aux");
+
+ fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs));
+ gegl_node_remove_child (drawable->source_node,
+ fs_source);
+
+ gegl_node_remove_child (drawable->source_node,
+ drawable->fs_opacity_node);
+ drawable->fs_opacity_node = NULL;
+
+ gegl_node_remove_child (drawable->source_node,
+ drawable->fs_offset_node);
+ drawable->fs_offset_node = NULL;
+
+ gegl_node_remove_child (drawable->source_node,
+ drawable->fs_mode_node);
+ drawable->fs_mode_node = NULL;
+
+ g_signal_handlers_disconnect_by_func (fs,
+ gimp_drawable_fs_notify,
+ drawable);
+ }
+
+ gegl_node_connect_to (drawable->tile_source_node, "output",
+ output, "input");
+ }
+}
+
+static void
+gimp_drawable_fs_notify (GimpLayer *fs,
+ const GParamSpec *pspec,
+ GimpDrawable *drawable)
+{
+ if (! strcmp (pspec->name, "offset-x") ||
+ ! strcmp (pspec->name, "offset-y") ||
+ ! strcmp (pspec->name, "visible") ||
+ ! strcmp (pspec->name, "mode") ||
+ ! strcmp (pspec->name, "opacity"))
+ {
+ gimp_drawable_sync_source_node (drawable, FALSE);
+ }
+}
+
/* public functions */
@@ -932,8 +1068,8 @@
drawable->preview_cache = NULL;
drawable->preview_valid = FALSE;
- if (drawable->source_node)
- gegl_node_set (drawable->source_node,
+ if (drawable->tile_source_node)
+ gegl_node_set (drawable->tile_source_node,
"tile-manager", drawable->tiles,
NULL);
}
@@ -1239,13 +1375,16 @@
if (drawable->source_node)
return drawable->source_node;
- drawable->source_node = g_object_new (GEGL_TYPE_NODE,
- "operation", "gimp:tilemanager-source",
- NULL);
- gegl_node_set (drawable->source_node,
- "tile-manager", drawable->tiles,
- "linear", TRUE,
- NULL);
+ drawable->source_node = gegl_node_new ();
+
+ drawable->tile_source_node =
+ gegl_node_new_child (drawable->source_node,
+ "operation", "gimp:tilemanager-source",
+ "tile-manager", drawable->tiles,
+ "linear", TRUE,
+ NULL);
+
+ gimp_drawable_sync_source_node (drawable, FALSE);
return drawable->source_node;
}
@@ -1654,3 +1793,44 @@
return image ? gimp_image_get_colormap (image) : NULL;
}
+
+void
+gimp_drawable_attach_floating_sel (GimpDrawable *drawable,
+ GimpLayer *floating_sel)
+{
+ g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+ g_return_if_fail (GIMP_IS_LAYER (floating_sel));
+
+ g_printerr ("%s\n", G_STRFUNC);
+
+ gimp_drawable_sync_source_node (drawable, FALSE);
+
+#ifdef __GNUC__
+#warning FIXME: remove this hack when the floating sel is no layer any longer
+#endif
+ g_signal_emit_by_name (floating_sel, "visibility-changed");
+}
+
+void
+gimp_drawable_detach_floating_sel (GimpDrawable *drawable,
+ GimpLayer *floating_sel)
+{
+ g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+ g_return_if_fail (GIMP_IS_LAYER (floating_sel));
+
+ g_printerr ("%s\n", G_STRFUNC);
+
+ gimp_drawable_sync_source_node (drawable, TRUE);
+
+#ifdef __GNUC__
+#warning FIXME: remove this hack when the floating sel is no layer any longer
+#endif
+ g_signal_emit_by_name (floating_sel, "visibility-changed");
+
+ /* Invalidate the preview of the obscured drawable. We do this here
+ * because it will not be done until the floating selection is removed,
+ * at which point the obscured drawable's preview will not be declared
+ * invalid.
+ */
+ gimp_viewable_invalidate_preview (GIMP_VIEWABLE (floating_sel));
+}
Modified: trunk/app/core/gimpdrawable.h
==============================================================================
--- trunk/app/core/gimpdrawable.h (original)
+++ trunk/app/core/gimpdrawable.h Mon Jan 26 22:05:07 2009
@@ -40,6 +40,10 @@
TileManager *shadow; /* shadow buffer tiles */
GeglNode *source_node;
+ GeglNode *tile_source_node;
+ GeglNode *fs_opacity_node;
+ GeglNode *fs_offset_node;
+ GeglNode *fs_mode_node;
GeglNode *mode_node;
@@ -248,5 +252,10 @@
const guchar * gimp_drawable_get_colormap (const GimpDrawable *drawable);
+void gimp_drawable_attach_floating_sel (GimpDrawable *drawable,
+ GimpLayer *floating_sel);
+void gimp_drawable_detach_floating_sel (GimpDrawable *drawable,
+ GimpLayer *floating_sel);
+
#endif /* __GIMP_DRAWABLE_H__ */
Modified: trunk/app/core/gimpfloatingselundo.c
==============================================================================
--- trunk/app/core/gimpfloatingselundo.c (original)
+++ trunk/app/core/gimpfloatingselundo.c Mon Jan 26 22:05:07 2009
@@ -114,11 +114,14 @@
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (floating_layer));
+
+ gimp_drawable_attach_floating_sel (floating_layer->fs.drawable,
+ floating_layer);
}
else
{
- /* Update the preview for the underlying drawable */
- gimp_viewable_invalidate_preview (GIMP_VIEWABLE (floating_layer));
+ gimp_drawable_detach_floating_sel (floating_layer->fs.drawable,
+ floating_layer);
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (floating_layer));
Modified: trunk/app/core/gimpimage.c
==============================================================================
--- trunk/app/core/gimpimage.c (original)
+++ trunk/app/core/gimpimage.c Mon Jan 26 22:05:07 2009
@@ -2969,7 +2969,11 @@
/* If the layer is a floating selection, set the fs pointer */
if (gimp_layer_is_floating_sel (layer))
- gimp_image_set_floating_selection (image, layer);
+ {
+ gimp_image_set_floating_selection (image, layer);
+
+ gimp_drawable_attach_floating_sel (layer->fs.drawable, layer);
+ }
if (old_has_alpha != gimp_image_has_alpha (image))
image->flush_accum.alpha_changed = TRUE;
@@ -3019,16 +3023,11 @@
old_has_alpha = gimp_image_has_alpha (image);
- if (gimp_image_get_floating_selection (image) == layer)
+ if (gimp_layer_is_floating_sel (layer))
{
undo_desc = _("Remove Floating Selection");
- /* Invalidate the preview of the obscured drawable. We do this here
- * because it will not be done until the floating selection is removed,
- * at which point the obscured drawable's preview will not be declared
- * invalid.
- */
- gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));
+ gimp_drawable_detach_floating_sel (layer->fs.drawable, layer);
}
else
{
Modified: trunk/app/core/gimplayer-floating-sel.c
==============================================================================
--- trunk/app/core/gimplayer-floating-sel.c (original)
+++ trunk/app/core/gimplayer-floating-sel.c Mon Jan 26 22:05:07 2009
@@ -139,8 +139,7 @@
gimp_image_undo_push_fs_to_layer (image, NULL, layer);
- /* clear the selection */
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
+ gimp_drawable_detach_floating_sel (layer->fs.drawable, layer);
/* Set pointers */
gimp_layer_set_floating_sel_drawable (layer, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]