[gimp/wip/gradient-edit: 31/42] app: convert midpoints to stops via double-click in the blend tool



commit 5a9d1f3f072a1988c198ab43cd14ccb9dac606ab
Author: Ell <ell_se yahoo com>
Date:   Tue Aug 1 18:45:13 2017 -0400

    app: convert midpoints to stops via double-click in the blend tool
    
    When a midpoint is double-clicked, convert it into a gradient stop
    (i.e., split the corresponding segment at the midpoint,) by
    responding to the line's handle-clicked signal.

 app/tools/gimpblendtool-editor.c |  172 +++++++++++++++++++++++++++++---------
 app/tools/gimpblendtool.c        |   36 ++++----
 2 files changed, 150 insertions(+), 58 deletions(-)
---
diff --git a/app/tools/gimpblendtool-editor.c b/app/tools/gimpblendtool-editor.c
index 23d1b0e..bb3af08 100644
--- a/app/tools/gimpblendtool-editor.c
+++ b/app/tools/gimpblendtool-editor.c
@@ -49,29 +49,43 @@
 
 /*  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_remove_slider   (GimpToolLine  *line,
-                                                                          gint           slider,
-                                                                          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 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_update_sliders       (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_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_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_freeze_gradient      (GimpBlendTool       *blend_tool);
+static void                  gimp_blend_tool_editor_thaw_gradient        (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  */
@@ -94,13 +108,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);
@@ -109,17 +119,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
@@ -140,6 +140,40 @@ gimp_blend_tool_editor_line_remove_slider (GimpToolLine  *line,
 }
 
 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)
 {
   GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool);
@@ -148,6 +182,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)
@@ -241,6 +305,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)
 {
@@ -407,6 +494,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 a00d920..b74d34f 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]