app: improve source tool options GUI.

The "Source" dropdown to choose an image or pattern, and to check
"Sample merged" seem important enough that I moved them up the source
tool options. I also added a label giving information about the image
source being currently set, i.e. in particular which image (when the
source is another image), how many composited layers (or all of them
with "Sample merged" checked), or if each layer is its own source.

For this to happen, I moved src-drawables property from GimpSourceCore
to GimpSourceOptions (though without making it a config property,
because we don't want this option to be saved in config files). It
actually makes sense, it is a kind of "option" of how the tool will
behave, and then it is also visible by the options GUI.
This commit is contained in:
Jehan 2021-09-03 23:39:03 +02:00
parent 370db868a3
commit 6ad00cdbba
8 changed files with 334 additions and 177 deletions

View file

@ -146,7 +146,7 @@ gimp_perspective_clone_paint (GimpPaintCore *paint_core,
case GIMP_PAINT_STATE_INIT:
if (source_core->set_source)
{
g_object_set (source_core, "src-drawables", drawables, NULL);
g_object_set (options, "src-drawables", drawables, NULL);
source_core->src_x = floor (coords->x);
source_core->src_y = floor (coords->y);
@ -194,7 +194,7 @@ gimp_perspective_clone_paint (GimpPaintCore *paint_core,
* Otherwise, we need a call to get_orig_image to make sure
* we get a copy of the unblemished (offset) image
*/
src_image = gimp_pickable_get_image (source_core->src_drawables->data);
src_image = gimp_pickable_get_image (options->src_drawables->data);
if (sample_merged)
src_pickable = GIMP_PICKABLE (src_image);
@ -204,12 +204,12 @@ gimp_perspective_clone_paint (GimpPaintCore *paint_core,
if ((sample_merged &&
(src_image != dest_image)) ||
(! sample_merged &&
g_list_length (source_core->src_drawables) == 1 &&
g_list_length (options->src_drawables) == 1 &&
g_list_length (drawables) == 1 &&
(source_core->src_drawables != drawables->data)))
(options->src_drawables != drawables->data)))
{
if (! sample_merged)
src_pickable = GIMP_PICKABLE (source_core->src_drawables->data);
src_pickable = GIMP_PICKABLE (options->src_drawables->data);
orig_buffer = gimp_pickable_get_buffer (src_pickable);
}

View file

@ -46,13 +46,11 @@
enum
{
PROP_0,
PROP_SRC_DRAWABLES,
PROP_SRC_X,
PROP_SRC_Y
};
static void gimp_source_core_finalize (GObject *object);
static void gimp_source_core_set_property (GObject *object,
guint property_id,
const GValue *value,
@ -101,10 +99,6 @@ static GeglBuffer *
gint *paint_area_height,
GeglRectangle *src_rect);
static void gimp_source_core_set_src_drawable (GimpSourceCore *source_core,
GList *drawables);
static void gimp_source_core_make_pickable (GimpSourceCore *source_core);
G_DEFINE_TYPE (GimpSourceCore, gimp_source_core, GIMP_TYPE_BRUSH_CORE)
@ -118,7 +112,6 @@ gimp_source_core_class_init (GimpSourceCoreClass *klass)
GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
GimpBrushCoreClass *brush_core_class = GIMP_BRUSH_CORE_CLASS (klass);
object_class->finalize = gimp_source_core_finalize;
object_class->set_property = gimp_source_core_set_property;
object_class->get_property = gimp_source_core_get_property;
@ -131,11 +124,6 @@ gimp_source_core_class_init (GimpSourceCoreClass *klass)
klass->get_source = gimp_source_core_real_get_source;
klass->motion = NULL;
g_object_class_install_property (object_class, PROP_SRC_DRAWABLES,
g_param_spec_pointer ("src-drawables",
NULL, NULL,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_SRC_X,
g_param_spec_int ("src-x", NULL, NULL,
0, GIMP_MAX_IMAGE_SIZE,
@ -154,7 +142,6 @@ gimp_source_core_init (GimpSourceCore *source_core)
{
source_core->set_source = FALSE;
source_core->src_drawables = NULL;
source_core->src_x = 0;
source_core->src_y = 0;
@ -166,17 +153,6 @@ gimp_source_core_init (GimpSourceCore *source_core)
source_core->first_stroke = TRUE;
}
static void
gimp_source_core_finalize (GObject *object)
{
GimpSourceCore *source_core = GIMP_SOURCE_CORE (object);
g_clear_object (&source_core->src_image);
g_clear_pointer (&source_core->src_drawables, g_list_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_source_core_set_property (GObject *object,
guint property_id,
@ -187,11 +163,6 @@ gimp_source_core_set_property (GObject *object,
switch (property_id)
{
case PROP_SRC_DRAWABLES:
gimp_source_core_set_src_drawable (source_core,
g_value_get_pointer (value));
gimp_source_core_make_pickable (source_core);
break;
case PROP_SRC_X:
source_core->src_x = g_value_get_int (value);
break;
@ -214,9 +185,6 @@ gimp_source_core_get_property (GObject *object,
switch (property_id)
{
case PROP_SRC_DRAWABLES:
g_value_set_pointer (value, source_core->src_drawables);
break;
case PROP_SRC_X:
g_value_set_int (value, source_core->src_x);
break;
@ -251,7 +219,7 @@ gimp_source_core_start (GimpPaintCore *paint_core,
if (! source_core->set_source &&
gimp_source_core_use_source (source_core, options))
{
if (! source_core->src_drawables)
if (! options->src_drawables)
{
g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
_("Set a source image first."));
@ -267,7 +235,7 @@ gimp_source_core_start (GimpPaintCore *paint_core,
if (options->sample_merged &&
g_list_length (drawables) == 1 &&
gimp_item_get_image (GIMP_ITEM (source_core->src_drawables->data)) ==
gimp_item_get_image (GIMP_ITEM (options->src_drawables->data)) ==
gimp_item_get_image (GIMP_ITEM (drawables->data)))
{
paint_core->use_saved_proj = TRUE;
@ -297,7 +265,7 @@ gimp_source_core_paint (GimpPaintCore *paint_core,
case GIMP_PAINT_STATE_INIT:
if (source_core->set_source)
{
gimp_source_core_set_src_drawable (source_core, drawables);
g_object_set (options, "src-drawables", drawables, NULL);
/* FIXME(?): subpixel source sampling */
source_core->src_x = floor (coords->x);
@ -312,8 +280,6 @@ gimp_source_core_paint (GimpPaintCore *paint_core,
source_core->first_stroke = TRUE;
}
gimp_source_core_make_pickable (source_core);
break;
case GIMP_PAINT_STATE_MOTION:
@ -450,7 +416,7 @@ gimp_source_core_motion (GimpSourceCore *source_core,
{
GimpImage *src_image;
src_image = gimp_pickable_get_image (source_core->src_drawables->data);
src_image = gimp_pickable_get_image (options->src_drawables->data);
if (! gimp_paint_core_get_show_all (paint_core))
{
@ -463,7 +429,7 @@ gimp_source_core_motion (GimpSourceCore *source_core,
}
else
{
src_pickable = source_core->src_pickable;
src_pickable = options->src_pickable;
}
if (GIMP_IS_ITEM (src_pickable))
@ -671,8 +637,8 @@ gimp_source_core_real_get_source (GimpSourceCore *source_core,
* we get a copy of the unblemished (offset) image
*/
if (( sample_merged && (src_image != image)) ||
(! sample_merged && (g_list_length (source_core->src_drawables) != 1 ||
source_core->src_drawables->data != drawable)))
(! sample_merged && (g_list_length (options->src_drawables) != 1 ||
options->src_drawables->data != drawable)))
{
dest_buffer = src_buffer;
}
@ -695,98 +661,3 @@ gimp_source_core_real_get_source (GimpSourceCore *source_core,
return g_object_ref (dest_buffer);
}
static void
gimp_source_core_src_drawable_removed (GimpDrawable *drawable,
GimpSourceCore *source_core)
{
source_core->src_drawables = g_list_remove (source_core->src_drawables, drawable);
g_signal_handlers_disconnect_by_func (drawable,
gimp_source_core_src_drawable_removed,
source_core);
}
static void
gimp_source_core_set_src_drawable (GimpSourceCore *source_core,
GList *drawables)
{
GimpImage *image = NULL;
GList *iter;
if (g_list_length (source_core->src_drawables) == g_list_length (drawables))
{
GList *iter2;
for (iter = source_core->src_drawables, iter2 = drawables;
iter; iter = iter->next, iter2 = iter2->next)
{
if (iter->data != iter2->data)
break;
}
if (iter == NULL)
return;
}
for (GList *iter = drawables; iter; iter = iter->next)
{
/* Make sure all drawables are from the same image. */
if (image == NULL)
image = gimp_item_get_image (GIMP_ITEM (iter->data));
else
g_return_if_fail (image == gimp_item_get_image (GIMP_ITEM (iter->data)));
}
if (source_core->src_drawables)
{
for (GList *iter = source_core->src_drawables; iter; iter = iter->next)
g_signal_handlers_disconnect_by_func (iter->data,
gimp_source_core_src_drawable_removed,
source_core);
g_list_free (source_core->src_drawables);
}
source_core->src_drawables = g_list_copy (drawables);
if (source_core->src_drawables)
{
for (GList *iter = source_core->src_drawables; iter; iter = iter->next)
g_signal_connect (iter->data, "removed",
G_CALLBACK (gimp_source_core_src_drawable_removed),
source_core);
}
g_object_notify (G_OBJECT (source_core), "src-drawables");
}
static void
gimp_source_core_make_pickable (GimpSourceCore *source_core)
{
g_clear_object (&source_core->src_image);
source_core->src_pickable = NULL;
if (source_core->src_drawables)
{
GimpImage *image;
image = gimp_item_get_image (GIMP_ITEM (source_core->src_drawables->data));
if (g_list_length (source_core->src_drawables) > 1)
{
/* A composited projection of src_drawables as if they were on
* their own in the image. Some kind of sample_merged limited
* to these drawables.
*/
source_core->src_image = gimp_image_new_from_drawables (image->gimp, source_core->src_drawables,
FALSE);
gimp_container_remove (image->gimp->images, GIMP_OBJECT (source_core->src_image));
source_core->src_pickable = GIMP_PICKABLE (source_core->src_image);
gimp_pickable_flush (source_core->src_pickable);
}
else
{
source_core->src_pickable = GIMP_PICKABLE (source_core->src_drawables->data);
}
}
}

View file

@ -38,14 +38,9 @@ struct _GimpSourceCore
gboolean set_source;
GList *src_drawables;
gint src_x;
gint src_y;
/* The pickable to use when not in sample merged mode. */
GimpPickable *src_pickable;
GimpImage *src_image;
gint orig_src_x;
gint orig_src_y;

View file

@ -25,6 +25,13 @@
#include "paint-types.h"
#include "core/gimp.h"
#include "core/gimpcontainer.h"
#include "core/gimpimage.h"
#include "core/gimpimage-new.h"
#include "core/gimpitem.h"
#include "core/gimppickable.h"
#include "gimpsourceoptions.h"
#include "gimp-intl.h"
@ -33,32 +40,50 @@
enum
{
PROP_0,
PROP_SRC_DRAWABLES,
PROP_ALIGN_MODE,
PROP_SAMPLE_MERGED
};
static void gimp_source_options_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_source_options_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_source_options_finalize (GObject *object);
static void gimp_source_options_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_source_options_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void
gimp_source_options_set_src_drawables (GimpSourceOptions *options,
GList *drawables);
static void
gimp_source_options_src_drawable_removed (GimpDrawable *drawable,
GimpSourceOptions *options);
static void gimp_source_options_make_pickable (GimpSourceOptions *options);
G_DEFINE_TYPE (GimpSourceOptions, gimp_source_options, GIMP_TYPE_PAINT_OPTIONS)
#define parent_class gimp_source_options_parent_class
static void
gimp_source_options_class_init (GimpSourceOptionsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gimp_source_options_finalize;
object_class->set_property = gimp_source_options_set_property;
object_class->get_property = gimp_source_options_get_property;
g_object_class_install_property (object_class, PROP_SRC_DRAWABLES,
g_param_spec_pointer ("src-drawables",
NULL, NULL,
GIMP_PARAM_READWRITE));
GIMP_CONFIG_PROP_ENUM (object_class, PROP_ALIGN_MODE,
"align-mode",
_("Alignment"),
@ -78,6 +103,18 @@ gimp_source_options_class_init (GimpSourceOptionsClass *klass)
static void
gimp_source_options_init (GimpSourceOptions *options)
{
options->src_drawables = NULL;
}
static void
gimp_source_options_finalize (GObject *object)
{
GimpSourceOptions *options = GIMP_SOURCE_OPTIONS (object);
gimp_source_options_set_src_drawables (options, NULL);
g_clear_object (&options->src_image);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
@ -90,6 +127,10 @@ gimp_source_options_set_property (GObject *object,
switch (property_id)
{
case PROP_SRC_DRAWABLES:
gimp_source_options_set_src_drawables (options,
g_value_get_pointer (value));
break;
case PROP_ALIGN_MODE:
options->align_mode = g_value_get_enum (value);
break;
@ -112,6 +153,9 @@ gimp_source_options_get_property (GObject *object,
switch (property_id)
{
case PROP_SRC_DRAWABLES:
g_value_set_pointer (value, options->src_drawables);
break;
case PROP_ALIGN_MODE:
g_value_set_enum (value, options->align_mode);
break;
@ -123,3 +167,102 @@ gimp_source_options_get_property (GObject *object,
break;
}
}
static void
gimp_source_options_set_src_drawables (GimpSourceOptions *options,
GList *drawables)
{
GimpImage *image = NULL;
GList *iter;
if (g_list_length (options->src_drawables) == g_list_length (drawables))
{
GList *iter2;
for (iter = options->src_drawables, iter2 = drawables;
iter; iter = iter->next, iter2 = iter2->next)
{
if (iter->data != iter2->data)
break;
}
if (iter == NULL)
return;
}
for (GList *iter = drawables; iter; iter = iter->next)
{
/* Make sure all drawables are from the same image. */
if (image == NULL)
image = gimp_item_get_image (GIMP_ITEM (iter->data));
else
g_return_if_fail (image == gimp_item_get_image (GIMP_ITEM (iter->data)));
}
if (options->src_drawables)
{
for (GList *iter = options->src_drawables; iter; iter = iter->next)
g_signal_handlers_disconnect_by_func (iter->data,
gimp_source_options_src_drawable_removed,
options);
g_list_free (options->src_drawables);
}
options->src_drawables = g_list_copy (drawables);
if (options->src_drawables)
{
for (GList *iter = options->src_drawables; iter; iter = iter->next)
g_signal_connect (iter->data, "removed",
G_CALLBACK (gimp_source_options_src_drawable_removed),
options);
}
gimp_source_options_make_pickable (options);
g_object_notify (G_OBJECT (options), "src-drawables");
}
static void
gimp_source_options_src_drawable_removed (GimpDrawable *drawable,
GimpSourceOptions *options)
{
options->src_drawables = g_list_remove (options->src_drawables, drawable);
g_signal_handlers_disconnect_by_func (drawable,
gimp_source_options_src_drawable_removed,
options);
gimp_source_options_make_pickable (options);
g_object_notify (G_OBJECT (options), "src-drawables");
}
static void
gimp_source_options_make_pickable (GimpSourceOptions *options)
{
g_clear_object (&options->src_image);
options->src_pickable = NULL;
if (options->src_drawables)
{
GimpImage *image;
image = gimp_item_get_image (GIMP_ITEM (options->src_drawables->data));
if (g_list_length (options->src_drawables) > 1)
{
/* A composited projection of src_drawables as if they were on
* their own in the image. Some kind of sample_merged limited
* to these drawables.
*/
options->src_image = gimp_image_new_from_drawables (image->gimp, options->src_drawables,
FALSE);
gimp_container_remove (image->gimp->images, GIMP_OBJECT (options->src_image));
options->src_pickable = GIMP_PICKABLE (options->src_image);
gimp_pickable_flush (options->src_pickable);
}
else
{
options->src_pickable = GIMP_PICKABLE (options->src_drawables->data);
}
}
}

View file

@ -36,6 +36,12 @@ struct _GimpSourceOptions
{
GimpPaintOptions parent_instance;
GList *src_drawables;
/* The pickable to use when not in sample merged mode. */
GimpPickable *src_pickable;
GimpImage *src_image;
GimpSourceAlignMode align_mode;
gboolean sample_merged;
};

View file

@ -26,6 +26,7 @@
#include "core/gimp.h"
#include "core/gimpimage.h"
#include "core/gimpitem.h"
#include "paint/gimpcloneoptions.h"
@ -38,6 +39,24 @@
#include "gimp-intl.h"
static gboolean gimp_clone_options_sync_source (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data);
static void gimp_clone_options_gui_drawables_changed (GimpImage *image,
GimpSourceOptions *options);
static void gimp_clone_options_gui_src_changed (GimpSourceOptions *options,
GParamSpec *pspec,
GtkWidget *label);
static void gimp_clone_options_gui_context_image_changed (GimpContext *context,
GimpImage *image,
GimpSourceOptions *options);
static void gimp_clone_options_gui_update_src_label (GimpSourceOptions *options,
GtkWidget *label);
static gboolean
gimp_clone_options_sync_source (GBinding *binding,
const GValue *source_value,
@ -53,39 +72,55 @@ gimp_clone_options_sync_source (GBinding *binding,
}
static void
gimp_clone_options_gui_drawables_changed (GimpImage *image,
GtkWidget *button)
gimp_clone_options_gui_drawables_changed (GimpImage *image,
GimpSourceOptions *options)
{
GList *drawables;
GList *drawables;
GtkWidget *button;
drawables = gimp_image_get_selected_drawables (image);
button = g_object_get_data (G_OBJECT (options), "sample-merged-checkbox");
gtk_widget_set_sensitive (button, (g_list_length (drawables) < 2));
g_list_free (drawables);
gimp_clone_options_gui_update_src_label (options, NULL);
}
static void
gimp_clone_options_gui_context_image_changed (GimpContext *context,
GimpImage *image,
GtkWidget *button)
gimp_clone_options_gui_src_changed (GimpSourceOptions *options,
GParamSpec *pspec,
GtkWidget *label)
{
gimp_clone_options_gui_update_src_label (options, label);
}
static void
gimp_clone_options_gui_context_image_changed (GimpContext *context,
GimpImage *image,
GimpSourceOptions *options)
{
GimpImage *prev_image;
GtkWidget *button;
button = g_object_get_data (G_OBJECT (options), "sample-merged-checkbox");
prev_image = g_object_get_data (G_OBJECT (button), "gimp-clone-options-gui-image");
if (image != prev_image)
{
if (prev_image)
g_signal_handlers_disconnect_by_func (prev_image,
G_CALLBACK (gimp_clone_options_gui_drawables_changed),
button);
options);
if (image)
{
g_signal_connect_object (image, "selected-channels-changed",
G_CALLBACK (gimp_clone_options_gui_drawables_changed),
button, 0);
options, 0);
g_signal_connect_object (image, "selected-layers-changed",
G_CALLBACK (gimp_clone_options_gui_drawables_changed),
button, 0);
gimp_clone_options_gui_drawables_changed (image, button);
options, 0);
gimp_clone_options_gui_drawables_changed (image, options);
}
else
{
@ -96,20 +131,98 @@ gimp_clone_options_gui_context_image_changed (GimpContext *context,
}
}
static void
gimp_clone_options_gui_update_src_label (GimpSourceOptions *options,
GtkWidget *label)
{
gchar *markup = NULL;
if (! label)
label = g_object_get_data (G_OBJECT (options), "src-label");
if (options->src_drawables == NULL)
{
markup = g_strdup_printf ("<i>%s</i>", _("No source selected"));
}
else
{
GimpImage *image;
GList *drawables;
gchar *str = NULL;
gboolean sample_merged;
image = gimp_context_get_image (gimp_get_user_context (GIMP_CONTEXT (options)->gimp));
drawables = gimp_image_get_selected_drawables (image);
sample_merged = options->sample_merged && g_list_length (drawables) == 1;
if (g_list_length (drawables) > 1)
{
str = g_strdup_printf (ngettext ("Source: %d item to itself",
"Source: %d items to themselves",
g_list_length (drawables)),
g_list_length (drawables));
}
else
{
GimpImage *src_image = NULL;
src_image = gimp_item_get_image (options->src_drawables->data);
if (sample_merged)
{
if (image == src_image)
str = g_strdup (_("All composited visible layers"));
else
str = g_strdup_printf (_("All composited visible layers from '%s'"),
gimp_image_get_display_name (src_image));
}
else
{
if (image == src_image)
str = g_strdup_printf (ngettext ("Source: %d item",
"Source: %d items",
g_list_length (options->src_drawables)),
g_list_length (options->src_drawables));
else
str = g_strdup_printf (ngettext ("Source: %d item from '%s'",
"Source: %d items from '%s'",
g_list_length (options->src_drawables)),
g_list_length (options->src_drawables),
gimp_image_get_display_name (src_image));
}
}
markup = g_strdup_printf ("<i>%s</i>", str);
g_list_free (drawables);
g_free (str);
}
gtk_label_set_markup (GTK_LABEL (label), markup);
g_free (markup);
}
/* Public functions. */
GtkWidget *
gimp_clone_options_gui (GimpToolOptions *tool_options)
{
GObject *config = G_OBJECT (tool_options);
GtkWidget *vbox = gimp_paint_options_gui (tool_options);
GtkWidget *frame;
GtkWidget *label;
GtkWidget *combo;
GtkWidget *source_vbox;
GtkWidget *button;
GtkWidget *hbox;
gchar *str;
/* the source frame */
frame = gimp_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_box_reorder_child (GTK_BOX (vbox), frame, 2);
gtk_widget_show (frame);
/* the source type menu */
@ -123,6 +236,7 @@ gimp_clone_options_gui (GimpToolOptions *tool_options)
gtk_widget_show (source_vbox);
button = gimp_prop_check_button_new (config, "sample-merged", NULL);
g_object_set_data (G_OBJECT (tool_options), "sample-merged-checkbox", button);
gtk_box_pack_start (GTK_BOX (source_vbox), button, FALSE, FALSE, 0);
g_object_bind_property_full (config, "clone-type",
@ -132,10 +246,26 @@ gimp_clone_options_gui (GimpToolOptions *tool_options)
NULL,
GINT_TO_POINTER (GIMP_CLONE_IMAGE), NULL);
label = gtk_label_new (NULL);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
str = g_strdup_printf ("<i>%s</i>", _("No source selected"));
gtk_label_set_markup (GTK_LABEL (label), str);
g_object_set_data (G_OBJECT (tool_options), "src-label", label);
g_free (str);
gtk_box_pack_start (GTK_BOX (source_vbox), label, FALSE, FALSE, 0);
g_object_bind_property_full (config, "clone-type",
label, "visible",
G_BINDING_SYNC_CREATE,
gimp_clone_options_sync_source,
NULL,
GINT_TO_POINTER (GIMP_CLONE_IMAGE), NULL);
g_signal_connect (gimp_get_user_context (GIMP_CONTEXT (tool_options)->gimp),
"image-changed",
G_CALLBACK (gimp_clone_options_gui_context_image_changed),
button);
tool_options);
hbox = gimp_prop_pattern_box_new (NULL, GIMP_CONTEXT (tool_options),
NULL, 2,
@ -153,6 +283,16 @@ gimp_clone_options_gui (GimpToolOptions *tool_options)
gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Alignment"));
g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
gtk_box_pack_start (GTK_BOX (vbox), combo, TRUE, TRUE, 0);
gtk_box_reorder_child (GTK_BOX (vbox), combo, 3);
/* A few options which can trigger a change in the source label. */
g_signal_connect (config, "notify::src-drawables",
G_CALLBACK (gimp_clone_options_gui_src_changed),
label);
g_signal_connect (config, "notify::sample-merged",
G_CALLBACK (gimp_clone_options_gui_src_changed),
label);
gimp_clone_options_gui_src_changed (GIMP_SOURCE_OPTIONS (config), NULL, label);
return vbox;
}

View file

@ -563,7 +563,7 @@ gimp_perspective_clone_tool_cursor_update (GimpTool *tool,
{
cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
}
else if (! GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core)->src_drawables)
else if (! GIMP_SOURCE_OPTIONS (options)->src_drawables)
{
modifier = GIMP_CURSOR_MODIFIER_BAD;
}
@ -621,7 +621,7 @@ gimp_perspective_clone_tool_oper_update (GimpTool *tool,
GimpPerspectiveClone *clone = GIMP_PERSPECTIVE_CLONE (core);
GimpSourceCore *source_core = GIMP_SOURCE_CORE (core);
if (source_core->src_drawables == NULL)
if (GIMP_SOURCE_OPTIONS (options)->src_drawables == NULL)
{
gimp_tool_replace_status (tool, display,
_("Ctrl-Click to set a clone source"));
@ -708,8 +708,6 @@ gimp_perspective_clone_tool_draw (GimpDrawTool *draw_tool)
{
GimpTool *tool = GIMP_TOOL (draw_tool);
GimpPerspectiveCloneTool *clone_tool = GIMP_PERSPECTIVE_CLONE_TOOL (draw_tool);
GimpPerspectiveClone *clone = GIMP_PERSPECTIVE_CLONE (GIMP_PAINT_TOOL (tool)->core);
GimpSourceCore *source_core = GIMP_SOURCE_CORE (clone);
GimpPerspectiveCloneOptions *options;
options = GIMP_PERSPECTIVE_CLONE_TOOL_GET_OPTIONS (tool);
@ -756,7 +754,7 @@ gimp_perspective_clone_tool_draw (GimpDrawTool *draw_tool)
gimp_draw_tool_pop_group (draw_tool);
}
if (source_core->src_drawables && clone_tool->src_display)
if (GIMP_SOURCE_OPTIONS (options)->src_drawables && clone_tool->src_display)
{
GimpDisplay *tmp_display;
@ -780,11 +778,14 @@ gimp_perspective_clone_tool_draw (GimpDrawTool *draw_tool)
static void
gimp_perspective_clone_tool_halt (GimpPerspectiveCloneTool *clone_tool)
{
GimpTool *tool = GIMP_TOOL (clone_tool);
GimpTool *tool = GIMP_TOOL (clone_tool);
GimpPerspectiveCloneOptions *options;
options = GIMP_PERSPECTIVE_CLONE_TOOL_GET_OPTIONS (tool);
clone_tool->src_display = NULL;
g_object_set (GIMP_PAINT_TOOL (tool)->core,
g_object_set (options,
"src-drawables", NULL,
NULL);

View file

@ -157,7 +157,8 @@ gimp_source_tool_control (GimpTool *tool,
GimpToolAction action,
GimpDisplay *display)
{
GimpSourceTool *source_tool = GIMP_SOURCE_TOOL (tool);
GimpSourceTool *source_tool = GIMP_SOURCE_TOOL (tool);
GimpSourceOptions *options = GIMP_SOURCE_TOOL_GET_OPTIONS (tool);
switch (action)
{
@ -167,7 +168,7 @@ gimp_source_tool_control (GimpTool *tool,
case GIMP_TOOL_ACTION_HALT:
gimp_source_tool_set_src_display (source_tool, NULL);
g_object_set (GIMP_PAINT_TOOL (tool)->core,
g_object_set (options,
"src-drawables", NULL,
NULL);
break;
@ -302,7 +303,7 @@ gimp_source_tool_cursor_update (GimpTool *tool,
{
cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
}
else if (! GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core)->src_drawables)
else if (! options->src_drawables)
{
modifier = GIMP_CURSOR_MODIFIER_BAD;
}
@ -341,7 +342,7 @@ gimp_source_tool_oper_update (GimpTool *tool,
if (gimp_source_core_use_source (source, options))
{
if (source->src_drawables == NULL)
if (options->src_drawables == NULL)
{
GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask ();
@ -400,7 +401,7 @@ gimp_source_tool_draw (GimpDrawTool *draw_tool)
GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool);
if (gimp_source_core_use_source (source, options) &&
source->src_drawables && source_tool->src_display)
options->src_drawables && source_tool->src_display)
{
GimpDisplayShell *src_shell;
gdouble src_x;