diff --git a/app/core/Makefile.am b/app/core/Makefile.am index 6b1edf8362..1be64396d6 100644 --- a/app/core/Makefile.am +++ b/app/core/Makefile.am @@ -145,6 +145,8 @@ libappcore_a_sources = \ gimpdrawable-fill.h \ gimpdrawable-filters.c \ gimpdrawable-filters.h \ + gimpdrawable-floating-selection.c \ + gimpdrawable-floating-selection.h \ gimpdrawable-foreground-extract.c \ gimpdrawable-foreground-extract.h \ gimpdrawable-histogram.c \ diff --git a/app/core/gimpdrawable-floating-selection.c b/app/core/gimpdrawable-floating-selection.c new file mode 100644 index 0000000000..b33a350ed2 --- /dev/null +++ b/app/core/gimpdrawable-floating-selection.c @@ -0,0 +1,391 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include +#include + +#include "libgimpbase/gimpbase.h" + +#include "core-types.h" + +#include "gegl/gimpapplicator.h" + +#include "gimpchannel.h" +#include "gimpdrawable-floating-selection.h" +#include "gimpdrawable-filters.h" +#include "gimpdrawable-private.h" +#include "gimpimage.h" +#include "gimplayer.h" + +#include "gimp-log.h" + +#include "gimp-intl.h" + + +/* local function prototypes */ + +static void gimp_drawable_remove_fs_filter (GimpDrawable *drawable); +static void gimp_drawable_sync_fs_filter (GimpDrawable *drawable); + +static void gimp_drawable_fs_notify (GimpLayer *fs, + const GParamSpec *pspec, + GimpDrawable *drawable); +static void gimp_drawable_fs_affect_changed (GimpImage *image, + GimpChannelType channel, + GimpDrawable *drawable); +static void gimp_drawable_fs_mask_changed (GimpImage *image, + GimpDrawable *drawable); +static void gimp_drawable_fs_update (GimpLayer *fs, + gint x, + gint y, + gint width, + gint height, + GimpDrawable *drawable); + + +/* public functions */ + +GimpLayer * +gimp_drawable_get_floating_sel (GimpDrawable *drawable) +{ + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); + + return drawable->private->floating_selection; +} + +void +gimp_drawable_attach_floating_sel (GimpDrawable *drawable, + GimpLayer *fs) +{ + GimpImage *image; + + g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); + g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); + g_return_if_fail (gimp_drawable_get_floating_sel (drawable) == NULL); + g_return_if_fail (GIMP_IS_LAYER (fs)); + + GIMP_LOG (FLOATING_SELECTION, "%s", G_STRFUNC); + + image = gimp_item_get_image (GIMP_ITEM (drawable)); + + drawable->private->floating_selection = fs; + gimp_image_set_floating_selection (image, fs); + + /* clear the selection */ + gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fs)); + + _gimp_drawable_add_floating_sel_filter (drawable); + + g_signal_connect (fs, "update", + G_CALLBACK (gimp_drawable_fs_update), + drawable); + + gimp_drawable_fs_update (fs, + 0, 0, + gimp_item_get_width (GIMP_ITEM (fs)), + gimp_item_get_height (GIMP_ITEM (fs)), + drawable); +} + +void +gimp_drawable_detach_floating_sel (GimpDrawable *drawable) +{ + GimpImage *image; + GimpLayer *fs; + + g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); + g_return_if_fail (gimp_drawable_get_floating_sel (drawable) != NULL); + + GIMP_LOG (FLOATING_SELECTION, "%s", G_STRFUNC); + + image = gimp_item_get_image (GIMP_ITEM (drawable)); + fs = drawable->private->floating_selection; + + gimp_drawable_remove_fs_filter (drawable); + + g_signal_handlers_disconnect_by_func (fs, + gimp_drawable_fs_update, + drawable); + + gimp_drawable_fs_update (fs, + 0, 0, + gimp_item_get_width (GIMP_ITEM (fs)), + gimp_item_get_height (GIMP_ITEM (fs)), + drawable); + + /* clear the selection */ + gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fs)); + + gimp_image_set_floating_selection (image, NULL); + drawable->private->floating_selection = NULL; +} + +GimpFilter * +gimp_drawable_get_floating_sel_filter (GimpDrawable *drawable) +{ + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (gimp_drawable_get_floating_sel (drawable) != NULL, NULL); + + /* Ensure that the graph is construced before the filter is used. + * Otherwise, we rely on the projection to cause the graph to be + * constructed, which fails for images that aren't displayed. + */ + gimp_filter_get_node (GIMP_FILTER (drawable)); + + return drawable->private->fs_filter; +} + + +/* private functions */ + +void +_gimp_drawable_add_floating_sel_filter (GimpDrawable *drawable) +{ + GimpDrawablePrivate *private = drawable->private; + GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); + GimpLayer *fs = gimp_drawable_get_floating_sel (drawable); + GeglNode *node; + GeglNode *fs_source; + gboolean linear; + + if (! private->source_node) + return; + + private->fs_filter = gimp_filter_new (_("Floating Selection")); + gimp_viewable_set_icon_name (GIMP_VIEWABLE (private->fs_filter), + "gimp-floating-selection"); + + node = gimp_filter_get_node (private->fs_filter); + + fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs)); + linear = gimp_drawable_get_linear (GIMP_DRAWABLE (fs)); + + /* rip the fs' source node out of its graph */ + if (fs->layer_offset_node) + { + gegl_node_disconnect (fs->layer_offset_node, "input"); + gegl_node_remove_child (gimp_filter_get_node (GIMP_FILTER (fs)), + fs_source); + } + + gegl_node_add_child (node, fs_source); + + private->fs_applicator = gimp_applicator_new (node, linear, + FALSE, FALSE); + + private->fs_crop_node = + gegl_node_new_child (node, + "operation", "gegl:crop", + NULL); + + gegl_node_connect_to (fs_source, "output", + private->fs_crop_node, "input"); + gegl_node_connect_to (private->fs_crop_node, "output", + node, "aux"); + + gimp_drawable_add_filter (drawable, private->fs_filter); + + g_signal_connect (fs, "notify", + G_CALLBACK (gimp_drawable_fs_notify), + drawable); + g_signal_connect (image, "component-active-changed", + G_CALLBACK (gimp_drawable_fs_affect_changed), + drawable); + g_signal_connect (image, "mask-changed", + G_CALLBACK (gimp_drawable_fs_mask_changed), + drawable); + + gimp_drawable_sync_fs_filter (drawable); +} + + +/* private functions */ + +static void +gimp_drawable_remove_fs_filter (GimpDrawable *drawable) +{ + GimpDrawablePrivate *private = drawable->private; + GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); + GimpLayer *fs = gimp_drawable_get_floating_sel (drawable); + + if (private->fs_filter) + { + GeglNode *node; + GeglNode *fs_source; + + g_signal_handlers_disconnect_by_func (fs, + gimp_drawable_fs_notify, + drawable); + g_signal_handlers_disconnect_by_func (image, + gimp_drawable_fs_affect_changed, + drawable); + g_signal_handlers_disconnect_by_func (image, + gimp_drawable_fs_mask_changed, + drawable); + + gimp_drawable_remove_filter (drawable, private->fs_filter); + + node = gimp_filter_get_node (private->fs_filter); + + fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs)); + + gegl_node_remove_child (node, fs_source); + + /* plug the fs' source node back into its graph */ + if (fs->layer_offset_node) + { + gegl_node_add_child (gimp_filter_get_node (GIMP_FILTER (fs)), + fs_source); + gegl_node_connect_to (fs_source, "output", + fs->layer_offset_node, "input"); + } + + g_object_unref (private->fs_filter); + private->fs_filter = NULL; + + g_object_unref (private->fs_applicator); + private->fs_applicator = NULL; + + private->fs_crop_node = NULL; + } +} + +static void +gimp_drawable_sync_fs_filter (GimpDrawable *drawable) +{ + GimpDrawablePrivate *private = drawable->private; + GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); + GimpChannel *mask = gimp_image_get_mask (image); + GimpLayer *fs = gimp_drawable_get_floating_sel (drawable); + gint off_x, off_y; + gint fs_off_x, fs_off_y; + + 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 (private->fs_crop_node, + "x", (gdouble) (off_x - fs_off_x), + "y", (gdouble) (off_y - fs_off_y), + "width", (gdouble) gimp_item_get_width (GIMP_ITEM (drawable)), + "height", (gdouble) gimp_item_get_height (GIMP_ITEM (drawable)), + NULL); + + gimp_applicator_set_apply_offset (private->fs_applicator, + fs_off_x - off_x, + fs_off_y - off_y); + + if (gimp_channel_is_empty (mask)) + { + gimp_applicator_set_mask_buffer (private->fs_applicator, NULL); + } + else + { + GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)); + + gimp_applicator_set_mask_buffer (private->fs_applicator, buffer); + gimp_applicator_set_mask_offset (private->fs_applicator, + -off_x, -off_y); + } + + gimp_applicator_set_opacity (private->fs_applicator, + gimp_layer_get_opacity (fs)); + gimp_applicator_set_mode (private->fs_applicator, + gimp_layer_get_mode (fs)); + gimp_applicator_set_affect (private->fs_applicator, + gimp_drawable_get_active_mask (drawable)); +} + +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_fs_filter (drawable); + } +} + +static void +gimp_drawable_fs_affect_changed (GimpImage *image, + GimpChannelType channel, + GimpDrawable *drawable) +{ + GimpLayer *fs = gimp_drawable_get_floating_sel (drawable); + + gimp_drawable_sync_fs_filter (drawable); + + gimp_drawable_update (GIMP_DRAWABLE (fs), + 0, 0, + gimp_item_get_width (GIMP_ITEM (fs)), + gimp_item_get_height (GIMP_ITEM (fs))); +} + +static void +gimp_drawable_fs_mask_changed (GimpImage *image, + GimpDrawable *drawable) +{ + GimpLayer *fs = gimp_drawable_get_floating_sel (drawable); + + gimp_drawable_sync_fs_filter (drawable); + + gimp_drawable_update (GIMP_DRAWABLE (fs), + 0, 0, + gimp_item_get_width (GIMP_ITEM (fs)), + gimp_item_get_height (GIMP_ITEM (fs))); +} + +static void +gimp_drawable_fs_update (GimpLayer *fs, + gint x, + gint y, + gint width, + gint height, + GimpDrawable *drawable) +{ + gint fs_off_x, fs_off_y; + gint off_x, off_y; + gint dr_x, dr_y, dr_width, dr_height; + + gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y); + gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); + + if (gimp_rectangle_intersect (x + fs_off_x, + y + fs_off_y, + width, + height, + off_x, + off_y, + gimp_item_get_width (GIMP_ITEM (drawable)), + gimp_item_get_height (GIMP_ITEM (drawable)), + &dr_x, + &dr_y, + &dr_width, + &dr_height)) + { + gimp_drawable_update (drawable, + dr_x - off_x, dr_y - off_y, + dr_width, dr_height); + } +} diff --git a/app/core/gimpdrawable-floating-selection.h b/app/core/gimpdrawable-floating-selection.h new file mode 100644 index 0000000000..ef186749dd --- /dev/null +++ b/app/core/gimpdrawable-floating-selection.h @@ -0,0 +1,31 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_DRAWABLE_FLOATING_SELECTION_H__ +#define __GIMP_DRAWABLE_FLOATING_SELECTION_H__ + + +GimpLayer * gimp_drawable_get_floating_sel (GimpDrawable *drawable); +void gimp_drawable_attach_floating_sel (GimpDrawable *drawable, + GimpLayer *floating_sel); +void gimp_drawable_detach_floating_sel (GimpDrawable *drawable); +GimpFilter * gimp_drawable_get_floating_sel_filter (GimpDrawable *drawable); + +void _gimp_drawable_add_floating_sel_filter (GimpDrawable *drawable); + + +#endif /* __GIMP_DRAWABLE_FLOATING_SELECTION_H__ */ diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c index 8ce84d4034..4a65c7a925 100644 --- a/app/core/gimpdrawable.c +++ b/app/core/gimpdrawable.c @@ -26,7 +26,6 @@ #include "core-types.h" -#include "gegl/gimpapplicator.h" #include "gegl/gimp-babl.h" #include "gegl/gimp-gegl-apply-operation.h" #include "gegl/gimp-gegl-utils.h" @@ -36,7 +35,7 @@ #include "gimpchannel.h" #include "gimpcontext.h" #include "gimpdrawable-combine.h" -#include "gimpdrawable-filters.h" +#include "gimpdrawable-floating-selection.h" #include "gimpdrawable-preview.h" #include "gimpdrawable-private.h" #include "gimpdrawable-shadow.h" @@ -45,9 +44,7 @@ #include "gimpimage.h" #include "gimpimage-colormap.h" #include "gimpimage-undo-push.h" -#include "gimplayer.h" #include "gimpmarshal.h" -#include "gimppattern.h" #include "gimppickable.h" #include "gimpprogress.h" @@ -185,23 +182,6 @@ static void gimp_drawable_real_swap_pixels (GimpDrawable *drawable, gint x, gint y); -static void gimp_drawable_sync_fs_filter (GimpDrawable *drawable, - gboolean detach_fs); -static void gimp_drawable_fs_notify (GimpLayer *fs, - const GParamSpec *pspec, - GimpDrawable *drawable); -static void gimp_drawable_fs_affect_changed (GimpImage *image, - GimpChannelType channel, - GimpDrawable *drawable); -static void gimp_drawable_fs_mask_changed (GimpImage *image, - GimpDrawable *drawable); -static void gimp_drawable_fs_update (GimpLayer *fs, - gint x, - gint y, - gint width, - gint height, - GimpDrawable *drawable); - G_DEFINE_TYPE_WITH_CODE (GimpDrawable, gimp_drawable, GIMP_TYPE_ITEM, G_IMPLEMENT_INTERFACE (GIMP_TYPE_COLOR_MANAGED, @@ -946,232 +926,6 @@ gimp_drawable_real_swap_pixels (GimpDrawable *drawable, gimp_drawable_update (drawable, x, y, width, height); } -static void -gimp_drawable_sync_fs_filter (GimpDrawable *drawable, - gboolean detach_fs) -{ - GimpDrawablePrivate *private = drawable->private; - GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); - GimpLayer *fs = gimp_drawable_get_floating_sel (drawable); - - if (! private->source_node) - return; - - if (fs && ! detach_fs) - { - GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); - GimpChannel *mask = gimp_image_get_mask (image); - gint off_x, off_y; - gint fs_off_x, fs_off_y; - - if (! private->fs_filter) - { - GeglNode *node; - GeglNode *fs_source; - gboolean linear; - - private->fs_filter = gimp_filter_new ("Floating Selection"); - gimp_viewable_set_icon_name (GIMP_VIEWABLE (private->fs_filter), - "gimp-floating-selection"); - - node = gimp_filter_get_node (private->fs_filter); - - fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs)); - linear = gimp_drawable_get_linear (GIMP_DRAWABLE (fs)); - - /* rip the fs' source node out of its graph */ - if (fs->layer_offset_node) - { - gegl_node_disconnect (fs->layer_offset_node, "input"); - gegl_node_remove_child (gimp_filter_get_node (GIMP_FILTER (fs)), - fs_source); - } - - gegl_node_add_child (node, fs_source); - - private->fs_applicator = gimp_applicator_new (node, linear, - FALSE, FALSE); - - private->fs_crop_node = - gegl_node_new_child (node, - "operation", "gegl:crop", - NULL); - - gegl_node_connect_to (fs_source, "output", - private->fs_crop_node, "input"); - gegl_node_connect_to (private->fs_crop_node, "output", - node, "aux"); - - gimp_drawable_add_filter (drawable, private->fs_filter); - - g_signal_connect (fs, "notify", - G_CALLBACK (gimp_drawable_fs_notify), - drawable); - g_signal_connect (image, "component-active-changed", - G_CALLBACK (gimp_drawable_fs_affect_changed), - drawable); - g_signal_connect (image, "mask-changed", - G_CALLBACK (gimp_drawable_fs_mask_changed), - drawable); - } - - 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 (private->fs_crop_node, - "x", (gdouble) (off_x - fs_off_x), - "y", (gdouble) (off_y - fs_off_y), - "width", (gdouble) gimp_item_get_width (GIMP_ITEM (drawable)), - "height", (gdouble) gimp_item_get_height (GIMP_ITEM (drawable)), - NULL); - - gimp_applicator_set_apply_offset (private->fs_applicator, - fs_off_x - off_x, - fs_off_y - off_y); - - if (gimp_channel_is_empty (mask)) - { - gimp_applicator_set_mask_buffer (private->fs_applicator, NULL); - } - else - { - GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)); - - gimp_applicator_set_mask_buffer (private->fs_applicator, buffer); - gimp_applicator_set_mask_offset (private->fs_applicator, - -off_x, -off_y); - } - - gimp_applicator_set_opacity (private->fs_applicator, - gimp_layer_get_opacity (fs)); - gimp_applicator_set_mode (private->fs_applicator, - gimp_layer_get_mode (fs)); - gimp_applicator_set_affect (private->fs_applicator, - gimp_drawable_get_active_mask (drawable)); - } - else - { - if (private->fs_filter) - { - GeglNode *node; - GeglNode *fs_source; - - g_signal_handlers_disconnect_by_func (fs, - gimp_drawable_fs_notify, - drawable); - g_signal_handlers_disconnect_by_func (image, - gimp_drawable_fs_affect_changed, - drawable); - g_signal_handlers_disconnect_by_func (image, - gimp_drawable_fs_mask_changed, - drawable); - - gimp_drawable_remove_filter (drawable, private->fs_filter); - - node = gimp_filter_get_node (private->fs_filter); - - fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs)); - - gegl_node_remove_child (node, fs_source); - - /* plug the fs' source node back into its graph */ - if (fs->layer_offset_node) - { - gegl_node_add_child (gimp_filter_get_node (GIMP_FILTER (fs)), - fs_source); - gegl_node_connect_to (fs_source, "output", - fs->layer_offset_node, "input"); - } - - g_object_unref (private->fs_filter); - private->fs_filter = NULL; - - g_object_unref (private->fs_applicator); - private->fs_applicator = NULL; - - private->fs_crop_node = NULL; - } - } -} - -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_fs_filter (drawable, FALSE); - } -} - -static void -gimp_drawable_fs_affect_changed (GimpImage *image, - GimpChannelType channel, - GimpDrawable *drawable) -{ - GimpLayer *fs = gimp_drawable_get_floating_sel (drawable); - - gimp_drawable_sync_fs_filter (drawable, FALSE); - - gimp_drawable_update (GIMP_DRAWABLE (fs), - 0, 0, - gimp_item_get_width (GIMP_ITEM (fs)), - gimp_item_get_height (GIMP_ITEM (fs))); -} - -static void -gimp_drawable_fs_mask_changed (GimpImage *image, - GimpDrawable *drawable) -{ - GimpLayer *fs = gimp_drawable_get_floating_sel (drawable); - - gimp_drawable_sync_fs_filter (drawable, FALSE); - - gimp_drawable_update (GIMP_DRAWABLE (fs), - 0, 0, - gimp_item_get_width (GIMP_ITEM (fs)), - gimp_item_get_height (GIMP_ITEM (fs))); -} - -static void -gimp_drawable_fs_update (GimpLayer *fs, - gint x, - gint y, - gint width, - gint height, - GimpDrawable *drawable) -{ - gint fs_off_x, fs_off_y; - gint off_x, off_y; - gint dr_x, dr_y, dr_width, dr_height; - - gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y); - gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); - - if (gimp_rectangle_intersect (x + fs_off_x, - y + fs_off_y, - width, - height, - off_x, - off_y, - gimp_item_get_width (GIMP_ITEM (drawable)), - gimp_item_get_height (GIMP_ITEM (drawable)), - &dr_x, - &dr_y, - &dr_width, - &dr_height)) - { - gimp_drawable_update (drawable, - dr_x - off_x, dr_y - off_y, - dr_width, dr_height); - } -} - /* public functions */ @@ -1478,7 +1232,8 @@ gimp_drawable_get_source_node (GimpDrawable *drawable) gegl_node_connect_to (filter, "output", output, "input"); - gimp_drawable_sync_fs_filter (drawable, FALSE); + if (gimp_drawable_get_floating_sel (drawable)) + _gimp_drawable_add_floating_sel_filter (drawable); return drawable->private->source_node; } @@ -1732,94 +1487,3 @@ gimp_drawable_get_colormap (const GimpDrawable *drawable) return image ? gimp_image_get_colormap (image) : NULL; } - -GimpLayer * -gimp_drawable_get_floating_sel (const GimpDrawable *drawable) -{ - g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); - - return drawable->private->floating_selection; -} - -void -gimp_drawable_attach_floating_sel (GimpDrawable *drawable, - GimpLayer *fs) -{ - GimpImage *image; - - g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); - g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); - g_return_if_fail (gimp_drawable_get_floating_sel (drawable) == NULL); - g_return_if_fail (GIMP_IS_LAYER (fs)); - - GIMP_LOG (FLOATING_SELECTION, "%s", G_STRFUNC); - - image = gimp_item_get_image (GIMP_ITEM (drawable)); - - drawable->private->floating_selection = fs; - gimp_image_set_floating_selection (image, fs); - - /* clear the selection */ - gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fs)); - - gimp_drawable_sync_fs_filter (drawable, FALSE); - - g_signal_connect (fs, "update", - G_CALLBACK (gimp_drawable_fs_update), - drawable); - - gimp_drawable_fs_update (fs, - 0, 0, - gimp_item_get_width (GIMP_ITEM (fs)), - gimp_item_get_height (GIMP_ITEM (fs)), - drawable); -} - -void -gimp_drawable_detach_floating_sel (GimpDrawable *drawable) -{ - GimpImage *image; - GimpLayer *fs; - - g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); - g_return_if_fail (gimp_drawable_get_floating_sel (drawable) != NULL); - - GIMP_LOG (FLOATING_SELECTION, "%s", G_STRFUNC); - - image = gimp_item_get_image (GIMP_ITEM (drawable)); - fs = drawable->private->floating_selection; - - gimp_drawable_sync_fs_filter (drawable, TRUE); - - g_signal_handlers_disconnect_by_func (fs, - gimp_drawable_fs_update, - drawable); - - gimp_drawable_fs_update (fs, - 0, 0, - gimp_item_get_width (GIMP_ITEM (fs)), - gimp_item_get_height (GIMP_ITEM (fs)), - drawable); - - /* clear the selection */ - gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fs)); - - gimp_image_set_floating_selection (image, NULL); - drawable->private->floating_selection = NULL; -} - -GimpFilter * -gimp_drawable_get_floating_sel_filter (GimpDrawable *drawable) -{ - g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); - g_return_val_if_fail (gimp_drawable_get_floating_sel (drawable) != NULL, NULL); - - /* - * Ensure that the graph is construced before the filter is used. - * Otherwise, we rely on the projection to cause the graph to be constructed, - * which fails for images that aren't displayed. - */ - gimp_filter_get_node (GIMP_FILTER (drawable)); - - return drawable->private->fs_filter; -} diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h index 3cb35e3f5b..52fc8c3292 100644 --- a/app/core/gimpdrawable.h +++ b/app/core/gimpdrawable.h @@ -220,12 +220,5 @@ gint gimp_drawable_get_component_index (const GimpDrawable *drawable, const guchar * gimp_drawable_get_colormap (const GimpDrawable *drawable); -GimpLayer * gimp_drawable_get_floating_sel (const GimpDrawable *drawable); -void gimp_drawable_attach_floating_sel (GimpDrawable *drawable, - GimpLayer *floating_sel); -void gimp_drawable_detach_floating_sel (GimpDrawable *drawable); -GimpFilter * - gimp_drawable_get_floating_sel_filter (GimpDrawable *drawable); - #endif /* __GIMP_DRAWABLE_H__ */ diff --git a/app/core/gimpfloatingselundo.c b/app/core/gimpfloatingselundo.c index d39ae00895..b7ff3d2c91 100644 --- a/app/core/gimpfloatingselundo.c +++ b/app/core/gimpfloatingselundo.c @@ -22,6 +22,7 @@ #include "core-types.h" +#include "gimpdrawable-floating-selection.h" #include "gimpfloatingselundo.h" #include "gimpimage.h" #include "gimplayer.h" diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c index 7e6eb956e6..a6654e586b 100644 --- a/app/core/gimpimage.c +++ b/app/core/gimpimage.c @@ -41,6 +41,7 @@ #include "gimp-parasites.h" #include "gimp-utils.h" #include "gimpcontext.h" +#include "gimpdrawable-floating-selection.h" #include "gimpdrawablestack.h" #include "gimpgrid.h" #include "gimperror.h" diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c index b95515c2b9..ebbe011447 100644 --- a/app/core/gimplayer.c +++ b/app/core/gimplayer.c @@ -40,6 +40,7 @@ #include "gimpchannel-select.h" #include "gimpcontext.h" #include "gimpcontainer.h" +#include "gimpdrawable-floating-selection.h" #include "gimperror.h" #include "gimpimage-undo-push.h" #include "gimpimage-undo.h" diff --git a/po/POTFILES.in b/po/POTFILES.in index 7dd389dfb8..5df36ac7e6 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -125,6 +125,7 @@ app/core/gimpdrawable.c app/core/gimpdrawable-blend.c app/core/gimpdrawable-bucket-fill.c app/core/gimpdrawable-equalize.c +app/core/gimpdrawable-floating-selection.c app/core/gimpdrawable-foreground-extract.c app/core/gimpdrawable-fill.c app/core/gimpdrawable-levels.c