[gimp/wip/gradient-edit: 26/35] 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/wip/gradient-edit: 26/35] app: modify the gradient in response to blend-tool slider motion
- Date: Fri, 4 Aug 2017 14:59:59 +0000 (UTC)
commit 423e11ddf7d57d47fb04d261e0595f5c30898437
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 | 158 ++++++++++++++++++++++++++++++++++++--
app/tools/gimpblendtool-editor.h | 2 +
app/tools/gimpblendtool.c | 2 +
app/tools/gimpblendtool.h | 4 +
4 files changed, 159 insertions(+), 7 deletions(-)
---
diff --git a/app/tools/gimpblendtool-editor.c b/app/tools/gimpblendtool-editor.c
index e4d32e9..6cdf095 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,14 +44,20 @@
#include "gimp-intl.h"
+#define EPSILON 1e-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_freeze_gradient (GimpBlendTool *blend_tool);
-static void gimp_blend_tool_editor_thaw_gradient (GimpBlendTool *blend_tool);
+static GimpGradientSegment * gimp_blend_tool_editor_handle_get_segment (GimpBlendTool *blend_tool,
+ gint handle);
-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 */
@@ -66,6 +73,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_freeze_gradient (GimpBlendTool *blend_tool)
{
@@ -117,9 +155,11 @@ gimp_blend_tool_editor_update_sliders (GimpBlendTool *blend_tool)
GimpControllerSlider *slider;
gint i;
- if (! blend_tool->widget || options->instant)
+ if (! blend_tool->widget || options->instant || blend_tool->modifying)
return;
+ blend_tool->modifying = TRUE;
+
editable = gimp_blend_tool_editor_is_gradient_editable (blend_tool);
n_segments = gimp_gradient_segment_range_get_n_segments (
@@ -203,6 +243,8 @@ gimp_blend_tool_editor_update_sliders (GimpBlendTool *blend_tool)
sliders, n_sliders);
g_free (sliders);
+
+ blend_tool->modifying = FALSE;
}
@@ -252,9 +294,111 @@ 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;
+
+ if (offset == 1.0 || ! blend_tool->gradient || blend_tool->modifying)
+ 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 (! blend_tool->modifying)
+ {
+ blend_tool->modifying = TRUE;
+
+ 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);
+ }
+
+ gimp_gradient_segment_set_middle_pos (blend_tool->gradient,
+ seg, 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 (! blend_tool->modifying)
+ {
+ blend_tool->modifying = TRUE;
+
+ 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);
+ }
+
+ 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 (blend_tool->modifying)
+ {
+ gimp_blend_tool_editor_thaw_gradient (blend_tool);
+
+ blend_tool->modifying = FALSE;
+
+ gimp_blend_tool_editor_update_sliders (blend_tool);
+ }
+}
+
+void
gimp_blend_tool_editor_gradient_dirty (GimpBlendTool *blend_tool)
{
- if (blend_tool->widget)
+ if (blend_tool->widget && ! blend_tool->modifying)
{
gimp_blend_tool_editor_update_sliders (blend_tool);
@@ -283,7 +427,7 @@ gimp_blend_tool_editor_gradient_changed (GimpBlendTool *blend_tool)
! gimp_data_is_writable (GIMP_DATA (blend_tool->gradient)));
}
- if (blend_tool->widget)
+ if (blend_tool->widget && ! blend_tool->modifying)
{
gimp_blend_tool_editor_update_sliders (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 425007b..8b91866 100644
--- a/app/tools/gimpblendtool.c
+++ b/app/tools/gimpblendtool.c
@@ -746,6 +746,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
diff --git a/app/tools/gimpblendtool.h b/app/tools/gimpblendtool.h
index df7a032..2da233e 100644
--- a/app/tools/gimpblendtool.h
+++ b/app/tools/gimpblendtool.h
@@ -61,6 +61,10 @@ struct _GimpBlendTool
GeglNode *dist_node;
GeglBuffer *dist_buffer;
GimpDrawableFilter *filter;
+
+ /* editor */
+
+ gboolean modifying;
};
struct _GimpBlendToolClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]