Commit 009766a8 authored by Simon Budig's avatar Simon Budig Committed by Simon Budig

app/vectors/gimpstroke.[ch] Implemented direct moving of the curve. Whee!

2003-08-26  Simon Budig  <simon@gimp.org>

	* app/vectors/gimpstroke.[ch]
	* app/vectors/gimpbezierstroke.c: Implemented direct moving of the
	curve. Whee!  :-)

	* app/tools/gimpvectortool.[ch]: Use it.
parent dc95e16b
2003-08-26 Simon Budig <simon@gimp.org>
* app/vectors/gimpstroke.[ch]
* app/vectors/gimpbezierstroke.c: Implemented direct moving of the
curve. Whee! :-)
* app/tools/gimpvectortool.[ch]: Use it.
2003-08-25 Michael Natterer <mitch@gimp.org> 2003-08-25 Michael Natterer <mitch@gimp.org>
* app/core/core-enums.[ch]: added enum GimpContainerPolicy. * app/core/core-enums.[ch]: added enum GimpContainerPolicy.
...@@ -438,6 +438,21 @@ gimp_vector_tool_button_press (GimpTool *tool, ...@@ -438,6 +438,21 @@ gimp_vector_tool_button_press (GimpTool *tool,
break; /* here it is... :-) */ break; /* here it is... :-) */
case VECTORS_MOVE_CURVE:
if (gimp_vector_tool_on_curve (tool, coords, gdisp,
NULL, &pos, &segment_start, &stroke)
&& gimp_stroke_point_is_movable (stroke, segment_start, pos))
{
vector_tool->cur_stroke = stroke;
vector_tool->cur_anchor = segment_start;
vector_tool->cur_position = pos;
}
else
{
vector_tool->function = VECTORS_FINISHED;
}
break;
case VECTORS_CONVERT_EDGE: case VECTORS_CONVERT_EDGE:
if (gimp_vector_tool_on_handle (tool, coords, if (gimp_vector_tool_on_handle (tool, coords,
GIMP_ANCHOR_ANCHOR, gdisp, GIMP_ANCHOR_ANCHOR, gdisp,
...@@ -544,6 +559,14 @@ gimp_vector_tool_motion (GimpTool *tool, ...@@ -544,6 +559,14 @@ gimp_vector_tool_motion (GimpTool *tool,
gimp_stroke_anchor_move_absolute (vector_tool->cur_stroke, gimp_stroke_anchor_move_absolute (vector_tool->cur_stroke,
vector_tool->cur_anchor, vector_tool->cur_anchor,
coords, vector_tool->restriction); coords, vector_tool->restriction);
break;
case VECTORS_MOVE_CURVE:
gimp_stroke_point_move_absolute (vector_tool->cur_stroke,
vector_tool->cur_anchor,
vector_tool->cur_position,
coords, vector_tool->restriction);
break;
default: default:
break; break;
...@@ -894,10 +917,8 @@ gimp_vector_tool_cursor_update (GimpTool *tool, ...@@ -894,10 +917,8 @@ gimp_vector_tool_cursor_update (GimpTool *tool,
cmodifier = GIMP_CURSOR_MODIFIER_HAND; cmodifier = GIMP_CURSOR_MODIFIER_HAND;
break; break;
case VECTORS_MOVE_ANCHOR: case VECTORS_MOVE_ANCHOR:
cmodifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case VECTORS_MOVE_CURVE: case VECTORS_MOVE_CURVE:
cmodifier = GIMP_CURSOR_MODIFIER_NONE; cmodifier = GIMP_CURSOR_MODIFIER_MOVE;
break; break;
default: default:
cursor = GIMP_BAD_CURSOR; cursor = GIMP_BAD_CURSOR;
......
...@@ -63,10 +63,11 @@ struct _GimpVectorTool ...@@ -63,10 +63,11 @@ struct _GimpVectorTool
gint last_x; /* last x coordinate */ gint last_x; /* last x coordinate */
gint last_y; /* last y coordinate */ gint last_y; /* last y coordinate */
GimpAnchor *cur_anchor; /* The current Anchor */ GimpAnchor *cur_anchor; /* The current Anchor */
GimpStroke *cur_stroke; /* The current Stroke */ GimpStroke *cur_stroke; /* The current Stroke */
GimpVectors *vectors; /* The current Vector data */ gdouble cur_position; /* The current Position on a segment */
GList *active_anchors; /* The currently active anchors */ GimpVectors *vectors; /* The current Vector data */
GList *active_anchors; /* The currently active anchors */
}; };
struct _GimpVectorToolClass struct _GimpVectorToolClass
......
...@@ -62,6 +62,24 @@ static void gimp_bezier_stroke_anchor_convert (GimpStroke *stroke, ...@@ -62,6 +62,24 @@ static void gimp_bezier_stroke_anchor_convert (GimpStroke *stroke,
GimpAnchorFeatureType feature); GimpAnchorFeatureType feature);
static void gimp_bezier_stroke_anchor_delete (GimpStroke *stroke, static void gimp_bezier_stroke_anchor_delete (GimpStroke *stroke,
GimpAnchor *anchor); GimpAnchor *anchor);
static gboolean gimp_bezier_stroke_point_is_movable
(GimpStroke *stroke,
GimpAnchor *predec,
gdouble position);
static void gimp_bezier_stroke_point_move_relative
(GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *deltacoord,
GimpAnchorFeatureType feature);
static void gimp_bezier_stroke_point_move_absolute
(GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *coord,
GimpAnchorFeatureType feature);
static GimpStroke * gimp_bezier_stroke_open (GimpStroke *stroke, static GimpStroke * gimp_bezier_stroke_open (GimpStroke *stroke,
GimpAnchor *end_anchor); GimpAnchor *end_anchor);
static gboolean gimp_bezier_stroke_anchor_is_insertable static gboolean gimp_bezier_stroke_anchor_is_insertable
...@@ -163,6 +181,9 @@ gimp_bezier_stroke_class_init (GimpBezierStrokeClass *klass) ...@@ -163,6 +181,9 @@ gimp_bezier_stroke_class_init (GimpBezierStrokeClass *klass)
stroke_class->anchor_move_absolute = gimp_bezier_stroke_anchor_move_absolute; stroke_class->anchor_move_absolute = gimp_bezier_stroke_anchor_move_absolute;
stroke_class->anchor_convert = gimp_bezier_stroke_anchor_convert; stroke_class->anchor_convert = gimp_bezier_stroke_anchor_convert;
stroke_class->anchor_delete = gimp_bezier_stroke_anchor_delete; stroke_class->anchor_delete = gimp_bezier_stroke_anchor_delete;
stroke_class->point_is_movable = gimp_bezier_stroke_point_is_movable;
stroke_class->point_move_relative = gimp_bezier_stroke_point_move_relative;
stroke_class->point_move_absolute = gimp_bezier_stroke_point_move_absolute;
stroke_class->open = gimp_bezier_stroke_open; stroke_class->open = gimp_bezier_stroke_open;
stroke_class->anchor_is_insertable = gimp_bezier_stroke_anchor_is_insertable; stroke_class->anchor_is_insertable = gimp_bezier_stroke_anchor_is_insertable;
stroke_class->anchor_insert = gimp_bezier_stroke_anchor_insert; stroke_class->anchor_insert = gimp_bezier_stroke_anchor_insert;
...@@ -409,6 +430,118 @@ gimp_bezier_stroke_anchor_insert (GimpStroke *stroke, ...@@ -409,6 +430,118 @@ gimp_bezier_stroke_anchor_insert (GimpStroke *stroke,
} }
static gboolean
gimp_bezier_stroke_point_is_movable (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position)
{
g_return_val_if_fail (GIMP_IS_BEZIER_STROKE (stroke), FALSE);
return (g_list_find (stroke->anchors, predec) != NULL);
}
static void
gimp_bezier_stroke_point_move_relative (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *deltacoord,
GimpAnchorFeatureType feature)
{
GimpCoords beziercoords[4];
GList *segment_start, *list;
gint i;
gdouble feel_good;
g_return_if_fail (GIMP_IS_BEZIER_STROKE (stroke));
segment_start = g_list_find (stroke->anchors, predec);
g_return_if_fail (segment_start != NULL);
list = segment_start;
for (i=0; i <= 3; i++)
{
beziercoords[i] = ((GimpAnchor *) list->data)->position;
list = g_list_next (list);
if (!list)
list = stroke->anchors;
}
if (position <= 0.5)
feel_good = (pow(2 * position, 3)) / 2;
else
feel_good = (1 - pow((1-position)*2, 3)) / 2 + 0.5;
gimp_bezier_coords_mix (1.0, &(beziercoords[1]),
(1-feel_good)/(3*position*(1-position)*(1-position)),
deltacoord,
&(beziercoords[1]));
gimp_bezier_coords_mix (1.0, &(beziercoords[2]),
feel_good/(3*position*position*(1-position)),
deltacoord,
&(beziercoords[2]));
list = segment_start;
list = g_list_next (list);
if (!list)
list = stroke->anchors;
for (i=1; i <= 2; i++)
{
((GimpAnchor *) list->data)->position = beziercoords[i];
list = g_list_next (list);
if (!list)
list = stroke->anchors;
}
}
static void
gimp_bezier_stroke_point_move_absolute (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *coord,
GimpAnchorFeatureType feature)
{
GimpCoords deltacoord;
GimpCoords tmp1, tmp2, abs_pos;
GimpCoords beziercoords[4];
GList *segment_start, *list;
gint i;
g_return_if_fail (GIMP_IS_BEZIER_STROKE (stroke));
segment_start = g_list_find (stroke->anchors, predec);
g_return_if_fail (segment_start != NULL);
list = segment_start;
for (i=0; i <= 3; i++)
{
beziercoords[i] = ((GimpAnchor *) list->data)->position;
list = g_list_next (list);
if (!list)
list = stroke->anchors;
}
gimp_bezier_coords_mix ((1-position)*(1-position)*(1-position), &(beziercoords[0]),
3*(1-position)*(1-position)*position, &(beziercoords[1]),
&tmp1);
gimp_bezier_coords_mix (3*(1-position)*position*position, &(beziercoords[2]),
position*position*position, &(beziercoords[3]),
&tmp2);
gimp_bezier_coords_add (&tmp1, &tmp2, &abs_pos);
gimp_bezier_coords_difference (coord, &abs_pos, &deltacoord);
gimp_bezier_stroke_point_move_relative (stroke, predec, position,
&deltacoord, feature);
}
static gdouble static gdouble
gimp_bezier_stroke_nearest_point_get (const GimpStroke *stroke, gimp_bezier_stroke_nearest_point_get (const GimpStroke *stroke,
const GimpCoords *coord, const GimpCoords *coord,
......
...@@ -41,6 +41,12 @@ static void gimp_stroke_finalize (GObject *object); ...@@ -41,6 +41,12 @@ static void gimp_stroke_finalize (GObject *object);
static gsize gimp_stroke_get_memsize (GimpObject *object, static gsize gimp_stroke_get_memsize (GimpObject *object,
gsize *gui_size); gsize *gui_size);
gdouble gimp_stroke_real_nearest_point_get (const GimpStroke *stroke,
const GimpCoords *coord,
const gdouble precision,
GimpCoords *ret_point,
GimpAnchor **ret_segment_start,
gdouble *ret_pos);
static GimpAnchor * gimp_stroke_real_anchor_get (const GimpStroke *stroke, static GimpAnchor * gimp_stroke_real_anchor_get (const GimpStroke *stroke,
const GimpCoords *coord); const GimpCoords *coord);
static GimpAnchor * gimp_stroke_real_anchor_get_next (const GimpStroke *stroke, static GimpAnchor * gimp_stroke_real_anchor_get_next (const GimpStroke *stroke,
...@@ -61,6 +67,23 @@ static void gimp_stroke_real_anchor_convert (GimpStroke *stroke, ...@@ -61,6 +67,23 @@ static void gimp_stroke_real_anchor_convert (GimpStroke *stroke,
GimpAnchorFeatureType feature); GimpAnchorFeatureType feature);
static void gimp_stroke_real_anchor_delete (GimpStroke *stroke, static void gimp_stroke_real_anchor_delete (GimpStroke *stroke,
GimpAnchor *anchor); GimpAnchor *anchor);
static gboolean gimp_stroke_real_point_is_movable
(GimpStroke *stroke,
GimpAnchor *predec,
gdouble position);
static void gimp_stroke_real_point_move_relative
(GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *deltacoord,
GimpAnchorFeatureType feature);
static void gimp_stroke_real_point_move_absolute
(GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *coord,
GimpAnchorFeatureType feature);
static GimpStroke * gimp_stroke_real_open (GimpStroke *stroke, static GimpStroke * gimp_stroke_real_open (GimpStroke *stroke,
GimpAnchor *end_anchor); GimpAnchor *end_anchor);
static gboolean gimp_stroke_real_anchor_is_insertable static gboolean gimp_stroke_real_anchor_is_insertable
...@@ -177,6 +200,11 @@ gimp_stroke_class_init (GimpStrokeClass *klass) ...@@ -177,6 +200,11 @@ gimp_stroke_class_init (GimpStrokeClass *klass)
klass->anchor_convert = gimp_stroke_real_anchor_convert; klass->anchor_convert = gimp_stroke_real_anchor_convert;
klass->anchor_delete = gimp_stroke_real_anchor_delete; klass->anchor_delete = gimp_stroke_real_anchor_delete;
klass->point_is_movable = gimp_stroke_real_point_is_movable;
klass->point_move_relative = gimp_stroke_real_point_move_relative;
klass->point_move_absolute = gimp_stroke_real_point_move_absolute;
klass->nearest_point_get = gimp_stroke_real_nearest_point_get;
klass->open = gimp_stroke_real_open; klass->open = gimp_stroke_real_open;
klass->anchor_is_insertable = gimp_stroke_real_anchor_is_insertable; klass->anchor_is_insertable = gimp_stroke_real_anchor_is_insertable;
klass->anchor_insert = gimp_stroke_real_anchor_insert; klass->anchor_insert = gimp_stroke_real_anchor_insert;
...@@ -252,12 +280,12 @@ gimp_stroke_anchor_get (const GimpStroke *stroke, ...@@ -252,12 +280,12 @@ gimp_stroke_anchor_get (const GimpStroke *stroke,
gdouble gdouble
gimp_stroke_nearest_point_get (const GimpStroke *stroke, gimp_stroke_nearest_point_get (const GimpStroke *stroke,
const GimpCoords *coord, const GimpCoords *coord,
const gdouble precision, const gdouble precision,
GimpCoords *ret_point, GimpCoords *ret_point,
GimpAnchor **ret_segment_start, GimpAnchor **ret_segment_start,
gdouble *ret_pos) gdouble *ret_pos)
{ {
g_return_val_if_fail (GIMP_IS_STROKE (stroke), FALSE); g_return_val_if_fail (GIMP_IS_STROKE (stroke), FALSE);
g_return_val_if_fail (coord != NULL, FALSE); g_return_val_if_fail (coord != NULL, FALSE);
...@@ -270,6 +298,18 @@ gimp_stroke_nearest_point_get (const GimpStroke *stroke, ...@@ -270,6 +298,18 @@ gimp_stroke_nearest_point_get (const GimpStroke *stroke,
ret_pos); ret_pos);
} }
gdouble
gimp_stroke_real_nearest_point_get (const GimpStroke *stroke,
const GimpCoords *coord,
const gdouble precision,
GimpCoords *ret_point,
GimpAnchor **ret_segment_start,
gdouble *ret_pos)
{
g_printerr ("gimp_stroke_nearest_point_get: default implementation\n");
return -1;
}
static GimpAnchor * static GimpAnchor *
gimp_stroke_real_anchor_get (const GimpStroke *stroke, gimp_stroke_real_anchor_get (const GimpStroke *stroke,
const GimpCoords *coord) const GimpCoords *coord)
...@@ -437,6 +477,78 @@ gimp_stroke_real_anchor_move_absolute (GimpStroke *stroke, ...@@ -437,6 +477,78 @@ gimp_stroke_real_anchor_move_absolute (GimpStroke *stroke,
anchor->position.y = coord->y; anchor->position.y = coord->y;
} }
gboolean
gimp_stroke_point_is_movable (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position)
{
g_return_val_if_fail (GIMP_IS_STROKE (stroke), FALSE);
return GIMP_STROKE_GET_CLASS (stroke)->point_is_movable (stroke, predec,
position);
}
gboolean
gimp_stroke_real_point_is_movable (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position)
{
return FALSE;
}
void
gimp_stroke_point_move_relative (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *deltacoord,
GimpAnchorFeatureType feature)
{
g_return_if_fail (GIMP_IS_STROKE (stroke));
GIMP_STROKE_GET_CLASS (stroke)->point_move_relative (stroke, predec,
position, deltacoord,
feature);
}
void
gimp_stroke_real_point_move_relative (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *deltacoord,
GimpAnchorFeatureType feature)
{
g_printerr ("gimp_stroke_point_move_relative: default implementation\n");
}
void
gimp_stroke_point_move_absolute (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *coord,
GimpAnchorFeatureType feature)
{
g_return_if_fail (GIMP_IS_STROKE (stroke));
GIMP_STROKE_GET_CLASS (stroke)->point_move_absolute (stroke, predec,
position, coord,
feature);
}
void
gimp_stroke_real_point_move_absolute (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *coord,
GimpAnchorFeatureType feature)
{
g_printerr ("gimp_stroke_point_move_absolute: default implementation\n");
}
void void
gimp_stroke_close (GimpStroke *stroke) gimp_stroke_close (GimpStroke *stroke)
{ {
......
...@@ -77,6 +77,20 @@ struct _GimpStrokeClass ...@@ -77,6 +77,20 @@ struct _GimpStrokeClass
GimpAnchorFeatureType feature); GimpAnchorFeatureType feature);
void (* anchor_delete) (GimpStroke *stroke, void (* anchor_delete) (GimpStroke *stroke,
GimpAnchor *anchor); GimpAnchor *anchor);
gboolean (* point_is_movable) (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position);
void (* point_move_relative) (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *deltacoord,
GimpAnchorFeatureType feature);
void (* point_move_absolute) (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *coord,
GimpAnchorFeatureType feature);
GimpStroke * (* open) (GimpStroke *stroke, GimpStroke * (* open) (GimpStroke *stroke,
GimpAnchor *end_anchor); GimpAnchor *end_anchor);
...@@ -88,6 +102,7 @@ struct _GimpStrokeClass ...@@ -88,6 +102,7 @@ struct _GimpStrokeClass
gdouble position); gdouble position);
gboolean (* is_extendable) (GimpStroke *stroke, gboolean (* is_extendable) (GimpStroke *stroke,
GimpAnchor *neighbor); GimpAnchor *neighbor);
GimpAnchor * (* extend) (GimpStroke *stroke, GimpAnchor * (* extend) (GimpStroke *stroke,
const GimpCoords *coords, const GimpCoords *coords,
GimpAnchor *neighbor, GimpAnchor *neighbor,
...@@ -184,6 +199,20 @@ void gimp_stroke_anchor_move_absolute (GimpStroke *stroke, ...@@ -184,6 +199,20 @@ void gimp_stroke_anchor_move_absolute (GimpStroke *stroke,
const GimpCoords *coord, const GimpCoords *coord,
GimpAnchorFeatureType feature); GimpAnchorFeatureType feature);
gboolean gimp_stroke_point_is_movable (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position);
void gimp_stroke_point_move_relative (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *deltacoord,
GimpAnchorFeatureType feature);
void gimp_stroke_point_move_absolute (GimpStroke *stroke,
GimpAnchor *predec,
gdouble position,
const GimpCoords *coord,
GimpAnchorFeatureType feature);
void gimp_stroke_close (GimpStroke *stroke); void gimp_stroke_close (GimpStroke *stroke);
void gimp_stroke_anchor_convert (GimpStroke *stroke, void gimp_stroke_anchor_convert (GimpStroke *stroke,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment