app: add "instant mode" option to the blend tool

Add a boolean "instant mode" option to the blend tool, togglable
using shift.  When checked, commit the gradient immediately when
the mouse is released.

When not in instant mode, don't commit the gradient when clicking
outside the line, since this will become easy to do accidentally
once we add on-canvas gradient editing.
This commit is contained in:
Ell 2017-08-01 08:14:10 -04:00
parent 02ad016b39
commit f95f8eb347
3 changed files with 110 additions and 33 deletions

View File

@ -29,6 +29,7 @@
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpviewablebox.h"
#include "widgets/gimpwidgets-utils.h"
#include "gimpblendoptions.h"
#include "gimppaintoptions-gui.h"
@ -45,7 +46,8 @@ enum
PROP_SUPERSAMPLE,
PROP_SUPERSAMPLE_DEPTH,
PROP_SUPERSAMPLE_THRESHOLD,
PROP_DITHER
PROP_DITHER,
PROP_INSTANT
};
@ -120,6 +122,13 @@ gimp_blend_options_class_init (GimpBlendOptionsClass *klass)
NULL,
TRUE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INSTANT,
"instant",
_("Instant mode"),
_("Commit gradient instantly"),
FALSE,
GIMP_PARAM_STATIC_STRINGS);
}
static void
@ -162,6 +171,10 @@ gimp_blend_options_set_property (GObject *object,
options->dither = g_value_get_boolean (value);
break;
case PROP_INSTANT:
options->instant = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -203,6 +216,10 @@ gimp_blend_options_get_property (GObject *object,
g_value_set_boolean (value, options->dither);
break;
case PROP_INSTANT:
g_value_set_boolean (value, options->instant);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -212,13 +229,18 @@ gimp_blend_options_get_property (GObject *object,
GtkWidget *
gimp_blend_options_gui (GimpToolOptions *tool_options)
{
GObject *config = G_OBJECT (tool_options);
GtkWidget *vbox = gimp_paint_options_gui (tool_options);
GtkWidget *vbox2;
GtkWidget *frame;
GtkWidget *scale;
GtkWidget *combo;
GtkWidget *button;
GObject *config = G_OBJECT (tool_options);
GimpBlendOptions *options = GIMP_BLEND_OPTIONS (tool_options);
GtkWidget *vbox = gimp_paint_options_gui (tool_options);
GtkWidget *vbox2;
GtkWidget *frame;
GtkWidget *scale;
GtkWidget *combo;
GtkWidget *button;
gchar *str;
GdkModifierType extend_mask;
extend_mask = gimp_get_extend_selection_mask ();
/* the gradient */
button = gimp_prop_gradient_box_new (NULL, GIMP_CONTEXT (tool_options),
@ -281,6 +303,18 @@ gimp_blend_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
gtk_widget_show (scale);
/* the instant toggle */
str = g_strdup_printf (_("Instant mode (%s)"),
gimp_get_mod_string (extend_mask));
button = gimp_prop_check_button_new (config, "instant", str);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_free (str);
options->instant_toggle = button;
return vbox;
}

View File

@ -45,6 +45,11 @@ struct _GimpBlendOptions
gdouble supersample_threshold;
gboolean dither;
gboolean instant;
/* options gui */
GtkWidget *instant_toggle;
};

View File

@ -90,6 +90,11 @@ static void gimp_blend_tool_motion (GimpTool *tool,
guint32 time,
GdkModifierType state,
GimpDisplay *display);
static void gimp_blend_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *display);
static void gimp_blend_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
@ -180,6 +185,7 @@ gimp_blend_tool_class_init (GimpBlendToolClass *klass)
tool_class->button_press = gimp_blend_tool_button_press;
tool_class->button_release = gimp_blend_tool_button_release;
tool_class->motion = gimp_blend_tool_motion;
tool_class->modifier_key = gimp_blend_tool_modifier_key;
tool_class->cursor_update = gimp_blend_tool_cursor_update;
tool_class->can_undo = gimp_blend_tool_can_undo;
tool_class->can_redo = gimp_blend_tool_can_redo;
@ -346,7 +352,8 @@ gimp_blend_tool_button_release (GimpTool *tool,
GimpButtonReleaseType release_type,
GimpDisplay *display)
{
GimpBlendTool *blend_tool = GIMP_BLEND_TOOL (tool);
GimpBlendTool *blend_tool = GIMP_BLEND_TOOL (tool);
GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (tool);
gimp_tool_pop_status (tool, display);
@ -358,36 +365,39 @@ gimp_blend_tool_button_release (GimpTool *tool,
coords, time, state, release_type);
blend_tool->grab_widget = NULL;
if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
if (options->instant)
{
/* simply destroy the undo step we pushed in button_press(),
* the tool widget restored the old position by itself
*/
blend_info_free (blend_tool->undo_stack->data);
blend_tool->undo_stack = g_list_remove (blend_tool->undo_stack,
blend_tool->undo_stack->data);
if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
else
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display);
}
else
{
/* blow the redo stack, we had an actual undoable movement
*/
if (blend_tool->redo_stack)
if (release_type == GIMP_BUTTON_RELEASE_CANCEL)
{
g_list_free_full (blend_tool->redo_stack,
(GDestroyNotify) blend_info_free);
blend_tool->redo_stack = NULL;
/* simply destroy the undo step we pushed in button_press(),
* the tool widget restored the old position by itself
*/
blend_info_free (blend_tool->undo_stack->data);
blend_tool->undo_stack = g_list_remove (blend_tool->undo_stack,
blend_tool->undo_stack->data);
}
else
{
/* blow the redo stack, we had an actual undoable movement
*/
if (blend_tool->redo_stack)
{
g_list_free_full (blend_tool->redo_stack,
(GDestroyNotify) blend_info_free);
blend_tool->redo_stack = NULL;
}
}
}
/* update the undo actions / menu items */
gimp_image_flush (gimp_display_get_image (display));
}
else if (release_type == GIMP_BUTTON_RELEASE_CLICK ||
release_type == GIMP_BUTTON_RELEASE_NO_MOTION)
{
/* a click outside any handle commits the tool
*/
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display);
/* update the undo actions / menu items */
gimp_image_flush (gimp_display_get_image (display));
}
}
}
@ -406,6 +416,27 @@ gimp_blend_tool_motion (GimpTool *tool,
}
}
static void
gimp_blend_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *display)
{
GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (tool);
if (key == gimp_get_extend_selection_mask ())
{
if (options->instant_toggle &&
gtk_widget_get_sensitive (options->instant_toggle))
{
g_object_set (options,
"instant", ! options->instant,
NULL);
}
}
}
static void
gimp_blend_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
@ -576,6 +607,9 @@ gimp_blend_tool_start (GimpBlendTool *blend_tool,
GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool);
GimpContext *context = GIMP_CONTEXT (options);
if (options->instant_toggle)
gtk_widget_set_sensitive (options->instant_toggle, FALSE);
tool->display = display;
tool->drawable = drawable;
@ -621,7 +655,8 @@ gimp_blend_tool_start (GimpBlendTool *blend_tool,
static void
gimp_blend_tool_halt (GimpBlendTool *blend_tool)
{
GimpTool *tool = GIMP_TOOL (blend_tool);
GimpTool *tool = GIMP_TOOL (blend_tool);
GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool);
if (blend_tool->graph)
{
@ -674,6 +709,9 @@ gimp_blend_tool_halt (GimpBlendTool *blend_tool)
tool->display = NULL;
tool->drawable = NULL;
if (options->instant_toggle)
gtk_widget_set_sensitive (options->instant_toggle, TRUE);
}
static void