mirror of https://github.com/GNOME/gimp.git
Improve Foreground Select tool's GUI
* Add a dialog with Preview, Apply, and Reset buttons instead of depending only on hidden keyboard shortcuts. * Change default paint mode to Unknown. * Disable engine list when there is only one engine available. * Hide useless Anti-Alias toggle. * Write to selection instead of the layer mask.
This commit is contained in:
parent
33b7c897de
commit
e9d3bf8f19
|
@ -228,6 +228,7 @@ static const GimpDialogFactoryEntry entries[] =
|
|||
FOREIGN ("gimp-crop-tool-dialog", TRUE, FALSE),
|
||||
FOREIGN ("gimp-curves-tool-dialog", TRUE, TRUE),
|
||||
FOREIGN ("gimp-desaturate-tool-dialog", TRUE, FALSE),
|
||||
FOREIGN ("gimp-foreground-select-tool-dialog", TRUE, FALSE),
|
||||
FOREIGN ("gimp-gegl-tool-dialog", TRUE, FALSE),
|
||||
FOREIGN ("gimp-hue-saturation-tool-dialog", TRUE, FALSE),
|
||||
FOREIGN ("gimp-levels-tool-dialog", TRUE, TRUE),
|
||||
|
|
|
@ -84,7 +84,7 @@ gimp_foreground_select_options_class_init (GimpForegroundSelectOptionsClass *kla
|
|||
N_("Paint over areas to mark color values for "
|
||||
"inclusion or exclusion from selection"),
|
||||
GIMP_TYPE_MATTING_DRAW_MODE,
|
||||
GIMP_MATTING_DRAW_MODE_FOREGROUND,
|
||||
GIMP_MATTING_DRAW_MODE_UNKNOWN,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_STROKE_WIDTH,
|
||||
|
@ -155,6 +155,11 @@ gimp_foreground_select_options_set_property (GObject *object,
|
|||
|
||||
case PROP_ENGINE:
|
||||
options->engine = g_value_get_enum (value);
|
||||
if ((options->engine == GIMP_MATTING_ENGINE_LEVIN) &&
|
||||
!(gegl_has_operation ("gegl:matting-levin")))
|
||||
{
|
||||
options->engine = GIMP_MATTING_ENGINE_GLOBAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_LEVELS:
|
||||
|
@ -251,6 +256,10 @@ gimp_foreground_select_options_gui (GimpToolOptions *tool_options)
|
|||
GtkWidget *scale;
|
||||
GtkWidget *combo;
|
||||
GtkWidget *inner_vbox;
|
||||
GtkWidget *antialias_toggle;
|
||||
|
||||
antialias_toggle = GIMP_SELECTION_OPTIONS (tool_options)->antialias_toggle;
|
||||
gtk_widget_hide (antialias_toggle);
|
||||
|
||||
frame = gimp_prop_enum_radio_frame_new (config, "draw-mode", _("Draw Mode"),
|
||||
0,0);
|
||||
|
@ -301,6 +310,9 @@ gimp_foreground_select_options_gui (GimpToolOptions *tool_options)
|
|||
gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Engine"));
|
||||
g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
|
||||
gtk_frame_set_label_widget (GTK_FRAME (frame), combo);
|
||||
|
||||
if (!gegl_has_operation ("gegl:matting-levin"))
|
||||
gtk_widget_set_sensitive (combo, FALSE);
|
||||
gtk_widget_show (combo);
|
||||
|
||||
inner_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
||||
|
@ -350,25 +362,6 @@ gimp_foreground_select_options_gui (GimpToolOptions *tool_options)
|
|||
return vbox;
|
||||
}
|
||||
|
||||
gdouble
|
||||
gimp_foreground_select_options_get_opacity (GimpForegroundSelectOptions *options)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_FOREGROUND_SELECT_OPTIONS (options), 0.0);
|
||||
|
||||
switch (options->draw_mode)
|
||||
{
|
||||
case GIMP_MATTING_DRAW_MODE_FOREGROUND:
|
||||
return 1.0;
|
||||
|
||||
case GIMP_MATTING_DRAW_MODE_BACKGROUND:
|
||||
return 0.0;
|
||||
|
||||
case GIMP_MATTING_DRAW_MODE_UNKNOWN:
|
||||
default:
|
||||
return 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
|
||||
GimpRGB *color)
|
||||
|
|
|
@ -59,7 +59,6 @@ GtkWidget * gimp_foreground_select_options_gui (GimpToolOptions
|
|||
|
||||
void gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
|
||||
GimpRGB *color);
|
||||
gdouble gimp_foreground_select_options_get_opacity (GimpForegroundSelectOptions *options);
|
||||
|
||||
|
||||
#endif /* __GIMP_FOREGROUND_SELECT_OPTIONS_H__ */
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "gegl/gimp-gegl-mask.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpchannel-select.h"
|
||||
#include "core/gimpdrawable-foreground-extract.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimplayer.h"
|
||||
|
@ -47,6 +48,7 @@
|
|||
|
||||
#include "display/gimpdisplay.h"
|
||||
#include "display/gimpdisplayshell.h"
|
||||
#include "display/gimptoolgui.h"
|
||||
|
||||
#include "gimpforegroundselecttool.h"
|
||||
#include "gimpforegroundselectoptions.h"
|
||||
|
@ -54,6 +56,9 @@
|
|||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
#define RESPONSE_RESET 1
|
||||
#define RESPONSE_PREVIEW 2
|
||||
#define RESPONSE_APPLY 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -130,6 +135,13 @@ static void gimp_foreground_select_tool_stroke_paint (GimpForegroundSelectTo
|
|||
GimpDisplay *display,
|
||||
GimpForegroundSelectOptions *options);
|
||||
|
||||
static void gimp_foreground_select_tool_update_gui (GimpForegroundSelectTool *fg_select);
|
||||
|
||||
|
||||
static void gimp_foreground_select_tool_response (GimpToolGui *gui,
|
||||
gint response_id,
|
||||
GimpForegroundSelectTool *fg_select);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpForegroundSelectTool, gimp_foreground_select_tool,
|
||||
GIMP_TYPE_FREE_SELECT_TOOL)
|
||||
|
@ -203,6 +215,7 @@ gimp_foreground_select_tool_init (GimpForegroundSelectTool *fg_select)
|
|||
fg_select->mask = NULL;
|
||||
fg_select->trimap = NULL;
|
||||
fg_select->state = MATTING_STATE_FREE_SELECT;
|
||||
fg_select->gui = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -222,6 +235,12 @@ gimp_foreground_select_tool_finalize (GObject *object)
|
|||
{
|
||||
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (object);
|
||||
|
||||
if (fg_select->gui)
|
||||
{
|
||||
g_object_unref (fg_select->gui);
|
||||
fg_select->gui = NULL;
|
||||
}
|
||||
|
||||
if (fg_select->stroke)
|
||||
g_warning ("%s: stroke should be NULL at this point", G_STRLOC);
|
||||
|
||||
|
@ -251,6 +270,9 @@ gimp_foreground_select_tool_control (GimpTool *tool,
|
|||
{
|
||||
gimp_foreground_select_tool_drop_masks (fg_select, display);
|
||||
tool->display = NULL;
|
||||
|
||||
if (fg_select->gui)
|
||||
gimp_tool_gui_hide (fg_select->gui);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -268,6 +290,9 @@ gimp_foreground_select_tool_oper_update (GimpTool *tool,
|
|||
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
|
||||
const gchar *status = NULL;
|
||||
|
||||
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
|
||||
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
|
||||
display);
|
||||
|
||||
|
@ -294,6 +319,13 @@ gimp_foreground_select_tool_oper_update (GimpTool *tool,
|
|||
|
||||
if (proximity && status)
|
||||
gimp_tool_replace_status (tool, display, "%s", status);
|
||||
|
||||
gimp_foreground_select_tool_update_gui (fg_select);
|
||||
|
||||
gimp_tool_gui_set_shell (fg_select->gui, shell);
|
||||
gimp_tool_gui_set_viewable (fg_select->gui, GIMP_VIEWABLE (image));
|
||||
|
||||
gimp_tool_gui_show (fg_select->gui);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -359,11 +391,11 @@ gimp_foreground_select_tool_key_press (GimpTool *tool,
|
|||
case GDK_KEY_Return:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
gimp_foreground_select_tool_preview (fg_select, display);
|
||||
gimp_foreground_select_tool_response (fg_select->gui, RESPONSE_PREVIEW, fg_select);
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_Escape:
|
||||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
|
||||
gimp_foreground_select_tool_response (fg_select->gui, RESPONSE_RESET, fg_select);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
|
@ -377,11 +409,11 @@ gimp_foreground_select_tool_key_press (GimpTool *tool,
|
|||
case GDK_KEY_Return:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
gimp_foreground_select_tool_apply (fg_select, display);
|
||||
gimp_foreground_select_tool_response (fg_select->gui, RESPONSE_APPLY, fg_select);
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_Escape:
|
||||
gimp_foreground_select_tool_set_trimap (fg_select, display);
|
||||
gimp_foreground_select_tool_response (fg_select->gui, RESPONSE_PREVIEW, fg_select);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
|
@ -474,6 +506,80 @@ gimp_foreground_select_tool_button_release (GimpTool *tool,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_foreground_select_tool_response (GimpToolGui *gui,
|
||||
gint response_id,
|
||||
GimpForegroundSelectTool *fg_select)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (fg_select);
|
||||
GimpDisplay *display = tool->display;
|
||||
|
||||
if (response_id == RESPONSE_PREVIEW)
|
||||
{
|
||||
if (fg_select->state == MATTING_STATE_PREVIEW_MASK)
|
||||
gimp_foreground_select_tool_set_trimap (fg_select, display);
|
||||
else
|
||||
gimp_foreground_select_tool_preview (fg_select, display);
|
||||
}
|
||||
else if (response_id == RESPONSE_APPLY)
|
||||
{
|
||||
if (fg_select->state != MATTING_STATE_PREVIEW_MASK)
|
||||
gimp_foreground_select_tool_preview (fg_select, display);
|
||||
gimp_foreground_select_tool_apply (fg_select, display);
|
||||
}
|
||||
else if (response_id == RESPONSE_RESET)
|
||||
{
|
||||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
|
||||
}
|
||||
|
||||
gimp_foreground_select_tool_update_gui (fg_select);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_foreground_select_tool_update_gui (GimpForegroundSelectTool *fg_select)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (fg_select);
|
||||
|
||||
if (!fg_select->gui)
|
||||
{
|
||||
fg_select->gui = gimp_tool_gui_new (tool->tool_info,
|
||||
_("Dialog for foreground select"),
|
||||
FALSE,
|
||||
_("Toggle Preview"), RESPONSE_PREVIEW,
|
||||
_("Apply"), RESPONSE_APPLY,
|
||||
GIMP_STOCK_RESET, RESPONSE_RESET,
|
||||
NULL);
|
||||
|
||||
g_signal_connect (fg_select->gui, "response",
|
||||
G_CALLBACK (gimp_foreground_select_tool_response),
|
||||
fg_select);
|
||||
}
|
||||
|
||||
if (fg_select->state == MATTING_STATE_FREE_SELECT)
|
||||
{
|
||||
gimp_tool_gui_set_description (fg_select->gui, _("Select foreground pixels"));
|
||||
}
|
||||
else if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
|
||||
{
|
||||
gimp_tool_gui_set_description (fg_select->gui, _("Paint mask"));
|
||||
}
|
||||
else if (fg_select->state == MATTING_STATE_PREVIEW_MASK)
|
||||
{
|
||||
gimp_tool_gui_set_description (fg_select->gui, _("Preview"));
|
||||
}
|
||||
|
||||
if (fg_select->state == MATTING_STATE_FREE_SELECT)
|
||||
{
|
||||
gimp_tool_gui_set_response_sensitive (fg_select->gui, RESPONSE_PREVIEW, FALSE);
|
||||
gimp_tool_gui_set_response_sensitive (fg_select->gui, RESPONSE_APPLY, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_tool_gui_set_response_sensitive (fg_select->gui, RESPONSE_PREVIEW, TRUE);
|
||||
gimp_tool_gui_set_response_sensitive (fg_select->gui, RESPONSE_APPLY, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_foreground_select_tool_motion (GimpTool *tool,
|
||||
const GimpCoords *coords,
|
||||
|
@ -814,18 +920,21 @@ static void
|
|||
gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
|
||||
GimpDisplay *display)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (fg_select);
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
GimpLayer *layer = gimp_image_get_active_layer (image);
|
||||
GimpLayerMask *layer_mask;
|
||||
GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
|
||||
GimpTool *tool = GIMP_TOOL (fg_select);
|
||||
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (fg_select);
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
|
||||
g_return_if_fail (fg_select->mask != NULL);
|
||||
|
||||
layer_mask = gimp_layer_mask_new_from_buffer (fg_select->mask, image,
|
||||
"mask", &color);
|
||||
|
||||
gimp_layer_add_mask (layer, layer_mask, TRUE, NULL);
|
||||
gimp_channel_select_buffer (gimp_image_get_mask (image),
|
||||
C_("command", "Foreground Select"),
|
||||
fg_select->mask,
|
||||
0, /* x offset */
|
||||
0, /* y offset */
|
||||
options->operation,
|
||||
options->feather,
|
||||
options->feather_radius,
|
||||
options->feather_radius);
|
||||
|
||||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
|
||||
|
||||
|
@ -839,6 +948,7 @@ gimp_foreground_select_tool_stroke_paint (GimpForegroundSelectTool *fg_select
|
|||
{
|
||||
GimpScanConvert *scan_convert;
|
||||
gint width;
|
||||
gdouble opacity;
|
||||
|
||||
g_return_if_fail (fg_select->stroke != NULL);
|
||||
|
||||
|
@ -870,9 +980,16 @@ gimp_foreground_select_tool_stroke_paint (GimpForegroundSelectTool *fg_select
|
|||
GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0,
|
||||
0.0, NULL);
|
||||
|
||||
if (options->draw_mode == GIMP_MATTING_DRAW_MODE_FOREGROUND)
|
||||
opacity = 1.0;
|
||||
else if (options->draw_mode == GIMP_MATTING_DRAW_MODE_BACKGROUND)
|
||||
opacity = 0.0;
|
||||
else
|
||||
opacity = 0.5;
|
||||
|
||||
gimp_scan_convert_compose_value (scan_convert, fg_select->trimap,
|
||||
0, 0,
|
||||
gimp_foreground_select_options_get_opacity (options));
|
||||
opacity);
|
||||
|
||||
gimp_scan_convert_free (scan_convert);
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ struct _GimpForegroundSelectTool
|
|||
GeglBuffer *trimap;
|
||||
GeglBuffer *mask;
|
||||
MattingState state;
|
||||
GimpToolGui *gui;
|
||||
};
|
||||
|
||||
struct _GimpForegroundSelectToolClass
|
||||
|
|
Loading…
Reference in New Issue