diff --git a/app/core/gimpdrawable-offset.c b/app/core/gimpdrawable-offset.c index b7f5eb21fc..b0e1fc03fc 100644 --- a/app/core/gimpdrawable-offset.c +++ b/app/core/gimpdrawable-offset.c @@ -39,6 +39,7 @@ gimp_drawable_offset (GimpDrawable *drawable, GimpContext *context, gboolean wrap_around, GimpOffsetType fill_type, + GeglColor *color, gint offset_x, gint offset_y) { @@ -69,12 +70,22 @@ gimp_drawable_offset (GimpDrawable *drawable, node = gegl_node_new_child (NULL, "operation", "gimp:offset", - "context", context, - "type", fill_type, - "x", offset_x, - "y", offset_y, + "type", fill_type, + "x", offset_x, + "y", offset_y, NULL); + if (color == NULL) + { + color = gegl_color_duplicate (gimp_context_get_background (context)); + gegl_node_set (node, "color", color, NULL); + g_object_unref (color); + } + else + { + gegl_node_set (node, "color", color, NULL); + } + gimp_drawable_apply_operation (drawable, NULL, C_("undo-type", "Offset Drawable"), node); diff --git a/app/core/gimpdrawable-offset.h b/app/core/gimpdrawable-offset.h index 662915024f..f41a1b53ff 100644 --- a/app/core/gimpdrawable-offset.h +++ b/app/core/gimpdrawable-offset.h @@ -23,6 +23,7 @@ void gimp_drawable_offset (GimpDrawable *drawable, GimpContext *context, gboolean wrap_around, GimpOffsetType fill_type, + GeglColor *color, gint offset_x, gint offset_y); diff --git a/app/operations/gimpoperationoffset.c b/app/operations/gimpoperationoffset.c index 788fa268ad..2c06129a13 100644 --- a/app/operations/gimpoperationoffset.c +++ b/app/operations/gimpoperationoffset.c @@ -24,6 +24,8 @@ #include #include +#include "libgimpcolor/gimpcolor.h" + #include "operations-types.h" #include "gegl/gimp-gegl-loops.h" @@ -39,7 +41,7 @@ enum { PROP_0, - PROP_CONTEXT, + PROP_COLOR, PROP_TYPE, PROP_X, PROP_Y @@ -118,13 +120,13 @@ gimp_operation_offset_class_init (GimpOperationOffsetClass *klass) "description", _("Shift the pixels, optionally wrapping them at the borders"), NULL); - g_object_class_install_property (object_class, PROP_CONTEXT, - g_param_spec_object ("context", - "Context", - "A GimpContext", - GIMP_TYPE_CONTEXT, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_COLOR, + gimp_param_spec_color_from_string ("color", + _("Fill Color"), + _("Fill Color"), + FALSE, "white", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, PROP_TYPE, g_param_spec_enum ("type", @@ -162,7 +164,7 @@ gimp_operation_offset_dispose (GObject *object) { GimpOperationOffset *offset = GIMP_OPERATION_OFFSET (object); - g_clear_object (&offset->context); + g_object_unref (offset->color); G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -177,8 +179,8 @@ gimp_operation_offset_get_property (GObject *object, switch (property_id) { - case PROP_CONTEXT: - g_value_set_object (value, offset->context); + case PROP_COLOR: + g_value_set_object (value, offset->color); break; case PROP_TYPE: @@ -201,16 +203,17 @@ gimp_operation_offset_get_property (GObject *object, static void gimp_operation_offset_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) + guint property_id, + const GValue *value, + GParamSpec *pspec) { GimpOperationOffset *offset = GIMP_OPERATION_OFFSET (object); switch (property_id) { - case PROP_CONTEXT: - g_set_object (&offset->context, g_value_get_object (value)); + case PROP_COLOR: + g_clear_object (&offset->color); + offset->color = gegl_color_duplicate (g_value_get_object (value)); break; case PROP_TYPE: @@ -293,9 +296,7 @@ gimp_operation_offset_parent_process (GeglOperation *operation, return TRUE; } - else if (offset->type == GIMP_OFFSET_TRANSPARENT || - (offset->type == GIMP_OFFSET_BACKGROUND && - ! offset->context)) + else if (offset->type == GIMP_OFFSET_TRANSPARENT) { GObject *output = NULL; @@ -346,7 +347,6 @@ gimp_operation_offset_process (GeglOperation *operation, gint level) { GimpOperationOffset *offset = GIMP_OPERATION_OFFSET (operation); - GeglColor *color = NULL; GeglRectangle bounds; gint x; gint y; @@ -356,9 +356,6 @@ gimp_operation_offset_process (GeglOperation *operation, gimp_operation_offset_get_offset (offset, FALSE, &x, &y); - if (offset->type == GIMP_OFFSET_BACKGROUND && offset->context) - color = gimp_context_get_background (offset->context); - for (i = 0; i < 4; i++) { GeglRectangle offset_bounds = bounds; @@ -385,9 +382,9 @@ gimp_operation_offset_process (GeglOperation *operation, gimp_gegl_buffer_copy (input, &offset_roi, GEGL_ABYSS_NONE, output, &offset_bounds); } - else if (color) + else if (offset->color) { - gegl_buffer_set_color (output, &offset_bounds, color); + gegl_buffer_set_color (output, &offset_bounds, offset->color); } } } diff --git a/app/operations/gimpoperationoffset.h b/app/operations/gimpoperationoffset.h index dcd0e0b320..edc567029c 100644 --- a/app/operations/gimpoperationoffset.h +++ b/app/operations/gimpoperationoffset.h @@ -37,7 +37,7 @@ struct _GimpOperationOffset { GeglOperationFilter parent_instance; - GimpContext *context; + GeglColor *color; GimpOffsetType type; gint x; gint y; diff --git a/app/pdb/drawable-cmds.c b/app/pdb/drawable-cmds.c index 8755d8c31f..9d81a5dc80 100644 --- a/app/pdb/drawable-cmds.c +++ b/app/pdb/drawable-cmds.c @@ -758,14 +758,16 @@ drawable_offset_invoker (GimpProcedure *procedure, GimpDrawable *drawable; gboolean wrap_around; gint fill_type; + GeglColor *color; gint offset_x; gint offset_y; drawable = g_value_get_object (gimp_value_array_index (args, 0)); wrap_around = g_value_get_boolean (gimp_value_array_index (args, 1)); fill_type = g_value_get_enum (gimp_value_array_index (args, 2)); - offset_x = g_value_get_int (gimp_value_array_index (args, 3)); - offset_y = g_value_get_int (gimp_value_array_index (args, 4)); + color = g_value_get_object (gimp_value_array_index (args, 3)); + offset_x = g_value_get_int (gimp_value_array_index (args, 4)); + offset_y = g_value_get_int (gimp_value_array_index (args, 5)); if (success) { @@ -773,7 +775,7 @@ drawable_offset_invoker (GimpProcedure *procedure, GIMP_PDB_ITEM_CONTENT, error) && gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)) gimp_drawable_offset (drawable, context, wrap_around, fill_type, - offset_x, offset_y); + color, offset_x, offset_y); else success = FALSE; } @@ -1737,8 +1739,15 @@ register_drawable_procs (GimpPDB *pdb) "fill type", "fill vacated regions of drawable with background or transparent", GIMP_TYPE_OFFSET_TYPE, - GIMP_OFFSET_BACKGROUND, + GIMP_OFFSET_COLOR, GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_color ("color", + "color", + "fills in the background color when fill_type is set to OFFSET-COLOR", + FALSE, + NULL, + GIMP_PARAM_READWRITE)); gimp_procedure_add_argument (procedure, g_param_spec_int ("offset-x", "offset x", diff --git a/app/tools/gimpoffsettool.c b/app/tools/gimpoffsettool.c index 4042d98d3f..9596720637 100644 --- a/app/tools/gimpoffsettool.c +++ b/app/tools/gimpoffsettool.c @@ -36,6 +36,7 @@ #include "core/gimplayermask.h" #include "widgets/gimphelp-ids.h" +#include "widgets/gimppropwidgets.h" #include "display/gimpdisplay.h" #include "display/gimptoolgui.h" @@ -101,8 +102,7 @@ static void gimp_offset_tool_half_y_clicked (GtkButton static void gimp_offset_tool_edge_behavior_toggled (GtkToggleButton *toggle, GimpOffsetTool *offset_tool); -static void gimp_offset_tool_background_changed (GimpContext *context, - GeglColor *color, +static void gimp_offset_tool_color_changed (GimpColorButton *button, GimpOffsetTool *offset_tool); static gint gimp_offset_tool_get_width (GimpOffsetTool *offset_tool); @@ -175,6 +175,7 @@ gimp_offset_tool_initialize (GimpTool *tool, GimpContext *context = GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (tool)); GimpImage *image; GimpDrawable *drawable; + GeglColor *color; gdouble xres; gdouble yres; @@ -225,14 +226,9 @@ gimp_offset_tool_initialize (GimpTool *tool, gimp_offset_tool_offset_changed, offset_tool); - gegl_node_set ( - filter_tool->operation, - "context", context, - NULL); - - g_signal_connect (context, "background-changed", - G_CALLBACK (gimp_offset_tool_background_changed), - offset_tool); + color = gegl_color_duplicate (gimp_context_get_background (context)); + gegl_node_set (filter_tool->operation, "color", color, NULL); + g_object_unref (color); gimp_offset_tool_update (offset_tool); @@ -467,6 +463,8 @@ gimp_offset_tool_dialog (GimpFilterTool *filter_tool) GtkWidget *spinbutton; GtkWidget *frame; GtkAdjustment *adjustment; + GeglColor *color = NULL; + gint type = 0; main_vbox = gimp_filter_tool_dialog_get_vbox (filter_tool); @@ -540,6 +538,11 @@ gimp_offset_tool_dialog (GimpFilterTool *filter_tool) G_CALLBACK (gimp_offset_tool_half_y_clicked), offset_tool); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_widget_set_halign (hbox, GTK_ALIGN_START); + gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0); + gtk_widget_set_visible (hbox, TRUE); + /* The edge behavior frame */ frame = gimp_int_radio_group_new (TRUE, _("Edge Behavior"), @@ -551,16 +554,40 @@ gimp_offset_tool_dialog (GimpFilterTool *filter_tool) _("W_rap around"), GIMP_OFFSET_WRAP_AROUND, NULL, - _("Fill with _background color"), - GIMP_OFFSET_BACKGROUND, NULL, + _("Fill with plain color"), + GIMP_OFFSET_COLOR, NULL, _("Make _transparent"), GIMP_OFFSET_TRANSPARENT, &offset_tool->transparent_radio, NULL); - gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0); gtk_widget_show (frame); + + /* Color area */ + gegl_node_get (filter_tool->operation, + "color", &color, + "type", &type, + NULL); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_widget_set_valign (vbox, GTK_ALIGN_END); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, FALSE, 0); + gtk_widget_set_visible (vbox, TRUE); + + offset_tool->color_button = gimp_color_button_new (_("Fill Color"), + 40, 24, color, + GIMP_COLOR_AREA_FLAT); + gtk_box_pack_start (GTK_BOX (vbox), offset_tool->color_button, TRUE, FALSE, 0); + if (type == GIMP_OFFSET_COLOR) + gtk_widget_set_visible (offset_tool->color_button, TRUE); + + g_signal_connect (GIMP_COLOR_BUTTON (offset_tool->color_button), + "color-changed", + G_CALLBACK (gimp_offset_tool_color_changed), + offset_tool); + g_object_unref (color); } static void @@ -632,29 +659,27 @@ gimp_offset_tool_edge_behavior_toggled (GtkToggleButton *toggle, g_object_set (GIMP_FILTER_TOOL (offset_tool)->config, "type", type, NULL); + + if (type == GIMP_OFFSET_COLOR) + gtk_widget_set_visible (offset_tool->color_button, TRUE); + else + gtk_widget_set_visible (offset_tool->color_button, FALSE); } } static void -gimp_offset_tool_background_changed (GimpContext *context, - GeglColor *color, - GimpOffsetTool *offset_tool) +gimp_offset_tool_color_changed (GimpColorButton *button, + GimpOffsetTool *offset_tool) { + GeglColor *color = gimp_color_button_get_color (button); GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (offset_tool); - GimpOffsetType type; - g_object_get (filter_tool->config, - "type", &type, - NULL); + gegl_node_set (filter_tool->operation, + "color", color, + NULL); - if (type == GIMP_OFFSET_BACKGROUND) - { - gegl_node_set (filter_tool->operation, - "context", context, - NULL); - - gimp_drawable_filter_apply (filter_tool->filter, NULL); - } + gimp_drawable_filter_apply (filter_tool->filter, NULL); + g_object_unref (color); } static gint @@ -723,11 +748,11 @@ gimp_offset_tool_update (GimpOffsetTool *offset_tool) type = orig_type; - if (tool->drawables && + if (tool->drawables && ! gimp_drawable_has_alpha (tool->drawables->data) && type == GIMP_OFFSET_TRANSPARENT) { - type = GIMP_OFFSET_BACKGROUND; + type = GIMP_OFFSET_COLOR; } if (x != orig_x || @@ -780,18 +805,31 @@ gimp_offset_tool_update (GimpOffsetTool *offset_tool) GTK_RADIO_BUTTON (offset_tool->transparent_radio), type); } + + if (offset_tool->color_button) + { + GeglColor *color; + + gegl_node_get (filter_tool->operation, "color", &color, NULL); + + g_signal_handlers_block_by_func (offset_tool->color_button, + gimp_offset_tool_color_changed, + offset_tool); + gimp_color_button_set_color (GIMP_COLOR_BUTTON (offset_tool->color_button), + color); + g_signal_handlers_unblock_by_func (offset_tool->color_button, + gimp_offset_tool_color_changed, + offset_tool); + + g_object_unref (color); + } + } static void gimp_offset_tool_halt (GimpOffsetTool *offset_tool) { - GimpContext *context = GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (offset_tool)); - offset_tool->offset_se = NULL; offset_tool->transparent_radio = NULL; - - g_signal_handlers_disconnect_by_func ( - context, - gimp_offset_tool_background_changed, - offset_tool); + offset_tool->color_button = NULL; } diff --git a/app/tools/gimpoffsettool.h b/app/tools/gimpoffsettool.h index ff651dede3..39b86ab242 100644 --- a/app/tools/gimpoffsettool.h +++ b/app/tools/gimpoffsettool.h @@ -46,6 +46,7 @@ struct _GimpOffsetTool /* dialog */ GtkWidget *offset_se; GtkWidget *transparent_radio; + GtkWidget *color_button; }; struct _GimpOffsetToolClass diff --git a/libgimp/gimpdrawable_pdb.c b/libgimp/gimpdrawable_pdb.c index 8610e972f4..8778fd9855 100644 --- a/libgimp/gimpdrawable_pdb.c +++ b/libgimp/gimpdrawable_pdb.c @@ -886,6 +886,7 @@ gimp_drawable_fill (GimpDrawable *drawable, * @drawable: The drawable to offset. * @wrap_around: wrap image around or fill vacated regions. * @fill_type: fill vacated regions of drawable with background or transparent. + * @color: fills in the background color when fill_type is set to OFFSET-COLOR. * @offset_x: offset by this amount in X direction. * @offset_y: offset by this amount in Y direction. * @@ -905,6 +906,7 @@ gboolean gimp_drawable_offset (GimpDrawable *drawable, gboolean wrap_around, GimpOffsetType fill_type, + GeglColor *color, gint offset_x, gint offset_y) { @@ -916,6 +918,7 @@ gimp_drawable_offset (GimpDrawable *drawable, GIMP_TYPE_DRAWABLE, drawable, G_TYPE_BOOLEAN, wrap_around, GIMP_TYPE_OFFSET_TYPE, fill_type, + GEGL_TYPE_COLOR, color, G_TYPE_INT, offset_x, G_TYPE_INT, offset_y, G_TYPE_NONE); diff --git a/libgimp/gimpdrawable_pdb.h b/libgimp/gimpdrawable_pdb.h index 180125d70c..c0e6723365 100644 --- a/libgimp/gimpdrawable_pdb.h +++ b/libgimp/gimpdrawable_pdb.h @@ -77,6 +77,7 @@ gboolean gimp_drawable_fill (GimpDrawable gboolean gimp_drawable_offset (GimpDrawable *drawable, gboolean wrap_around, GimpOffsetType fill_type, + GeglColor *color, gint offset_x, gint offset_y); G_GNUC_INTERNAL gboolean _gimp_drawable_thumbnail (GimpDrawable *drawable, diff --git a/libgimpbase/gimpbaseenums.c b/libgimpbase/gimpbaseenums.c index ff8e708ae5..490e08b1e5 100644 --- a/libgimpbase/gimpbaseenums.c +++ b/libgimpbase/gimpbaseenums.c @@ -1119,7 +1119,7 @@ gimp_offset_type_get_type (void) { static const GEnumValue values[] = { - { GIMP_OFFSET_BACKGROUND, "GIMP_OFFSET_BACKGROUND", "background" }, + { GIMP_OFFSET_COLOR, "GIMP_OFFSET_COLOR", "color" }, { GIMP_OFFSET_TRANSPARENT, "GIMP_OFFSET_TRANSPARENT", "transparent" }, { GIMP_OFFSET_WRAP_AROUND, "GIMP_OFFSET_WRAP_AROUND", "wrap-around" }, { 0, NULL, NULL } @@ -1127,7 +1127,7 @@ gimp_offset_type_get_type (void) static const GimpEnumDesc descs[] = { - { GIMP_OFFSET_BACKGROUND, "GIMP_OFFSET_BACKGROUND", NULL }, + { GIMP_OFFSET_COLOR, "GIMP_OFFSET_COLOR", NULL }, { GIMP_OFFSET_TRANSPARENT, "GIMP_OFFSET_TRANSPARENT", NULL }, { GIMP_OFFSET_WRAP_AROUND, "GIMP_OFFSET_WRAP_AROUND", NULL }, { 0, NULL, NULL } diff --git a/libgimpbase/gimpbaseenums.h b/libgimpbase/gimpbaseenums.h index 1ac739739c..33cbb6b192 100644 --- a/libgimpbase/gimpbaseenums.h +++ b/libgimpbase/gimpbaseenums.h @@ -750,7 +750,7 @@ typedef enum /** * GimpOffsetType: - * @GIMP_OFFSET_BACKGROUND: Background + * @GIMP_OFFSET_COLOR: Color * @GIMP_OFFSET_TRANSPARENT: Transparent * @GIMP_OFFSET_WRAP_AROUND: Wrap image around * @@ -762,7 +762,7 @@ GType gimp_offset_type_get_type (void) G_GNUC_CONST; typedef enum { - GIMP_OFFSET_BACKGROUND, + GIMP_OFFSET_COLOR, GIMP_OFFSET_TRANSPARENT, GIMP_OFFSET_WRAP_AROUND } GimpOffsetType; diff --git a/pdb/enums.pl b/pdb/enums.pl index 7884897929..623f059471 100644 --- a/pdb/enums.pl +++ b/pdb/enums.pl @@ -357,9 +357,9 @@ package Gimp::CodeGen::enums; GimpOffsetType => { contig => 1, header => 'libgimpbase/gimpbaseenums.h', - symbols => [ qw(GIMP_OFFSET_BACKGROUND GIMP_OFFSET_TRANSPARENT + symbols => [ qw(GIMP_OFFSET_COLOR GIMP_OFFSET_TRANSPARENT GIMP_OFFSET_WRAP_AROUND) ], - mapping => { GIMP_OFFSET_BACKGROUND => '0', + mapping => { GIMP_OFFSET_COLOR => '0', GIMP_OFFSET_TRANSPARENT => '1', GIMP_OFFSET_WRAP_AROUND => '2' } }, diff --git a/pdb/groups/drawable.pdb b/pdb/groups/drawable.pdb index 18ecb53fa2..71600fb34d 100644 --- a/pdb/groups/drawable.pdb +++ b/pdb/groups/drawable.pdb @@ -936,6 +936,9 @@ HELP { name => 'fill_type', type => 'enum GimpOffsetType', desc => 'fill vacated regions of drawable with background or transparent' }, + { name => 'color', type => 'geglcolor', + desc => 'fills in the background color when fill_type is + set to OFFSET-COLOR' }, { name => 'offset_x', type => 'int32', desc => 'offset by this amount in X direction' }, { name => 'offset_y', type => 'int32', @@ -949,7 +952,7 @@ HELP GIMP_PDB_ITEM_CONTENT, error) && gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)) gimp_drawable_offset (drawable, context, wrap_around, fill_type, - offset_x, offset_y); + color, offset_x, offset_y); else success = FALSE; }