Foreground-select Tool: new Preview Mode and color selector for "On color" preview

This commit adds a new preview called "Grayscale", allowing to see the
resulting mask in black and white. The previous preview is now called
"On color" and allow users to choose the color and opacity, instead of
imposing only 4 colors (red, green, blue, grey).
This commit is contained in:
Thomas Manni 2019-06-13 14:46:23 +02:00 committed by Jehan
parent ac8ad13f0a
commit d6bcb16b0b
6 changed files with 153 additions and 61 deletions

View File

@ -26,6 +26,7 @@
#include "tools-types.h"
#include "widgets/gimpcolorpanel.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpspinscale.h"
#include "widgets/gimpwidgets-constructors.h"
@ -46,6 +47,7 @@ enum
{
PROP_0,
PROP_DRAW_MODE,
PROP_PREVIEW_MODE,
PROP_STROKE_WIDTH,
PROP_MASK_COLOR,
PROP_ENGINE,
@ -73,6 +75,7 @@ static void
gimp_foreground_select_options_class_init (GimpForegroundSelectOptionsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpRGB blue = {0.0, 0.0, 1.0, 0.5};
object_class->set_property = gimp_foreground_select_options_set_property;
object_class->get_property = gimp_foreground_select_options_get_property;
@ -88,6 +91,14 @@ gimp_foreground_select_options_class_init (GimpForegroundSelectOptionsClass *kla
GIMP_MATTING_DRAW_MODE_FOREGROUND,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_ENUM (object_class, PROP_PREVIEW_MODE,
"preview-mode",
_("Preview Mode"),
_("Preview Mode"),
GIMP_TYPE_MATTING_PREVIEW_MODE,
GIMP_MATTING_PREVIEW_MODE_ON_COLOR,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_INT (object_class, PROP_STROKE_WIDTH,
"stroke-width",
_("Stroke width"),
@ -95,12 +106,12 @@ gimp_foreground_select_options_class_init (GimpForegroundSelectOptionsClass *kla
1, 6000, 10,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_ENUM (object_class, PROP_MASK_COLOR,
GIMP_CONFIG_PROP_RGB (object_class, PROP_MASK_COLOR,
"mask-color",
_("Preview color"),
_("Color of selection preview mask"),
GIMP_TYPE_CHANNEL_TYPE,
GIMP_CHANNEL_BLUE,
GIMP_TYPE_RGB,
&blue,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_ENUM (object_class, PROP_ENGINE,
@ -145,6 +156,7 @@ gimp_foreground_select_options_set_property (GObject *object,
GParamSpec *pspec)
{
GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_OPTIONS (object);
GimpRGB *color;
switch (property_id)
{
@ -152,12 +164,17 @@ gimp_foreground_select_options_set_property (GObject *object,
options->draw_mode = g_value_get_enum (value);
break;
case PROP_PREVIEW_MODE:
options->preview_mode = g_value_get_enum (value);
break;
case PROP_STROKE_WIDTH:
options->stroke_width = g_value_get_int (value);
break;
case PROP_MASK_COLOR:
options->mask_color = g_value_get_enum (value);
color = g_value_get_boxed (value);
options->mask_color = *color;
break;
case PROP_ENGINE:
@ -201,12 +218,16 @@ gimp_foreground_select_options_get_property (GObject *object,
g_value_set_enum (value, options->draw_mode);
break;
case PROP_PREVIEW_MODE:
g_value_set_enum (value, options->preview_mode);
break;
case PROP_STROKE_WIDTH:
g_value_set_int (value, options->stroke_width);
break;
case PROP_MASK_COLOR:
g_value_set_enum (value, options->mask_color);
g_value_set_boxed (value, &options->mask_color);
break;
case PROP_ENGINE:
@ -299,13 +320,21 @@ gimp_foreground_select_options_gui (GimpToolOptions *tool_options)
gimp_help_set_help_data (button,
_("Reset stroke width native size"), NULL);
/* preview mode */
frame = gimp_prop_enum_radio_frame_new (config, "preview-mode", NULL,
0, 0);
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
/* mask color */
combo = gimp_prop_enum_combo_box_new (config, "mask-color",
GIMP_CHANNEL_RED, GIMP_CHANNEL_GRAY);
gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Preview color"));
g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
gtk_widget_show (combo);
button = gimp_prop_color_button_new (config, "mask-color",
NULL,
128, 24,
GIMP_COLOR_AREA_SMALL_CHECKS);
gimp_color_panel_set_context (GIMP_COLOR_PANEL (button), GIMP_CONTEXT (config));
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
/* engine */
frame = gimp_frame_new (NULL);
@ -364,34 +393,3 @@ gimp_foreground_select_options_gui (GimpToolOptions *tool_options)
return vbox;
}
void
gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
GimpRGB *color)
{
g_return_if_fail (GIMP_IS_FOREGROUND_SELECT_OPTIONS (options));
g_return_if_fail (color != NULL);
switch (options->mask_color)
{
case GIMP_CHANNEL_RED:
gimp_rgba_set (color, 1, 0, 0, 0.7);
break;
case GIMP_CHANNEL_GREEN:
gimp_rgba_set (color, 0, 1, 0, 0.7);
break;
case GIMP_CHANNEL_BLUE:
gimp_rgba_set (color, 0, 0, 1, 0.7);
break;
case GIMP_CHANNEL_GRAY:
gimp_rgba_set (color, 1, 1, 1, 0.7);
break;
default:
g_warn_if_reached ();
break;
}
}

View File

@ -38,13 +38,14 @@ struct _GimpForegroundSelectOptions
{
GimpSelectionOptions parent_instance;
GimpMattingDrawMode draw_mode;
gint stroke_width;
GimpChannelType mask_color;
GimpMattingEngine engine;
gint levels;
gint active_levels;
gint iterations;
GimpMattingDrawMode draw_mode;
GimpMattingPreviewMode preview_mode;
gint stroke_width;
GimpRGB mask_color;
GimpMattingEngine engine;
gint levels;
gint active_levels;
gint iterations;
};
struct _GimpForegroundSelectOptionsClass
@ -57,8 +58,6 @@ GType gimp_foreground_select_options_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_foreground_select_options_gui (GimpToolOptions *tool_options);
void gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
GimpRGB *color);
#endif /* __GIMP_FOREGROUND_SELECT_OPTIONS_H__ */

View File

@ -49,6 +49,8 @@
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpwidgets-utils.h"
#include "display/gimpcanvasitem.h"
#include "display/gimpcanvasbufferpreview.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimptoolgui.h"
@ -246,6 +248,7 @@ gimp_foreground_select_tool_init (GimpForegroundSelectTool *fg_select)
"tools/tools-foreground-select-brush-size-set");
fg_select->state = MATTING_STATE_FREE_SELECT;
fg_select->grayscale_preview = NULL;
}
static void
@ -776,7 +779,8 @@ gimp_foreground_select_tool_options_notify (GimpTool *tool,
if (! tool->display)
return;
if (! strcmp (pspec->name, "mask-color"))
if (! strcmp (pspec->name, "mask-color") ||
! strcmp (pspec->name, "preview-mode"))
{
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
{
@ -889,6 +893,9 @@ gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool)
x - radius, y - radius,
2 * radius, 2 * radius,
0.0, 2.0 * G_PI);
if (fg_select->grayscale_preview)
gimp_draw_tool_add_preview (draw_tool, fg_select->grayscale_preview);
}
}
@ -920,6 +927,10 @@ gimp_foreground_select_tool_confirm (GimpPolygonSelectTool *poly_sel,
0, 0, 0.5);
gimp_scan_convert_free (scan_convert);
fg_select->grayscale_preview =
gimp_canvas_buffer_preview_new (gimp_display_get_shell (display),
fg_select->trimap);
gimp_foreground_select_tool_set_trimap (fg_select);
}
}
@ -927,8 +938,15 @@ gimp_foreground_select_tool_confirm (GimpPolygonSelectTool *poly_sel,
static void
gimp_foreground_select_tool_halt (GimpForegroundSelectTool *fg_select)
{
GimpTool *tool = GIMP_TOOL (fg_select);
GimpTool *tool = GIMP_TOOL (fg_select);
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (fg_select);
if (draw_tool->preview)
{
gimp_draw_tool_remove_preview (draw_tool, fg_select->grayscale_preview);
}
g_clear_object (&fg_select->grayscale_preview);
g_clear_object (&fg_select->trimap);
g_clear_object (&fg_select->mask);
@ -1009,7 +1027,6 @@ gimp_foreground_select_tool_set_trimap (GimpForegroundSelectTool *fg_select)
{
GimpTool *tool = GIMP_TOOL (fg_select);
GimpForegroundSelectOptions *options;
GimpRGB color;
g_return_if_fail (fg_select->trimap != NULL);
@ -1017,9 +1034,28 @@ gimp_foreground_select_tool_set_trimap (GimpForegroundSelectTool *fg_select)
gimp_polygon_select_tool_halt (GIMP_POLYGON_SELECT_TOOL (fg_select));
gimp_foreground_select_options_get_mask_color (options, &color);
gimp_display_shell_set_mask (gimp_display_get_shell (tool->display),
fg_select->trimap, 0, 0, &color, TRUE);
if (options->preview_mode == GIMP_MATTING_PREVIEW_MODE_ON_COLOR)
{
if (fg_select->grayscale_preview)
gimp_canvas_item_set_visible (fg_select->grayscale_preview, FALSE);
gimp_display_shell_set_mask (gimp_display_get_shell (tool->display),
fg_select->trimap, 0, 0,
&options->mask_color, TRUE);
}
else
{
gimp_display_shell_set_mask (gimp_display_get_shell (tool->display),
NULL, 0, 0, NULL, FALSE);
if (fg_select->grayscale_preview)
{
g_object_set (fg_select->grayscale_preview, "buffer",
fg_select->trimap, NULL);
gimp_canvas_item_set_visible (fg_select->grayscale_preview, TRUE);
}
}
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PAINTBRUSH);
@ -1046,15 +1082,32 @@ gimp_foreground_select_tool_set_preview (GimpForegroundSelectTool *fg_select)
GimpTool *tool = GIMP_TOOL (fg_select);
GimpForegroundSelectOptions *options;
GimpRGB color;
g_return_if_fail (fg_select->mask != NULL);
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
gimp_foreground_select_options_get_mask_color (options, &color);
gimp_display_shell_set_mask (gimp_display_get_shell (tool->display),
fg_select->mask, 0, 0, &color, TRUE);
if (options->preview_mode == GIMP_MATTING_PREVIEW_MODE_ON_COLOR)
{
if (fg_select->grayscale_preview)
gimp_canvas_item_set_visible (fg_select->grayscale_preview, FALSE);
gimp_display_shell_set_mask (gimp_display_get_shell (tool->display),
fg_select->mask, 0, 0,
&options->mask_color, TRUE);
}
else
{
gimp_display_shell_set_mask (gimp_display_get_shell (tool->display),
NULL, 0, 0, NULL, FALSE);
if (fg_select->grayscale_preview)
{
g_object_set (fg_select->grayscale_preview, "buffer",
fg_select->mask, NULL);
gimp_canvas_item_set_visible (fg_select->grayscale_preview, TRUE);
}
}
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PAINTBRUSH);

View File

@ -59,6 +59,8 @@ struct _GimpForegroundSelectTool
GimpToolGui *gui;
GtkWidget *preview_toggle;
GimpCanvasItem *grayscale_preview;
};
struct _GimpForegroundSelectToolClass

View File

@ -230,6 +230,35 @@ gimp_matting_draw_mode_get_type (void)
return type;
}
GType
gimp_matting_preview_mode_get_type (void)
{
static const GEnumValue values[] =
{
{ GIMP_MATTING_PREVIEW_MODE_ON_COLOR, "GIMP_MATTING_PREVIEW_MODE_ON_COLOR", "on-color" },
{ GIMP_MATTING_PREVIEW_MODE_GRAYSCALE, "GIMP_MATTING_PREVIEW_MODE_GRAYSCALE", "grayscale" },
{ 0, NULL, NULL }
};
static const GimpEnumDesc descs[] =
{
{ GIMP_MATTING_PREVIEW_MODE_ON_COLOR, NC_("matting-preview-mode", "On color"), NULL },
{ GIMP_MATTING_PREVIEW_MODE_GRAYSCALE, NC_("matting-preview-mode", "Grayscale"), NULL },
{ 0, NULL, NULL }
};
static GType type = 0;
if (G_UNLIKELY (! type))
{
type = g_enum_register_static ("GimpMattingPreviewMode", values);
gimp_type_set_translation_context (type, "matting-preview-mode");
gimp_enum_set_value_descriptions (type, descs);
}
return type;
}
GType
gimp_warp_behavior_get_type (void)
{

View File

@ -126,6 +126,17 @@ typedef enum
} GimpMattingDrawMode;
#define GIMP_TYPE_MATTING_PREVIEW_MODE (gimp_matting_preview_mode_get_type ())
GType gimp_matting_preview_mode_get_type (void) G_GNUC_CONST;
typedef enum
{
GIMP_MATTING_PREVIEW_MODE_ON_COLOR, /*< desc="On color" >*/
GIMP_MATTING_PREVIEW_MODE_GRAYSCALE, /*< desc="Grayscale" >*/
} GimpMattingPreviewMode;
#define GIMP_TYPE_WARP_BEHAVIOR (gimp_warp_behavior_get_type ())
GType gimp_warp_behavior_get_type (void) G_GNUC_CONST;