diff --git a/app/tools/gimpblendtool-editor.c b/app/tools/gimpblendtool-editor.c index 8c3bcf50a8..7862553b5b 100644 --- a/app/tools/gimpblendtool-editor.c +++ b/app/tools/gimpblendtool-editor.c @@ -49,33 +49,47 @@ /* local function prototypes */ -static gboolean gimp_blend_tool_editor_line_can_add_slider (GimpToolLine *line, - gdouble value, - GimpBlendTool *blend_tool); -static gint gimp_blend_tool_editor_line_add_slider (GimpToolLine *line, - gdouble value, - GimpBlendTool *blend_tool); -static void gimp_blend_tool_editor_line_prepare_to_remove_slider (GimpToolLine *line, - gint slider, - gboolean remove, - GimpBlendTool *blend_tool); -static void gimp_blend_tool_editor_line_remove_slider (GimpToolLine *line, - gint slider, - GimpBlendTool *blend_tool); +static gboolean gimp_blend_tool_editor_line_can_add_slider (GimpToolLine *line, + gdouble value, + GimpBlendTool *blend_tool); +static gint gimp_blend_tool_editor_line_add_slider (GimpToolLine *line, + gdouble value, + GimpBlendTool *blend_tool); +static void gimp_blend_tool_editor_line_prepare_to_remove_slider (GimpToolLine *line, + gint slider, + gboolean remove, + GimpBlendTool *blend_tool); +static void gimp_blend_tool_editor_line_remove_slider (GimpToolLine *line, + gint slider, + GimpBlendTool *blend_tool); +static gboolean gimp_blend_tool_editor_line_handle_clicked (GimpToolLine *line, + gint handle, + GdkModifierType state, + GimpButtonPressType press_type, + GimpBlendTool *blend_tool); -static gboolean gimp_blend_tool_editor_is_gradient_editable (GimpBlendTool *blend_tool); +static gboolean gimp_blend_tool_editor_is_gradient_editable (GimpBlendTool *blend_tool); -static GimpGradientSegment * gimp_blend_tool_editor_handle_get_segment (GimpBlendTool *blend_tool, - gint handle); +static gboolean gimp_blend_tool_editor_handle_is_endpoint (GimpBlendTool *blend_tool, + gint handle); +static gboolean gimp_blend_tool_editor_handle_is_stop (GimpBlendTool *blend_tool, + gint handle); +static gboolean gimp_blend_tool_editor_handle_is_midpoint (GimpBlendTool *blend_tool, + gint handle); +static GimpGradientSegment * gimp_blend_tool_editor_handle_get_segment (GimpBlendTool *blend_tool, + gint handle); -static void gimp_blend_tool_editor_block_handlers (GimpBlendTool *blend_tool); -static void gimp_blend_tool_editor_unblock_handlers (GimpBlendTool *blend_tool); -static gboolean gimp_blend_tool_editor_are_handlers_blocked (GimpBlendTool *blend_tool); +static void gimp_blend_tool_editor_block_handlers (GimpBlendTool *blend_tool); +static void gimp_blend_tool_editor_unblock_handlers (GimpBlendTool *blend_tool); +static gboolean gimp_blend_tool_editor_are_handlers_blocked (GimpBlendTool *blend_tool); -static void gimp_blend_tool_editor_freeze_gradient (GimpBlendTool *blend_tool); -static void gimp_blend_tool_editor_thaw_gradient (GimpBlendTool *blend_tool); +static void gimp_blend_tool_editor_freeze_gradient (GimpBlendTool *blend_tool); +static void gimp_blend_tool_editor_thaw_gradient (GimpBlendTool *blend_tool); -static void gimp_blend_tool_editor_update_sliders (GimpBlendTool *blend_tool); +static gint gimp_blend_tool_editor_add_stop (GimpBlendTool *blend_tool, + gdouble value); + +static void gimp_blend_tool_editor_update_sliders (GimpBlendTool *blend_tool); /* private functions */ @@ -98,13 +112,9 @@ gimp_blend_tool_editor_line_add_slider (GimpToolLine *line, gdouble value, GimpBlendTool *blend_tool) { - GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); - GimpPaintOptions *paint_options = GIMP_PAINT_OPTIONS (options); - gdouble offset = options->offset / 100.0; - GimpGradientSegment *seg; - gint slider; - - gimp_blend_tool_editor_freeze_gradient (blend_tool); + GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); + GimpPaintOptions *paint_options = GIMP_PAINT_OPTIONS (options); + gdouble offset = options->offset / 100.0; /* adjust slider value according to the offset */ value = (value - offset) / (1.0 - offset); @@ -113,17 +123,7 @@ gimp_blend_tool_editor_line_add_slider (GimpToolLine *line, if (paint_options->gradient_options->gradient_reverse) value = 1.0 - value; - gimp_gradient_split_at (blend_tool->gradient, - GIMP_CONTEXT (options), NULL, value, &seg, NULL); - - slider = - gimp_gradient_segment_range_get_n_segments (blend_tool->gradient, - blend_tool->gradient->segments, - seg) - 1; - - gimp_blend_tool_editor_thaw_gradient (blend_tool); - - return slider; + return gimp_blend_tool_editor_add_stop (blend_tool, value); } static void @@ -179,6 +179,40 @@ gimp_blend_tool_editor_line_remove_slider (GimpToolLine *line, gimp_blend_tool_set_tentative_gradient (blend_tool, NULL); } +static gboolean +gimp_blend_tool_editor_line_handle_clicked (GimpToolLine *line, + gint handle, + GdkModifierType state, + GimpButtonPressType press_type, + GimpBlendTool *blend_tool) +{ + if (gimp_blend_tool_editor_handle_is_midpoint (blend_tool, handle)) + { + if (press_type == GIMP_BUTTON_PRESS_DOUBLE && + gimp_blend_tool_editor_is_gradient_editable (blend_tool)) + { + const GimpControllerSlider *sliders; + gint stop; + + sliders = gimp_tool_line_get_sliders (line, NULL); + + if (sliders[handle].value > sliders[handle].min + EPSILON && + sliders[handle].value < sliders[handle].max - EPSILON) + { + stop = gimp_blend_tool_editor_add_stop (blend_tool, + sliders[handle].value); + + gimp_tool_line_set_selection (line, stop); + } + + /* return FALSE, so that the new slider can be dragged immediately */ + return FALSE; + } + } + + return FALSE; +} + static gboolean gimp_blend_tool_editor_is_gradient_editable (GimpBlendTool *blend_tool) { @@ -188,6 +222,36 @@ gimp_blend_tool_editor_is_gradient_editable (GimpBlendTool *blend_tool) gimp_data_is_writable (GIMP_DATA (blend_tool->gradient)); } +static gboolean +gimp_blend_tool_editor_handle_is_endpoint (GimpBlendTool *blend_tool, + gint handle) +{ + return handle == GIMP_TOOL_LINE_HANDLE_START || + handle == GIMP_TOOL_LINE_HANDLE_END; +} + +static gboolean +gimp_blend_tool_editor_handle_is_stop (GimpBlendTool *blend_tool, + gint handle) +{ + gint n_sliders; + + gimp_tool_line_get_sliders (GIMP_TOOL_LINE (blend_tool->widget), &n_sliders); + + return handle >= 0 && handle < n_sliders / 2; +} + +static gboolean +gimp_blend_tool_editor_handle_is_midpoint (GimpBlendTool *blend_tool, + gint handle) +{ + gint n_sliders; + + gimp_tool_line_get_sliders (GIMP_TOOL_LINE (blend_tool->widget), &n_sliders); + + return handle >= n_sliders / 2; +} + static GimpGradientSegment * gimp_blend_tool_editor_handle_get_segment (GimpBlendTool *blend_tool, gint handle) @@ -281,6 +345,29 @@ gimp_blend_tool_editor_thaw_gradient(GimpBlendTool *blend_tool) gimp_blend_tool_editor_unblock_handlers (blend_tool); } +static gint +gimp_blend_tool_editor_add_stop (GimpBlendTool *blend_tool, + gdouble value) +{ + GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); + GimpGradientSegment *seg; + gint stop; + + gimp_blend_tool_editor_freeze_gradient (blend_tool); + + gimp_gradient_split_at (blend_tool->gradient, + GIMP_CONTEXT (options), NULL, value, &seg, NULL); + + stop = + gimp_gradient_segment_range_get_n_segments (blend_tool->gradient, + blend_tool->gradient->segments, + seg) - 1; + + gimp_blend_tool_editor_thaw_gradient (blend_tool); + + return stop; +} + static void gimp_blend_tool_editor_update_sliders (GimpBlendTool *blend_tool) { @@ -450,6 +537,9 @@ gimp_blend_tool_editor_start (GimpBlendTool *blend_tool) g_signal_connect (blend_tool->widget, "remove-slider", G_CALLBACK (gimp_blend_tool_editor_line_remove_slider), blend_tool); + g_signal_connect (blend_tool->widget, "handle-clicked", + G_CALLBACK (gimp_blend_tool_editor_line_handle_clicked), + blend_tool); } void diff --git a/app/tools/gimpblendtool.c b/app/tools/gimpblendtool.c index ef9a1fc4de..d71573fbab 100644 --- a/app/tools/gimpblendtool.c +++ b/app/tools/gimpblendtool.c @@ -200,22 +200,23 @@ gimp_blend_tool_init (GimpBlendTool *blend_tool) { GimpTool *tool = GIMP_TOOL (blend_tool); - gimp_tool_control_set_scroll_lock (tool->control, TRUE); - gimp_tool_control_set_preserve (tool->control, FALSE); - gimp_tool_control_set_dirty_mask (tool->control, - GIMP_DIRTY_IMAGE | - GIMP_DIRTY_IMAGE_STRUCTURE | - GIMP_DIRTY_DRAWABLE | - GIMP_DIRTY_ACTIVE_DRAWABLE); - gimp_tool_control_set_wants_click (tool->control, TRUE); - gimp_tool_control_set_precision (tool->control, - GIMP_CURSOR_PRECISION_SUBPIXEL); - gimp_tool_control_set_tool_cursor (tool->control, - GIMP_TOOL_CURSOR_BLEND); - gimp_tool_control_set_action_opacity (tool->control, - "context/context-opacity-set"); - gimp_tool_control_set_action_object_1 (tool->control, - "context/context-gradient-select-set"); + gimp_tool_control_set_scroll_lock (tool->control, TRUE); + gimp_tool_control_set_preserve (tool->control, FALSE); + gimp_tool_control_set_dirty_mask (tool->control, + GIMP_DIRTY_IMAGE | + GIMP_DIRTY_IMAGE_STRUCTURE | + GIMP_DIRTY_DRAWABLE | + GIMP_DIRTY_ACTIVE_DRAWABLE); + gimp_tool_control_set_wants_click (tool->control, TRUE); + gimp_tool_control_set_wants_double_click (tool->control, TRUE); + gimp_tool_control_set_precision (tool->control, + GIMP_CURSOR_PRECISION_SUBPIXEL); + gimp_tool_control_set_tool_cursor (tool->control, + GIMP_TOOL_CURSOR_BLEND); + gimp_tool_control_set_action_opacity (tool->control, + "context/context-opacity-set"); + gimp_tool_control_set_action_object_1 (tool->control, + "context/context-gradient-select-set"); gimp_draw_tool_set_default_status (GIMP_DRAW_TOOL (tool), _("Click-Drag to draw a gradient")); @@ -342,7 +343,8 @@ gimp_blend_tool_button_press (GimpTool *tool, blend_info_new (start_x, start_y, end_x, end_y)); } - gimp_tool_control_activate (tool->control); + if (press_type == GIMP_BUTTON_PRESS_NORMAL) + gimp_tool_control_activate (tool->control); } static void