mirror of https://github.com/GNOME/gimp.git
app: move GimpDrawable's FS to gimpdrawable-floating-selection.[ch]
and refactor it a bit to have separate functions for adding, removing and updating the FS' drawable filter. Should be a lot more understandable now.
This commit is contained in:
parent
eacfd6a9ca
commit
81fd3e9c3f
|
@ -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 \
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#include <gegl.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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__ */
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "gimpdrawable-floating-selection.h"
|
||||
#include "gimpfloatingselundo.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimplayer.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue