mirror of https://github.com/GNOME/gimp.git
app: streamline GimpCurve
In GimpCurve, replace the use of a fixed-length control-point array with a dynamically-sized array. Adapt GimpCurve's interface, and the rest of the code. In addition to simplifying the code, this fixes a bug where the curve object could be broken by moving the mouse too fast (yep...), and allows more accurate point placement, both in the GUI editor, and through canvas interaction in the Curves tool (see issue #814).
This commit is contained in:
parent
dc6ca2cf9a
commit
b6d829a1b2
|
@ -37,6 +37,9 @@
|
|||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
#define EPSILON 1e-6
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@ -155,7 +158,9 @@ gimp_curve_class_init (GimpCurveClass *klass)
|
|||
"n-points",
|
||||
"Number of Points",
|
||||
"The number of points",
|
||||
17, 17, 17, 0);
|
||||
0, G_MAXINT, 0,
|
||||
/* for backward compatibility */
|
||||
GIMP_CONFIG_PARAM_IGNORE);
|
||||
|
||||
array_spec = g_param_spec_double ("point", NULL, NULL,
|
||||
-1.0, 1.0, 0.0, GIMP_PARAM_READWRITE);
|
||||
|
@ -237,7 +242,7 @@ gimp_curve_set_property (GObject *object,
|
|||
break;
|
||||
|
||||
case PROP_N_POINTS:
|
||||
gimp_curve_set_n_points (curve, g_value_get_int (value));
|
||||
/* ignored */
|
||||
break;
|
||||
|
||||
case PROP_POINTS:
|
||||
|
@ -246,19 +251,41 @@ gimp_curve_set_property (GObject *object,
|
|||
gint length;
|
||||
gint i;
|
||||
|
||||
curve->n_points = 0;
|
||||
g_clear_pointer (&curve->points, g_free);
|
||||
|
||||
if (! array)
|
||||
break;
|
||||
|
||||
length = gimp_value_array_length (array);
|
||||
length = gimp_value_array_length (array) / 2;
|
||||
|
||||
for (i = 0; i < curve->n_points && i * 2 < length; i++)
|
||||
curve->points = g_new (GimpVector2, length);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
GValue *x = gimp_value_array_index (array, i * 2);
|
||||
GValue *y = gimp_value_array_index (array, i * 2 + 1);
|
||||
|
||||
curve->points[i].x = g_value_get_double (x);
|
||||
curve->points[i].y = g_value_get_double (y);
|
||||
/* for backward compatibility */
|
||||
if (g_value_get_double (x) < 0.0)
|
||||
continue;
|
||||
|
||||
curve->points[curve->n_points].x = CLAMP (g_value_get_double (x),
|
||||
0.0, 1.0);
|
||||
curve->points[curve->n_points].y = CLAMP (g_value_get_double (y),
|
||||
0.0, 1.0);
|
||||
|
||||
if (curve->n_points > 0)
|
||||
{
|
||||
curve->points[curve->n_points].x = MAX (
|
||||
curve->points[curve->n_points].x,
|
||||
curve->points[curve->n_points - 1].x);
|
||||
}
|
||||
|
||||
curve->n_points++;
|
||||
}
|
||||
|
||||
g_object_notify (object, "n-points");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -281,7 +308,7 @@ gimp_curve_set_property (GObject *object,
|
|||
{
|
||||
GValue *v = gimp_value_array_index (array, i);
|
||||
|
||||
curve->samples[i] = g_value_get_double (v);
|
||||
curve->samples[i] = CLAMP (g_value_get_double (v), 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -484,11 +511,19 @@ gimp_curve_equal (GimpConfig *a,
|
|||
if (a_curve->curve_type != b_curve->curve_type)
|
||||
return FALSE;
|
||||
|
||||
if (memcmp (a_curve->points, b_curve->points,
|
||||
sizeof (GimpVector2) * b_curve->n_points) ||
|
||||
if (a_curve->n_points != b_curve->n_points ||
|
||||
memcmp (a_curve->points, b_curve->points,
|
||||
sizeof (GimpVector2) * a_curve->n_points))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (a_curve->n_samples != b_curve->n_samples ||
|
||||
memcmp (a_curve->samples, b_curve->samples,
|
||||
sizeof (gdouble) * b_curve->n_samples))
|
||||
return FALSE;
|
||||
sizeof (gdouble) * a_curve->n_samples))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -564,18 +599,18 @@ gimp_curve_reset (GimpCurve *curve,
|
|||
|
||||
g_object_notify (G_OBJECT (curve), "samples");
|
||||
|
||||
g_free (curve->points);
|
||||
|
||||
curve->n_points = 2;
|
||||
curve->points = g_new (GimpVector2, 2);
|
||||
|
||||
curve->points[0].x = 0.0;
|
||||
curve->points[0].y = 0.0;
|
||||
|
||||
for (i = 1; i < curve->n_points - 1; i++)
|
||||
{
|
||||
curve->points[i].x = -1.0;
|
||||
curve->points[i].y = -1.0;
|
||||
}
|
||||
|
||||
curve->points[curve->n_points - 1].x = 1.0;
|
||||
curve->points[curve->n_points - 1].y = 1.0;
|
||||
curve->points[1].x = 1.0;
|
||||
curve->points[1].y = 1.0;
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "n-points");
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
|
||||
if (reset_type)
|
||||
|
@ -599,44 +634,46 @@ gimp_curve_set_curve_type (GimpCurve *curve,
|
|||
|
||||
if (curve->curve_type != curve_type)
|
||||
{
|
||||
gimp_data_freeze (GIMP_DATA (curve));
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (curve));
|
||||
|
||||
curve->curve_type = curve_type;
|
||||
|
||||
if (curve_type == GIMP_CURVE_SMOOTH)
|
||||
{
|
||||
gint n_points;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < curve->n_points; i++)
|
||||
{
|
||||
curve->points[i].x = -1;
|
||||
curve->points[i].y = -1;
|
||||
}
|
||||
g_free (curve->points);
|
||||
|
||||
/* pick some points from the curve and make them control
|
||||
* points
|
||||
*/
|
||||
n_points = CLAMP (9, curve->n_points / 2, curve->n_points);
|
||||
curve->n_points = 9;
|
||||
curve->points = g_new (GimpVector2, 9);
|
||||
|
||||
for (i = 0; i < n_points; i++)
|
||||
for (i = 0; i < curve->n_points; i++)
|
||||
{
|
||||
gint sample = i * (curve->n_samples - 1) / (n_points - 1);
|
||||
gint point = i * (curve->n_points - 1) / (n_points - 1);
|
||||
gint sample = i * (curve->n_samples - 1) / (curve->n_points - 1);
|
||||
|
||||
curve->points[point].x = ((gdouble) sample /
|
||||
(gdouble) (curve->n_samples - 1));
|
||||
curve->points[point].y = curve->samples[sample];
|
||||
curve->points[i].x = (gdouble) sample /
|
||||
(gdouble) (curve->n_samples - 1);
|
||||
curve->points[i].y = curve->samples[sample];
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "n-points");
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_curve_clear_points (curve);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "curve-type");
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (curve));
|
||||
|
||||
gimp_data_dirty (GIMP_DATA (curve));
|
||||
gimp_data_thaw (GIMP_DATA (curve));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,46 +685,6 @@ gimp_curve_get_curve_type (GimpCurve *curve)
|
|||
return curve->curve_type;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_curve_set_n_points (GimpCurve *curve,
|
||||
gint n_points)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_CURVE (curve));
|
||||
g_return_if_fail (n_points >= 2);
|
||||
g_return_if_fail (n_points <= 1024);
|
||||
|
||||
if (n_points != curve->n_points)
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (curve));
|
||||
|
||||
curve->n_points = n_points;
|
||||
g_object_notify (G_OBJECT (curve), "n-points");
|
||||
|
||||
curve->points = g_renew (GimpVector2, curve->points, curve->n_points);
|
||||
|
||||
curve->points[0].x = 0.0;
|
||||
curve->points[0].y = 0.0;
|
||||
|
||||
for (i = 1; i < curve->n_points - 1; i++)
|
||||
{
|
||||
curve->points[i].x = -1.0;
|
||||
curve->points[i].y = -1.0;
|
||||
}
|
||||
|
||||
curve->points[curve->n_points - 1].x = 1.0;
|
||||
curve->points[curve->n_points - 1].y = 1.0;
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
|
||||
if (curve->curve_type == GIMP_CURVE_SMOOTH)
|
||||
curve->identity = TRUE;
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (curve));
|
||||
}
|
||||
}
|
||||
|
||||
gint
|
||||
gimp_curve_get_n_points (GimpCurve *curve)
|
||||
{
|
||||
|
@ -736,31 +733,135 @@ gimp_curve_get_n_samples (GimpCurve *curve)
|
|||
}
|
||||
|
||||
gint
|
||||
gimp_curve_get_closest_point (GimpCurve *curve,
|
||||
gdouble x)
|
||||
gimp_curve_get_point_at (GimpCurve *curve,
|
||||
gdouble x)
|
||||
{
|
||||
gint closest_point = 0;
|
||||
gdouble distance = G_MAXDOUBLE;
|
||||
gint closest_point = -1;
|
||||
gdouble distance = EPSILON;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CURVE (curve), 0);
|
||||
g_return_val_if_fail (GIMP_IS_CURVE (curve), -1);
|
||||
|
||||
for (i = 0; i < curve->n_points; i++)
|
||||
{
|
||||
if (curve->points[i].x >= 0.0 &&
|
||||
fabs (x - curve->points[i].x) < distance)
|
||||
gdouble point_distance;
|
||||
|
||||
point_distance = fabs (x - curve->points[i].x);
|
||||
|
||||
if (point_distance <= distance)
|
||||
{
|
||||
distance = fabs (x - curve->points[i].x);
|
||||
closest_point = i;
|
||||
distance = point_distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (distance > (1.0 / (curve->n_points * 2.0)))
|
||||
closest_point = ROUND (x * (gdouble) (curve->n_points - 1));
|
||||
return closest_point;
|
||||
}
|
||||
|
||||
gint
|
||||
gimp_curve_get_closest_point (GimpCurve *curve,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble max_distance)
|
||||
{
|
||||
gint closest_point = -1;
|
||||
gdouble distance2 = G_MAXDOUBLE;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CURVE (curve), -1);
|
||||
|
||||
if (max_distance >= 0.0)
|
||||
distance2 = SQR (max_distance);
|
||||
|
||||
for (i = curve->n_points - 1; i >= 0; i--)
|
||||
{
|
||||
gdouble point_distance2;
|
||||
|
||||
point_distance2 = SQR (x - curve->points[i].x) +
|
||||
SQR (y - curve->points[i].y);
|
||||
|
||||
if (point_distance2 <= distance2)
|
||||
{
|
||||
closest_point = i;
|
||||
distance2 = point_distance2;
|
||||
}
|
||||
}
|
||||
|
||||
return closest_point;
|
||||
}
|
||||
|
||||
gint
|
||||
gimp_curve_add_point (GimpCurve *curve,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GimpVector2 *points;
|
||||
gint point;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CURVE (curve), -1);
|
||||
|
||||
if (curve->curve_type == GIMP_CURVE_FREE)
|
||||
return -1;
|
||||
|
||||
x = CLAMP (x, 0.0, 1.0);
|
||||
y = CLAMP (y, 0.0, 1.0);
|
||||
|
||||
for (point = 0; point < curve->n_points; point++)
|
||||
{
|
||||
if (curve->points[point].x > x)
|
||||
break;
|
||||
}
|
||||
|
||||
points = g_new (GimpVector2, curve->n_points + 1);
|
||||
|
||||
memcpy (points, curve->points,
|
||||
point * sizeof (GimpVector2));
|
||||
memcpy (points + point + 1, curve->points + point,
|
||||
(curve->n_points - point) * sizeof (GimpVector2));
|
||||
|
||||
points[point].x = x;
|
||||
points[point].y = y;
|
||||
|
||||
g_free (curve->points);
|
||||
|
||||
curve->n_points++;
|
||||
curve->points = points;
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "n-points");
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
|
||||
gimp_data_dirty (GIMP_DATA (curve));
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_curve_delete_point (GimpCurve *curve,
|
||||
gint point)
|
||||
{
|
||||
GimpVector2 *points;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CURVE (curve));
|
||||
g_return_if_fail (point >= 0 && point < curve->n_points);
|
||||
|
||||
points = g_new (GimpVector2, curve->n_points - 1);
|
||||
|
||||
memcpy (points, curve->points,
|
||||
point * sizeof (GimpVector2));
|
||||
memcpy (points + point, curve->points + point + 1,
|
||||
(curve->n_points - point - 1) * sizeof (GimpVector2));
|
||||
|
||||
g_free (curve->points);
|
||||
|
||||
curve->n_points--;
|
||||
curve->points = points;
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "n-points");
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
|
||||
gimp_data_dirty (GIMP_DATA (curve));
|
||||
}
|
||||
|
||||
void
|
||||
gimp_curve_set_point (GimpCurve *curve,
|
||||
gint point,
|
||||
|
@ -769,14 +870,15 @@ gimp_curve_set_point (GimpCurve *curve,
|
|||
{
|
||||
g_return_if_fail (GIMP_IS_CURVE (curve));
|
||||
g_return_if_fail (point >= 0 && point < curve->n_points);
|
||||
g_return_if_fail (x == -1.0 || (x >= 0 && x <= 1.0));
|
||||
g_return_if_fail (y == -1.0 || (y >= 0 && y <= 1.0));
|
||||
|
||||
if (curve->curve_type == GIMP_CURVE_FREE)
|
||||
return;
|
||||
curve->points[point].x = CLAMP (x, 0.0, 1.0);
|
||||
curve->points[point].y = CLAMP (y, 0.0, 1.0);
|
||||
|
||||
curve->points[point].x = x;
|
||||
curve->points[point].y = y;
|
||||
if (point > 0)
|
||||
curve->points[point].x = MAX (x, curve->points[point - 1].x);
|
||||
|
||||
if (point < curve->n_points - 1)
|
||||
curve->points[point].x = MIN (x, curve->points[point + 1].x);
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
|
||||
|
@ -790,40 +892,8 @@ gimp_curve_move_point (GimpCurve *curve,
|
|||
{
|
||||
g_return_if_fail (GIMP_IS_CURVE (curve));
|
||||
g_return_if_fail (point >= 0 && point < curve->n_points);
|
||||
g_return_if_fail (y >= 0 && y <= 1.0);
|
||||
|
||||
if (curve->curve_type == GIMP_CURVE_FREE)
|
||||
return;
|
||||
|
||||
curve->points[point].y = y;
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
|
||||
gimp_data_dirty (GIMP_DATA (curve));
|
||||
}
|
||||
|
||||
void
|
||||
gimp_curve_delete_point (GimpCurve *curve,
|
||||
gint point)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_CURVE (curve));
|
||||
g_return_if_fail (point >= 0 && point < curve->n_points);
|
||||
|
||||
if (point == 0)
|
||||
{
|
||||
curve->points[0].x = 0.0;
|
||||
curve->points[0].y = 0.0;
|
||||
}
|
||||
else if (point == curve->n_points - 1)
|
||||
{
|
||||
curve->points[curve->n_points - 1].x = 1.0;
|
||||
curve->points[curve->n_points - 1].y = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
curve->points[point].x = -1.0;
|
||||
curve->points[point].y = -1.0;
|
||||
}
|
||||
curve->points[point].y = CLAMP (y, 0.0, 1.0);
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
|
||||
|
@ -839,18 +909,27 @@ gimp_curve_get_point (GimpCurve *curve,
|
|||
g_return_if_fail (GIMP_IS_CURVE (curve));
|
||||
g_return_if_fail (point >= 0 && point < curve->n_points);
|
||||
|
||||
if (curve->curve_type == GIMP_CURVE_FREE)
|
||||
{
|
||||
if (x) *x = -1.0;
|
||||
if (y) *y = -1.0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (x) *x = curve->points[point].x;
|
||||
if (y) *y = curve->points[point].y;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_curve_clear_points (GimpCurve *curve)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_CURVE (curve));
|
||||
|
||||
if (curve->points)
|
||||
{
|
||||
curve->n_points = 0;
|
||||
g_clear_pointer (&curve->points, g_free);
|
||||
|
||||
g_object_notify (G_OBJECT (curve), "n-points");
|
||||
g_object_notify (G_OBJECT (curve), "points");
|
||||
|
||||
gimp_data_dirty (GIMP_DATA (curve));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_curve_set_curve (GimpCurve *curve,
|
||||
gdouble x,
|
||||
|
@ -909,59 +988,49 @@ gimp_curve_get_uchar (GimpCurve *curve,
|
|||
static void
|
||||
gimp_curve_calculate (GimpCurve *curve)
|
||||
{
|
||||
gint *points;
|
||||
gint i;
|
||||
gint num_pts;
|
||||
gint p1, p2, p3, p4;
|
||||
gint i;
|
||||
gint p1, p2, p3, p4;
|
||||
|
||||
if (gimp_data_is_frozen (GIMP_DATA (curve)))
|
||||
return;
|
||||
|
||||
points = g_newa (gint, curve->n_points);
|
||||
|
||||
switch (curve->curve_type)
|
||||
{
|
||||
case GIMP_CURVE_SMOOTH:
|
||||
/* cycle through the curves */
|
||||
num_pts = 0;
|
||||
for (i = 0; i < curve->n_points; i++)
|
||||
if (curve->points[i].x >= 0.0)
|
||||
points[num_pts++] = i;
|
||||
|
||||
/* Initialize boundary curve points */
|
||||
if (num_pts != 0)
|
||||
if (curve->n_points > 0)
|
||||
{
|
||||
GimpVector2 point;
|
||||
gint boundary;
|
||||
|
||||
point = curve->points[points[0]];
|
||||
point = curve->points[0];
|
||||
boundary = ROUND (point.x * (gdouble) (curve->n_samples - 1));
|
||||
|
||||
for (i = 0; i < boundary; i++)
|
||||
curve->samples[i] = point.y;
|
||||
|
||||
point = curve->points[points[num_pts - 1]];
|
||||
point = curve->points[curve->n_points - 1];
|
||||
boundary = ROUND (point.x * (gdouble) (curve->n_samples - 1));
|
||||
|
||||
for (i = boundary; i < curve->n_samples; i++)
|
||||
curve->samples[i] = point.y;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_pts - 1; i++)
|
||||
for (i = 0; i < curve->n_points - 1; i++)
|
||||
{
|
||||
p1 = points[MAX (i - 1, 0)];
|
||||
p2 = points[i];
|
||||
p3 = points[i + 1];
|
||||
p4 = points[MIN (i + 2, num_pts - 1)];
|
||||
p1 = MAX (i - 1, 0);
|
||||
p2 = i;
|
||||
p3 = i + 1;
|
||||
p4 = MIN (i + 2, curve->n_points - 1);
|
||||
|
||||
gimp_curve_plot (curve, p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
/* ensure that the control points are used exactly */
|
||||
for (i = 0; i < num_pts; i++)
|
||||
for (i = 0; i < curve->n_points; i++)
|
||||
{
|
||||
gdouble x = curve->points[points[i]].x;
|
||||
gdouble y = curve->points[points[i]].y;
|
||||
gdouble x = curve->points[i].x;
|
||||
gdouble y = curve->points[i].y;
|
||||
|
||||
curve->samples[ROUND (x * (gdouble) (curve->n_samples - 1))] = y;
|
||||
}
|
||||
|
@ -1013,7 +1082,16 @@ gimp_curve_plot (GimpCurve *curve,
|
|||
dx = x3 - x0;
|
||||
dy = y3 - y0;
|
||||
|
||||
g_return_if_fail (dx > 0);
|
||||
if (dx <= EPSILON)
|
||||
{
|
||||
gint index;
|
||||
|
||||
index = ROUND (x0 * (gdouble) (curve->n_samples - 1));
|
||||
|
||||
curve->samples[index] = y3;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (p1 == p2 && p3 == p4)
|
||||
{
|
||||
|
|
|
@ -65,17 +65,24 @@ void gimp_curve_set_curve_type (GimpCurve *curve,
|
|||
GimpCurveType curve_type);
|
||||
GimpCurveType gimp_curve_get_curve_type (GimpCurve *curve);
|
||||
|
||||
void gimp_curve_set_n_points (GimpCurve *curve,
|
||||
gint n_points);
|
||||
gint gimp_curve_get_n_points (GimpCurve *curve);
|
||||
|
||||
void gimp_curve_set_n_samples (GimpCurve *curve,
|
||||
gint n_samples);
|
||||
gint gimp_curve_get_n_samples (GimpCurve *curve);
|
||||
|
||||
gint gimp_curve_get_closest_point (GimpCurve *curve,
|
||||
gint gimp_curve_get_point_at (GimpCurve *curve,
|
||||
gdouble x);
|
||||
gint gimp_curve_get_closest_point (GimpCurve *curve,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble max_distance);
|
||||
|
||||
gint gimp_curve_add_point (GimpCurve *curve,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
void gimp_curve_delete_point (GimpCurve *curve,
|
||||
gint point);
|
||||
void gimp_curve_set_point (GimpCurve *curve,
|
||||
gint point,
|
||||
gdouble x,
|
||||
|
@ -83,12 +90,11 @@ void gimp_curve_set_point (GimpCurve *curve,
|
|||
void gimp_curve_move_point (GimpCurve *curve,
|
||||
gint point,
|
||||
gdouble y);
|
||||
void gimp_curve_delete_point (GimpCurve *curve,
|
||||
gint point);
|
||||
void gimp_curve_get_point (GimpCurve *curve,
|
||||
gint point,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
void gimp_curve_clear_points (GimpCurve *curve);
|
||||
|
||||
void gimp_curve_set_curve (GimpCurve *curve,
|
||||
gdouble x,
|
||||
|
|
|
@ -421,13 +421,10 @@ gimp_curves_config_new_spline (gint32 channel,
|
|||
gimp_data_freeze (GIMP_DATA (curve));
|
||||
|
||||
gimp_curve_set_curve_type (curve, GIMP_CURVE_SMOOTH);
|
||||
gimp_curve_set_n_points (curve, n_points);
|
||||
|
||||
/* unset the last point */
|
||||
gimp_curve_set_point (curve, curve->n_points - 1, -1.0, -1.0);
|
||||
gimp_curve_clear_points (curve);
|
||||
|
||||
for (i = 0; i < n_points; i++)
|
||||
gimp_curve_set_point (curve, i,
|
||||
gimp_curve_add_point (curve,
|
||||
(gdouble) points[i * 2],
|
||||
(gdouble) points[i * 2 + 1]);
|
||||
|
||||
|
@ -617,18 +614,18 @@ gimp_curves_config_load_cruft (GimpCurvesConfig *config,
|
|||
gimp_data_freeze (GIMP_DATA (curve));
|
||||
|
||||
gimp_curve_set_curve_type (curve, GIMP_CURVE_SMOOTH);
|
||||
gimp_curve_set_n_points (curve, GIMP_CURVE_N_CRUFT_POINTS);
|
||||
|
||||
gimp_curve_reset (curve, FALSE);
|
||||
gimp_curve_clear_points (curve);
|
||||
|
||||
for (j = 0; j < GIMP_CURVE_N_CRUFT_POINTS; j++)
|
||||
{
|
||||
if (index[i][j] < 0 || value[i][j] < 0)
|
||||
gimp_curve_set_point (curve, j, -1.0, -1.0);
|
||||
else
|
||||
gimp_curve_set_point (curve, j,
|
||||
(gdouble) index[i][j] / 255.0,
|
||||
(gdouble) value[i][j] / 255.0);
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
|
||||
x = (gdouble) index[i][j] / 255.0;
|
||||
y = (gdouble) value[i][j] / 255.0;
|
||||
|
||||
if (x >= 0.0)
|
||||
gimp_curve_add_point (curve, x, y);
|
||||
}
|
||||
|
||||
gimp_data_thaw (GIMP_DATA (curve));
|
||||
|
@ -662,50 +659,34 @@ gimp_curves_config_save_cruft (GimpCurvesConfig *config,
|
|||
GimpCurve *curve = config->curve[i];
|
||||
gint j;
|
||||
|
||||
if (curve->curve_type == GIMP_CURVE_FREE)
|
||||
if (curve->curve_type == GIMP_CURVE_SMOOTH)
|
||||
{
|
||||
gint n_points;
|
||||
g_object_ref (curve);
|
||||
}
|
||||
else
|
||||
{
|
||||
curve = GIMP_CURVE (gimp_data_duplicate (GIMP_DATA (curve)));
|
||||
|
||||
for (j = 0; j < curve->n_points; j++)
|
||||
{
|
||||
curve->points[j].x = -1;
|
||||
curve->points[j].y = -1;
|
||||
}
|
||||
|
||||
/* pick some points from the curve and make them control
|
||||
* points
|
||||
*/
|
||||
n_points = CLAMP (9, curve->n_points / 2, curve->n_points);
|
||||
|
||||
for (j = 0; j < n_points; j++)
|
||||
{
|
||||
gint sample = j * (curve->n_samples - 1) / (n_points - 1);
|
||||
gint point = j * (curve->n_points - 1) / (n_points - 1);
|
||||
|
||||
curve->points[point].x = ((gdouble) sample /
|
||||
(gdouble) (curve->n_samples - 1));
|
||||
curve->points[point].y = curve->samples[sample];
|
||||
}
|
||||
gimp_curve_set_curve_type (curve, GIMP_CURVE_SMOOTH);
|
||||
}
|
||||
|
||||
for (j = 0; j < curve->n_points; j++)
|
||||
for (j = 0; j < GIMP_CURVE_N_CRUFT_POINTS; j++)
|
||||
{
|
||||
/* don't use gimp_curve_get_point() because that doesn't
|
||||
* work when the curve type is GIMP_CURVE_FREE
|
||||
*/
|
||||
gdouble x = curve->points[j].x;
|
||||
gdouble y = curve->points[j].y;
|
||||
gint x = -1;
|
||||
gint y = -1;
|
||||
|
||||
if (x < 0.0 || y < 0.0)
|
||||
if (j < gimp_curve_get_n_points (curve))
|
||||
{
|
||||
g_string_append_printf (string, "%d %d ", -1, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_printf (string, "%d %d ",
|
||||
(gint) (x * 255.999),
|
||||
(gint) (y * 255.999));
|
||||
gdouble point_x;
|
||||
gdouble point_y;
|
||||
|
||||
gimp_curve_get_point (curve, j, &point_x, &point_y);
|
||||
|
||||
x = floor (point_x * 255.999);
|
||||
y = floor (point_y * 255.999);
|
||||
}
|
||||
|
||||
g_string_append_printf (string, "%d %d ", x, y);
|
||||
}
|
||||
|
||||
g_string_append_printf (string, "\n");
|
||||
|
|
|
@ -715,17 +715,14 @@ gimp_levels_config_to_curves_config (GimpLevelsConfig *config)
|
|||
channel++)
|
||||
{
|
||||
GimpCurve *curve = curves->curve[channel];
|
||||
const gint n_points = gimp_curve_get_n_points (curve);
|
||||
static const gint n = 8;
|
||||
gint point = -1;
|
||||
gdouble gamma = config->gamma[channel];
|
||||
gdouble delta_in;
|
||||
gdouble delta_out;
|
||||
gdouble x, y;
|
||||
|
||||
/* clear the points set by default */
|
||||
gimp_curve_set_point (curve, 0, -1, -1);
|
||||
gimp_curve_set_point (curve, n_points - 1, -1, -1);
|
||||
gimp_curve_clear_points (curve);
|
||||
|
||||
delta_in = config->high_input[channel] - config->low_input[channel];
|
||||
delta_out = config->high_output[channel] - config->low_output[channel];
|
||||
|
@ -733,8 +730,7 @@ gimp_levels_config_to_curves_config (GimpLevelsConfig *config)
|
|||
x = config->low_input[channel];
|
||||
y = config->low_output[channel];
|
||||
|
||||
point = CLAMP (n_points * x, point + 1, n_points - 1 - n);
|
||||
gimp_curve_set_point (curve, point, x, y);
|
||||
gimp_curve_add_point (curve, x, y);
|
||||
|
||||
if (delta_out != 0 && gamma != 1.0)
|
||||
{
|
||||
|
@ -774,8 +770,7 @@ gimp_levels_config_to_curves_config (GimpLevelsConfig *config)
|
|||
x = config->low_input[channel] + dx;
|
||||
y = config->low_output[channel] + delta_out *
|
||||
gimp_operation_levels_map_input (config, channel, x);
|
||||
point = CLAMP (n_points * x, point + 1, n_points - 1 - n + i);
|
||||
gimp_curve_set_point (curve, point, x, y);
|
||||
gimp_curve_add_point (curve, x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -811,8 +806,7 @@ gimp_levels_config_to_curves_config (GimpLevelsConfig *config)
|
|||
y = config->low_output[channel] + dy;
|
||||
x = config->low_input[channel] + delta_in *
|
||||
gimp_operation_levels_map_input (config_inv, channel, y);
|
||||
point = CLAMP (n_points * x, point + 1, n_points - 1 - n + i);
|
||||
gimp_curve_set_point (curve, point, x, y);
|
||||
gimp_curve_add_point (curve, x, y);
|
||||
}
|
||||
|
||||
g_object_unref (config_inv);
|
||||
|
@ -822,8 +816,7 @@ gimp_levels_config_to_curves_config (GimpLevelsConfig *config)
|
|||
x = config->high_input[channel];
|
||||
y = config->high_output[channel];
|
||||
|
||||
point = CLAMP (n_points * x, point + 1, n_points - 1);
|
||||
gimp_curve_set_point (curve, point, x, y);
|
||||
gimp_curve_add_point (curve, x, y);
|
||||
}
|
||||
|
||||
return curves;
|
||||
|
|
|
@ -242,15 +242,18 @@ gimp_curves_tool_button_release (GimpTool *tool,
|
|||
{
|
||||
GimpCurve *curve = config->curve[config->channel];
|
||||
gdouble value = c_tool->picked_color[config->channel];
|
||||
gint closest;
|
||||
gint point;
|
||||
|
||||
closest = gimp_curve_get_closest_point (curve, value);
|
||||
point = gimp_curve_get_point_at (curve, value);
|
||||
|
||||
gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph),
|
||||
closest);
|
||||
if (point < 0)
|
||||
{
|
||||
point = gimp_curve_add_point (
|
||||
curve,
|
||||
value, gimp_curve_map_value (curve, value));
|
||||
}
|
||||
|
||||
gimp_curve_set_point (curve, closest,
|
||||
value, gimp_curve_map_value (curve, value));
|
||||
gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph), point);
|
||||
}
|
||||
else if (state & gimp_get_toggle_behavior_mask ())
|
||||
{
|
||||
|
@ -262,17 +265,25 @@ gimp_curves_tool_button_release (GimpTool *tool,
|
|||
{
|
||||
GimpCurve *curve = config->curve[channel];
|
||||
gdouble value = c_tool->picked_color[channel];
|
||||
gint closest;
|
||||
|
||||
if (value != -1)
|
||||
{
|
||||
closest = gimp_curve_get_closest_point (curve, value);
|
||||
gint point;
|
||||
|
||||
gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph),
|
||||
closest);
|
||||
point = gimp_curve_get_point_at (curve, value);
|
||||
|
||||
gimp_curve_set_point (curve, closest,
|
||||
value, gimp_curve_map_value (curve, value));
|
||||
if (point < 0)
|
||||
{
|
||||
point = gimp_curve_add_point (
|
||||
curve,
|
||||
value, gimp_curve_map_value (curve, value));
|
||||
}
|
||||
|
||||
if (channel == config->channel)
|
||||
{
|
||||
gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph),
|
||||
point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#include "gimpwidgets-utils.h"
|
||||
|
||||
|
||||
#define POINT_MAX_DISTANCE 16.0
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@ -68,39 +71,45 @@ typedef struct
|
|||
} BGCurve;
|
||||
|
||||
|
||||
static void gimp_curve_view_finalize (GObject *object);
|
||||
static void gimp_curve_view_dispose (GObject *object);
|
||||
static void gimp_curve_view_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_curve_view_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_curve_view_finalize (GObject *object);
|
||||
static void gimp_curve_view_dispose (GObject *object);
|
||||
static void gimp_curve_view_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_curve_view_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void gimp_curve_view_style_updated (GtkWidget *widget);
|
||||
static gboolean gimp_curve_view_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static gboolean gimp_curve_view_button_press (GtkWidget *widget,
|
||||
GdkEventButton *bevent);
|
||||
static gboolean gimp_curve_view_button_release (GtkWidget *widget,
|
||||
GdkEventButton *bevent);
|
||||
static gboolean gimp_curve_view_motion_notify (GtkWidget *widget,
|
||||
GdkEventMotion *bevent);
|
||||
static gboolean gimp_curve_view_leave_notify (GtkWidget *widget,
|
||||
GdkEventCrossing *cevent);
|
||||
static gboolean gimp_curve_view_key_press (GtkWidget *widget,
|
||||
GdkEventKey *kevent);
|
||||
static void gimp_curve_view_style_updated (GtkWidget *widget);
|
||||
static gboolean gimp_curve_view_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static gboolean gimp_curve_view_button_press (GtkWidget *widget,
|
||||
GdkEventButton *bevent);
|
||||
static gboolean gimp_curve_view_button_release (GtkWidget *widget,
|
||||
GdkEventButton *bevent);
|
||||
static gboolean gimp_curve_view_motion_notify (GtkWidget *widget,
|
||||
GdkEventMotion *bevent);
|
||||
static gboolean gimp_curve_view_leave_notify (GtkWidget *widget,
|
||||
GdkEventCrossing *cevent);
|
||||
static gboolean gimp_curve_view_key_press (GtkWidget *widget,
|
||||
GdkEventKey *kevent);
|
||||
|
||||
static void gimp_curve_view_cut_clipboard (GimpCurveView *view);
|
||||
static void gimp_curve_view_copy_clipboard (GimpCurveView *view);
|
||||
static void gimp_curve_view_paste_clipboard (GimpCurveView *view);
|
||||
static void gimp_curve_view_cut_clipboard (GimpCurveView *view);
|
||||
static void gimp_curve_view_copy_clipboard (GimpCurveView *view);
|
||||
static void gimp_curve_view_paste_clipboard (GimpCurveView *view);
|
||||
|
||||
static void gimp_curve_view_set_cursor (GimpCurveView *view,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
static void gimp_curve_view_unset_cursor (GimpCurveView *view);
|
||||
static void gimp_curve_view_curve_dirty (GimpCurve *curve,
|
||||
GimpCurveView *view);
|
||||
static void gimp_curve_view_curve_notify_n_points (GimpCurve *curve,
|
||||
GParamSpec *pspec,
|
||||
GimpCurveView *view);
|
||||
|
||||
static void gimp_curve_view_set_cursor (GimpCurveView *view,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
static void gimp_curve_view_unset_cursor (GimpCurveView *view);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpCurveView, gimp_curve_view,
|
||||
|
@ -211,7 +220,7 @@ static void
|
|||
gimp_curve_view_init (GimpCurveView *view)
|
||||
{
|
||||
view->curve = NULL;
|
||||
view->selected = 0;
|
||||
view->selected = -1;
|
||||
view->offset_x = 0.0;
|
||||
view->offset_y = 0.0;
|
||||
view->last_x = 0.0;
|
||||
|
@ -418,9 +427,6 @@ gimp_curve_view_draw_point (GimpCurveView *view,
|
|||
|
||||
gimp_curve_get_point (view->curve, i, &x, &y);
|
||||
|
||||
if (x < 0.0)
|
||||
return;
|
||||
|
||||
y = 1.0 - y;
|
||||
|
||||
#define RADIUS 3
|
||||
|
@ -789,10 +795,9 @@ gimp_curve_view_button_press (GtkWidget *widget,
|
|||
gint width, height;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
gint point;
|
||||
gdouble point_x;
|
||||
gdouble point_y;
|
||||
gint closest_point;
|
||||
gint i;
|
||||
|
||||
if (! curve || bevent->button != 1)
|
||||
return TRUE;
|
||||
|
@ -809,8 +814,6 @@ gimp_curve_view_button_press (GtkWidget *widget,
|
|||
x = CLAMP (x, 0.0, 1.0);
|
||||
y = CLAMP (y, 0.0, 1.0);
|
||||
|
||||
closest_point = gimp_curve_get_closest_point (curve, x);
|
||||
|
||||
view->grabbed = TRUE;
|
||||
|
||||
view->orig_curve = GIMP_CURVE (gimp_data_duplicate (GIMP_DATA (curve)));
|
||||
|
@ -820,47 +823,34 @@ gimp_curve_view_button_press (GtkWidget *widget,
|
|||
switch (gimp_curve_get_curve_type (curve))
|
||||
{
|
||||
case GIMP_CURVE_SMOOTH:
|
||||
/* determine the leftmost and rightmost points */
|
||||
view->leftmost = -1.0;
|
||||
for (i = closest_point - 1; i >= 0; i--)
|
||||
{
|
||||
gimp_curve_get_point (curve, i, &point_x, NULL);
|
||||
point = gimp_curve_get_closest_point (curve, x, 1.0 - y,
|
||||
POINT_MAX_DISTANCE /
|
||||
MAX (width, height));
|
||||
|
||||
if (point_x >= 0.0)
|
||||
{
|
||||
view->leftmost = point_x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
view->rightmost = 2.0;
|
||||
for (i = closest_point + 1; i < curve->n_points; i++)
|
||||
{
|
||||
gimp_curve_get_point (curve, i, &point_x, NULL);
|
||||
|
||||
if (point_x >= 0.0)
|
||||
{
|
||||
view->rightmost = point_x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gimp_curve_view_set_selected (view, closest_point);
|
||||
|
||||
gimp_curve_get_point (curve, view->selected, &point_x, &point_y);
|
||||
|
||||
if (point_x >= 0.0)
|
||||
{
|
||||
view->offset_x = point_x - x;
|
||||
view->offset_y = (1.0 - point_y) - y;
|
||||
}
|
||||
else
|
||||
if (point < 0)
|
||||
{
|
||||
if (bevent->state & gimp_get_constrain_behavior_mask ())
|
||||
y = 1.0 - gimp_curve_map_value (view->orig_curve, x);
|
||||
|
||||
gimp_curve_set_point (curve, view->selected, x, 1.0 - y);
|
||||
point = gimp_curve_add_point (curve, x, 1.0 - y);
|
||||
}
|
||||
|
||||
if (point > 0)
|
||||
gimp_curve_get_point (curve, point - 1, &view->leftmost, NULL);
|
||||
else
|
||||
view->leftmost = -1.0;
|
||||
|
||||
if (point < gimp_curve_get_n_points (curve) - 1)
|
||||
gimp_curve_get_point (curve, point + 1, &view->rightmost, NULL);
|
||||
else
|
||||
view->rightmost = 2.0;
|
||||
|
||||
gimp_curve_view_set_selected (view, point);
|
||||
|
||||
gimp_curve_get_point (curve, point, &point_x, &point_y);
|
||||
|
||||
view->offset_x = point_x - x;
|
||||
view->offset_y = (1.0 - point_y) - y;
|
||||
break;
|
||||
|
||||
case GIMP_CURVE_FREE:
|
||||
|
@ -912,7 +902,7 @@ gimp_curve_view_motion_notify (GtkWidget *widget,
|
|||
gdouble y;
|
||||
gdouble point_x;
|
||||
gdouble point_y;
|
||||
gint closest_point;
|
||||
gint point;
|
||||
|
||||
if (! curve)
|
||||
return TRUE;
|
||||
|
@ -932,17 +922,19 @@ gimp_curve_view_motion_notify (GtkWidget *widget,
|
|||
x = CLAMP (x, 0.0, 1.0);
|
||||
y = CLAMP (y, 0.0, 1.0);
|
||||
|
||||
closest_point = gimp_curve_get_closest_point (curve, x);
|
||||
|
||||
switch (gimp_curve_get_curve_type (curve))
|
||||
{
|
||||
case GIMP_CURVE_SMOOTH:
|
||||
if (! view->grabbed) /* If no point is grabbed... */
|
||||
{
|
||||
gimp_curve_get_point (curve, closest_point, &point_x, &point_y);
|
||||
point = gimp_curve_get_closest_point (curve, x, 1.0 - y,
|
||||
POINT_MAX_DISTANCE /
|
||||
MAX (width, height));
|
||||
|
||||
if (point_x >= 0.0)
|
||||
if (point >= 0)
|
||||
{
|
||||
gimp_curve_get_point (curve, point, &point_x, &point_y);
|
||||
|
||||
new_cursor = GDK_FLEUR;
|
||||
|
||||
x = point_x;
|
||||
|
@ -965,20 +957,27 @@ gimp_curve_view_motion_notify (GtkWidget *widget,
|
|||
|
||||
gimp_data_freeze (GIMP_DATA (curve));
|
||||
|
||||
gimp_curve_set_point (curve, view->selected, -1.0, -1.0);
|
||||
|
||||
if (x > view->leftmost && x < view->rightmost)
|
||||
{
|
||||
gint n_points = gimp_curve_get_n_points (curve);
|
||||
if (view->selected < 0)
|
||||
{
|
||||
gimp_curve_view_set_selected (
|
||||
view,
|
||||
gimp_curve_add_point (curve, x, 1.0 - y));
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_curve_set_point (curve, view->selected, x, 1.0 - y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (view->selected >= 0)
|
||||
{
|
||||
gimp_curve_delete_point (curve, view->selected);
|
||||
|
||||
closest_point = ROUND (x * (gdouble) (n_points - 1));
|
||||
|
||||
gimp_curve_get_point (curve, closest_point, &point_x, NULL);
|
||||
|
||||
if (point_x < 0.0)
|
||||
gimp_curve_view_set_selected (view, closest_point);
|
||||
|
||||
gimp_curve_set_point (curve, view->selected, x, 1.0 - y);
|
||||
gimp_curve_view_set_selected (view, -1);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_data_thaw (GIMP_DATA (curve));
|
||||
|
@ -1071,8 +1070,10 @@ gimp_curve_view_key_press (GtkWidget *widget,
|
|||
GimpCurve *curve = view->curve;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
if (! view->grabbed && curve &&
|
||||
gimp_curve_get_curve_type (curve) == GIMP_CURVE_SMOOTH)
|
||||
if (! view->grabbed &&
|
||||
curve &&
|
||||
gimp_curve_get_curve_type (curve) == GIMP_CURVE_SMOOTH &&
|
||||
view->selected >= 0)
|
||||
{
|
||||
gint i = view->selected;
|
||||
gdouble x, y;
|
||||
|
@ -1209,6 +1210,21 @@ gimp_curve_view_paste_clipboard (GimpCurveView *view)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_curve_view_curve_dirty (GimpCurve *curve,
|
||||
GimpCurveView *view)
|
||||
{
|
||||
gtk_widget_queue_draw (GTK_WIDGET (view));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_curve_view_curve_notify_n_points (GimpCurve *curve,
|
||||
GParamSpec *pspec,
|
||||
GimpCurveView *view)
|
||||
{
|
||||
gimp_curve_view_set_selected (view, -1);
|
||||
}
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
|
@ -1218,13 +1234,6 @@ gimp_curve_view_new (void)
|
|||
return g_object_new (GIMP_TYPE_CURVE_VIEW, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_curve_view_curve_dirty (GimpCurve *curve,
|
||||
GimpCurveView *view)
|
||||
{
|
||||
gtk_widget_queue_draw (GTK_WIDGET (view));
|
||||
}
|
||||
|
||||
void
|
||||
gimp_curve_view_set_curve (GimpCurveView *view,
|
||||
GimpCurve *curve,
|
||||
|
@ -1241,6 +1250,9 @@ gimp_curve_view_set_curve (GimpCurveView *view,
|
|||
g_signal_handlers_disconnect_by_func (view->curve,
|
||||
gimp_curve_view_curve_dirty,
|
||||
view);
|
||||
g_signal_handlers_disconnect_by_func (view->curve,
|
||||
gimp_curve_view_curve_notify_n_points,
|
||||
view);
|
||||
g_object_unref (view->curve);
|
||||
}
|
||||
|
||||
|
@ -1252,6 +1264,9 @@ gimp_curve_view_set_curve (GimpCurveView *view,
|
|||
g_signal_connect (view->curve, "dirty",
|
||||
G_CALLBACK (gimp_curve_view_curve_dirty),
|
||||
view);
|
||||
g_signal_connect (view->curve, "notify::n-points",
|
||||
G_CALLBACK (gimp_curve_view_curve_notify_n_points),
|
||||
view);
|
||||
}
|
||||
|
||||
if (view->curve_color)
|
||||
|
@ -1262,6 +1277,8 @@ gimp_curve_view_set_curve (GimpCurveView *view,
|
|||
else
|
||||
view->curve_color = NULL;
|
||||
|
||||
gimp_curve_view_set_selected (view, -1);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (view));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue