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:
parent
370db868a3
commit
6ad00cdbba
8 changed files with 334 additions and 177 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue