[gimp] app: modify the gradient in response to blend-tool slider motion
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: modify the gradient in response to blend-tool slider motion
- Date: Mon, 9 Oct 2017 16:53:43 +0000 (UTC)
commit 690f51d4eb3f92e543000bf9f528d10aa13381e8
Author: Ell <ell_se yahoo com>
Date: Tue Aug 1 14:04:28 2017 -0400
app: modify the gradient in response to blend-tool slider motion
Update the gradient's segment endpoint and midpoint positions,
according to the sliders.
app/tools/gimpblendtool-editor.c | 156 ++++++++++++++++++++++++++++++++++++--
app/tools/gimpblendtool-editor.h | 2 +
app/tools/gimpblendtool.c | 2 +
3 files changed, 153 insertions(+), 7 deletions(-)
---
diff --git a/app/tools/gimpblendtool-editor.c b/app/tools/gimpblendtool-editor.c
index f9552eb..13fe3dd 100644
--- a/app/tools/gimpblendtool-editor.c
+++ b/app/tools/gimpblendtool-editor.c
@@ -21,6 +21,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
+#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
@@ -43,18 +44,24 @@
#include "gimp-intl.h"
+#define EPSILON 2e-10
+
+
/* local function prototypes */
-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 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 GimpGradientSegment * gimp_blend_tool_editor_handle_get_segment (GimpBlendTool *blend_tool,
+ gint handle);
-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_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_update_sliders (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);
/* private functions */
@@ -69,6 +76,37 @@ gimp_blend_tool_editor_is_gradient_editable (GimpBlendTool *blend_tool)
gimp_data_is_writable (GIMP_DATA (blend_tool->gradient));
}
+static GimpGradientSegment *
+gimp_blend_tool_editor_handle_get_segment (GimpBlendTool *blend_tool,
+ gint handle)
+{
+ switch (handle)
+ {
+ case GIMP_TOOL_LINE_HANDLE_START:
+ return blend_tool->gradient->segments;
+
+ case GIMP_TOOL_LINE_HANDLE_END:
+ return gimp_gradient_segment_get_last (blend_tool->gradient->segments);
+
+ default:
+ {
+ const GimpControllerSlider *sliders;
+ gint n_sliders;
+ gint seg_i;
+
+ sliders = gimp_tool_line_get_sliders (GIMP_TOOL_LINE (blend_tool->widget),
+ &n_sliders);
+
+ g_assert (handle >= 0 && handle < n_sliders);
+
+ seg_i = GPOINTER_TO_INT (sliders[handle].data);
+
+ return gimp_gradient_segment_get_nth (blend_tool->gradient->segments,
+ seg_i);
+ }
+ }
+}
+
static void
gimp_blend_tool_editor_block_handlers (GimpBlendTool *blend_tool)
{
@@ -227,9 +265,14 @@ gimp_blend_tool_editor_update_sliders (GimpBlendTool *blend_tool)
sliders[i].max = (1.0 - offset) * sliders[i].max + offset;
}
+ /* avoid updating the gradient in gimp_blend_tool_editor_line_changed() */
+ gimp_blend_tool_editor_block_handlers (blend_tool);
+
gimp_tool_line_set_sliders (GIMP_TOOL_LINE (blend_tool->widget),
sliders, n_sliders);
+ gimp_blend_tool_editor_unblock_handlers (blend_tool);
+
g_free (sliders);
}
@@ -280,6 +323,105 @@ gimp_blend_tool_editor_options_notify (GimpBlendTool *blend_tool,
}
void
+gimp_blend_tool_editor_line_changed (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;
+ const GimpControllerSlider *sliders;
+ gint n_sliders;
+ gint i;
+ GimpGradientSegment *seg;
+ gboolean changed = FALSE;
+
+ if (gimp_blend_tool_editor_are_handlers_blocked (blend_tool))
+ return;
+
+ if (! blend_tool->gradient || offset == 1.0)
+ return;
+
+ sliders = gimp_tool_line_get_sliders (GIMP_TOOL_LINE (blend_tool->widget),
+ &n_sliders);
+
+ if (n_sliders == 0)
+ return;
+
+ /* update the midpoints first, since moving the gradient stops may change the
+ * gradient's midpoints w.r.t. the sliders, but not the other way around.
+ */
+ for (seg = blend_tool->gradient->segments, i = n_sliders / 2;
+ seg;
+ seg = seg->next, i++)
+ {
+ gdouble value;
+
+ value = sliders[i].value;
+
+ /* adjust slider value according to the offset */
+ value = (value - offset) / (1.0 - offset);
+
+ /* flip the slider value, if necessary */
+ if (paint_options->gradient_options->gradient_reverse)
+ value = 1.0 - value;
+
+ if (fabs (value - seg->middle) > EPSILON)
+ {
+ if (! changed)
+ {
+ gimp_blend_tool_editor_freeze_gradient (blend_tool);
+
+ /* refetch the segment, since the gradient might have changed */
+ seg = gimp_blend_tool_editor_handle_get_segment (blend_tool, i);
+
+ changed = TRUE;
+ }
+
+ seg->middle = value;
+ }
+ }
+
+ /* update the gradient stops */
+ for (seg = blend_tool->gradient->segments, i = 0;
+ seg->next;
+ seg = seg->next, i++)
+ {
+ gdouble value;
+
+ value = sliders[i].value;
+
+ /* adjust slider value according to the offset */
+ value = (value - offset) / (1.0 - offset);
+
+ /* flip the slider value, if necessary */
+ if (paint_options->gradient_options->gradient_reverse)
+ value = 1.0 - value;
+
+ if (fabs (value - seg->right) > EPSILON)
+ {
+ if (! changed)
+ {
+ gimp_blend_tool_editor_freeze_gradient (blend_tool);
+
+ /* refetch the segment, since the gradient might have changed */
+ seg = gimp_blend_tool_editor_handle_get_segment (blend_tool, i);
+
+ changed = TRUE;
+ }
+
+ gimp_gradient_segment_range_compress (blend_tool->gradient,
+ seg, seg,
+ seg->left, value);
+ gimp_gradient_segment_range_compress (blend_tool->gradient,
+ seg->next, seg->next,
+ value, seg->next->right);
+ }
+ }
+
+ if (changed)
+ gimp_blend_tool_editor_thaw_gradient (blend_tool);
+}
+
+void
gimp_blend_tool_editor_gradient_dirty (GimpBlendTool *blend_tool)
{
if (gimp_blend_tool_editor_are_handlers_blocked (blend_tool))
diff --git a/app/tools/gimpblendtool-editor.h b/app/tools/gimpblendtool-editor.h
index d34324b..0012ad3 100644
--- a/app/tools/gimpblendtool-editor.h
+++ b/app/tools/gimpblendtool-editor.h
@@ -23,6 +23,8 @@ void gimp_blend_tool_editor_options_notify (GimpBlendTool *blend_tool,
GimpToolOptions *options,
const GParamSpec *pspec);
+void gimp_blend_tool_editor_line_changed (GimpBlendTool *blend_tool);
+
void gimp_blend_tool_editor_gradient_dirty (GimpBlendTool *blend_tool);
void gimp_blend_tool_editor_gradient_changed (GimpBlendTool *blend_tool);
diff --git a/app/tools/gimpblendtool.c b/app/tools/gimpblendtool.c
index 90bef0a..7fd8eb8 100644
--- a/app/tools/gimpblendtool.c
+++ b/app/tools/gimpblendtool.c
@@ -749,6 +749,8 @@ gimp_blend_tool_line_changed (GimpToolWidget *widget,
gimp_blend_tool_update_graph (blend_tool);
gimp_drawable_filter_apply (blend_tool->filter, NULL);
+
+ gimp_blend_tool_editor_line_changed (blend_tool);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]