If an control handle gets converted to an edge simply move it to its next
2003-06-25 Simon Budig <simon@gimp.org> * app/vectors/gimpbezierstroke.c: If an control handle gets converted to an edge simply move it to its next anchor. * app/tools/gimpvectortool.c: Improved interactive handling of vectors. Still work in progress, esp. I am not sure about the assignment of the modifier keys. Right now it is: Drag (Anchor/Handle): Regular Movement Shift-Click (Anchor): select multiple anchors (does not work yet) Shift-Drag: (Handle): move opposite handle symmetrically Ctrl-Drag (Anchor): Drag out control point S-C-Click: (Anchor/Handle): Convert to Edge
This commit is contained in:
parent
7a6a908ad2
commit
ca50643729
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
2003-06-25 Simon Budig <simon@gimp.org>
|
||||||
|
|
||||||
|
* app/vectors/gimpbezierstroke.c: If an control handle gets
|
||||||
|
converted to an edge simply move it to its next anchor.
|
||||||
|
|
||||||
|
* app/tools/gimpvectortool.c: Improved interactive handling
|
||||||
|
of vectors. Still work in progress, esp. I am not sure about
|
||||||
|
the assignment of the modifier keys. Right now it is:
|
||||||
|
|
||||||
|
Drag (Anchor/Handle): Regular Movement
|
||||||
|
Shift-Click (Anchor): select multiple anchors (does not work yet)
|
||||||
|
Shift-Drag: (Handle): move opposite handle symmetrically
|
||||||
|
Ctrl-Drag (Anchor): Drag out control point
|
||||||
|
S-C-Click: (Anchor/Handle): Convert to Edge
|
||||||
|
|
||||||
2003-06-24 Sven Neumann <sven@gimp.org>
|
2003-06-24 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
* app/config/gimpconfig.[ch]: added new function
|
* app/config/gimpconfig.[ch]: added new function
|
||||||
|
@ -82,10 +82,12 @@ static void gimp_vector_tool_cursor_update (GimpTool *tool,
|
|||||||
GdkModifierType state,
|
GdkModifierType state,
|
||||||
GimpDisplay *gdisp);
|
GimpDisplay *gdisp);
|
||||||
|
|
||||||
static gboolean gimp_vector_tool_on_handle (GimpTool *tool,
|
static gboolean gimp_vector_tool_on_handle (GimpTool *tool,
|
||||||
GimpCoords *coords,
|
GimpCoords *coords,
|
||||||
GimpAnchorType preferred,
|
GimpAnchorType preferred,
|
||||||
GimpAnchor **ret_anchor);
|
GimpDisplay *gdisp,
|
||||||
|
GimpAnchor **ret_anchor,
|
||||||
|
GimpStroke **ret_stroke);
|
||||||
|
|
||||||
static void gimp_vector_tool_draw (GimpDrawTool *draw_tool);
|
static void gimp_vector_tool_draw (GimpDrawTool *draw_tool);
|
||||||
|
|
||||||
@ -228,16 +230,31 @@ gimp_vector_tool_button_press (GimpTool *tool,
|
|||||||
GimpVectorOptions *options;
|
GimpVectorOptions *options;
|
||||||
GimpAnchor *anchor = NULL;
|
GimpAnchor *anchor = NULL;
|
||||||
GimpStroke *stroke = NULL;
|
GimpStroke *stroke = NULL;
|
||||||
|
GimpAnchorType preferred = GIMP_ANCHOR_ANCHOR;
|
||||||
|
|
||||||
vector_tool = GIMP_VECTOR_TOOL (tool);
|
vector_tool = GIMP_VECTOR_TOOL (tool);
|
||||||
options = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
|
options = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
|
||||||
|
|
||||||
|
/* when pressing mouse down
|
||||||
|
*
|
||||||
|
* Anchor: (NONE) -> Regular Movement
|
||||||
|
* (SHFT) -> multiple selection
|
||||||
|
* (CTRL) -> Drag out control point
|
||||||
|
* (CTRL+SHFT) -> Convert to corner
|
||||||
|
*
|
||||||
|
* Handle: (NONE) -> Regular Movement
|
||||||
|
* (SHFT) -> (Handle) Move opposite handle symmetrically
|
||||||
|
* (CTRL+SHFT) -> move handle to its anchor
|
||||||
|
*/
|
||||||
|
|
||||||
/* if we are changing displays, pop the statusbar of the old one */
|
/* if we are changing displays, pop the statusbar of the old one */
|
||||||
if (gimp_tool_control_is_active (tool->control) && gdisp != tool->gdisp)
|
if (gimp_tool_control_is_active (tool->control) && gdisp != tool->gdisp)
|
||||||
{
|
{
|
||||||
/* gimp_tool_pop_status (tool); */
|
/* gimp_tool_pop_status (tool); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
|
||||||
|
|
||||||
if (vector_tool->vectors &&
|
if (vector_tool->vectors &&
|
||||||
gdisp->gimage != GIMP_ITEM (vector_tool->vectors)->gimage)
|
gdisp->gimage != GIMP_ITEM (vector_tool->vectors)->gimage)
|
||||||
gimp_vector_tool_clear_vectors (vector_tool);
|
gimp_vector_tool_clear_vectors (vector_tool);
|
||||||
@ -245,46 +262,45 @@ gimp_vector_tool_button_press (GimpTool *tool,
|
|||||||
if (vector_tool->vectors &&
|
if (vector_tool->vectors &&
|
||||||
gimp_tool_control_is_active (tool->control) && gdisp == tool->gdisp)
|
gimp_tool_control_is_active (tool->control) && gdisp == tool->gdisp)
|
||||||
{
|
{
|
||||||
/* if the cursor is in one of the handles,
|
if (state & GDK_CONTROL_MASK && !(state & GDK_SHIFT_MASK))
|
||||||
* the new function will be moving or adding a new point or guide
|
preferred = GIMP_ANCHOR_CONTROL;
|
||||||
*/
|
|
||||||
|
|
||||||
anchor = gimp_vectors_anchor_get (vector_tool->vectors, coords, &stroke);
|
if (gimp_vector_tool_on_handle (tool, coords,
|
||||||
|
preferred, gdisp, &anchor, &stroke))
|
||||||
if (anchor && gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), gdisp,
|
|
||||||
coords->x,
|
|
||||||
coords->y,
|
|
||||||
GIMP_HANDLE_CIRCLE,
|
|
||||||
anchor->position.x,
|
|
||||||
anchor->position.y,
|
|
||||||
TARGET,
|
|
||||||
TARGET,
|
|
||||||
GTK_ANCHOR_CENTER,
|
|
||||||
FALSE))
|
|
||||||
{
|
{
|
||||||
gimp_draw_tool_pause (GIMP_DRAW_TOOL (vector_tool));
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (vector_tool));
|
||||||
|
|
||||||
if (state & GDK_MOD1_MASK)
|
|
||||||
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
|
|
||||||
else
|
|
||||||
vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
|
|
||||||
|
|
||||||
if (anchor->type == GIMP_ANCHOR_ANCHOR)
|
if (anchor->type == GIMP_ANCHOR_ANCHOR)
|
||||||
{
|
{
|
||||||
gimp_stroke_anchor_select (stroke, anchor, TRUE);
|
if (state & GDK_SHIFT_MASK && !(state & GDK_CONTROL_MASK))
|
||||||
|
gimp_stroke_anchor_select (stroke, anchor, FALSE);
|
||||||
|
else
|
||||||
|
gimp_stroke_anchor_select (stroke, anchor, TRUE);
|
||||||
|
|
||||||
/* MOD1 pressed? Convert to Edge */
|
/* Maybe convert to edge */
|
||||||
if (state & GDK_MOD1_MASK)
|
if (state & GDK_CONTROL_MASK && state & GDK_SHIFT_MASK)
|
||||||
{
|
{
|
||||||
gimp_stroke_anchor_convert (stroke, anchor,
|
gimp_stroke_anchor_convert (stroke, anchor,
|
||||||
GIMP_ANCHOR_FEATURE_EDGE);
|
GIMP_ANCHOR_FEATURE_EDGE);
|
||||||
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
|
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* doublecheck if there are control handles at this anchor */
|
/* if the selected anchor changed, the visible control
|
||||||
anchor = gimp_vectors_anchor_get (vector_tool->vectors,
|
* points might have changed too */
|
||||||
coords, &stroke);
|
if (state & GDK_CONTROL_MASK)
|
||||||
|
gimp_vector_tool_on_handle (tool, coords, GIMP_ANCHOR_CONTROL,
|
||||||
|
gdisp, &anchor, &stroke);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (state & GDK_SHIFT_MASK && state & GDK_CONTROL_MASK)
|
||||||
|
{
|
||||||
|
gimp_stroke_anchor_convert (stroke, anchor,
|
||||||
|
GIMP_ANCHOR_FEATURE_EDGE);
|
||||||
|
vector_tool->cur_stroke = NULL;
|
||||||
|
vector_tool->cur_anchor = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
vector_tool->function = VECTORS_MOVING;
|
vector_tool->function = VECTORS_MOVING;
|
||||||
vector_tool->cur_stroke = stroke;
|
vector_tool->cur_stroke = stroke;
|
||||||
@ -361,7 +377,9 @@ gimp_vector_tool_button_press (GimpTool *tool,
|
|||||||
gimp_draw_tool_stop (GIMP_DRAW_TOOL (vector_tool));
|
gimp_draw_tool_stop (GIMP_DRAW_TOOL (vector_tool));
|
||||||
}
|
}
|
||||||
|
|
||||||
anchor = gimp_bezier_stroke_extend (GIMP_BEZIER_STROKE (vector_tool->cur_stroke), coords, vector_tool->cur_anchor, EXTEND_EDITABLE);
|
anchor = gimp_bezier_stroke_extend (GIMP_BEZIER_STROKE (vector_tool->cur_stroke),
|
||||||
|
coords, vector_tool->cur_anchor,
|
||||||
|
EXTEND_EDITABLE);
|
||||||
if (anchor)
|
if (anchor)
|
||||||
vector_tool->cur_anchor = anchor;
|
vector_tool->cur_anchor = anchor;
|
||||||
|
|
||||||
@ -412,11 +430,24 @@ gimp_vector_tool_motion (GimpTool *tool,
|
|||||||
GimpVectorOptions *options;
|
GimpVectorOptions *options;
|
||||||
GimpAnchor *anchor;
|
GimpAnchor *anchor;
|
||||||
|
|
||||||
|
/* While moving:
|
||||||
|
* (SHFT) -> restrict movement
|
||||||
|
*/
|
||||||
|
|
||||||
vector_tool = GIMP_VECTOR_TOOL (tool);
|
vector_tool = GIMP_VECTOR_TOOL (tool);
|
||||||
options = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
|
options = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
|
||||||
|
|
||||||
gimp_vectors_freeze (vector_tool->vectors);
|
gimp_vectors_freeze (vector_tool->vectors);
|
||||||
|
|
||||||
|
if (state & GDK_SHIFT_MASK)
|
||||||
|
{
|
||||||
|
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (vector_tool->function)
|
switch (vector_tool->function)
|
||||||
{
|
{
|
||||||
case VECTORS_MOVING:
|
case VECTORS_MOVING:
|
||||||
@ -438,10 +469,13 @@ static gboolean
|
|||||||
gimp_vector_tool_on_handle (GimpTool *tool,
|
gimp_vector_tool_on_handle (GimpTool *tool,
|
||||||
GimpCoords *coords,
|
GimpCoords *coords,
|
||||||
GimpAnchorType preferred,
|
GimpAnchorType preferred,
|
||||||
GimpAnchor **ret_anchor)
|
GimpDisplay *gdisp,
|
||||||
|
GimpAnchor **ret_anchor,
|
||||||
|
GimpStroke **ret_stroke)
|
||||||
{
|
{
|
||||||
GimpVectorTool *vector_tool;
|
GimpVectorTool *vector_tool;
|
||||||
GimpStroke *stroke = NULL;
|
GimpStroke *stroke = NULL;
|
||||||
|
GimpStroke *pref_stroke = NULL;
|
||||||
GimpAnchor *anchor = NULL;
|
GimpAnchor *anchor = NULL;
|
||||||
GimpAnchor *pref_anchor = NULL;
|
GimpAnchor *pref_anchor = NULL;
|
||||||
GList *list, *anchor_list = NULL;
|
GList *list, *anchor_list = NULL;
|
||||||
@ -453,49 +487,90 @@ gimp_vector_tool_on_handle (GimpTool *tool,
|
|||||||
{
|
{
|
||||||
if (ret_anchor)
|
if (ret_anchor)
|
||||||
*ret_anchor = NULL;
|
*ret_anchor = NULL;
|
||||||
|
|
||||||
|
if (ret_stroke)
|
||||||
|
*ret_stroke = NULL;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((stroke = gimp_vectors_stroke_get_next (vector_tool->vectors, stroke))
|
while ((stroke = gimp_vectors_stroke_get_next (vector_tool->vectors, stroke))
|
||||||
!= NULL)
|
!= NULL)
|
||||||
{
|
{
|
||||||
list = gimp_stroke_get_draw_anchors (stroke);
|
anchor_list = gimp_stroke_get_draw_anchors (stroke);
|
||||||
anchor_list = g_list_concat (anchor_list, list);
|
|
||||||
|
|
||||||
list = gimp_stroke_get_draw_controls (stroke);
|
list = gimp_stroke_get_draw_controls (stroke);
|
||||||
anchor_list = g_list_concat (anchor_list, list);
|
anchor_list = g_list_concat (anchor_list, list);
|
||||||
|
|
||||||
|
while (anchor_list)
|
||||||
|
{
|
||||||
|
dx = coords->x - ((GimpAnchor *) anchor_list->data)->position.x;
|
||||||
|
dy = coords->y - ((GimpAnchor *) anchor_list->data)->position.y;
|
||||||
|
|
||||||
|
if (mindist < 0 || mindist >= dx * dx + dy * dy)
|
||||||
|
{
|
||||||
|
mindist = dx * dx + dy * dy;
|
||||||
|
anchor = (GimpAnchor *) anchor_list->data;
|
||||||
|
if (ret_stroke)
|
||||||
|
*ret_stroke = stroke;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pref_mindist < 0 || pref_mindist >= dx * dx + dy * dy) &&
|
||||||
|
((GimpAnchor *) anchor_list->data)->type == preferred)
|
||||||
|
{
|
||||||
|
pref_mindist = dx * dx + dy * dy;
|
||||||
|
pref_anchor = (GimpAnchor *) anchor_list->data;
|
||||||
|
pref_stroke = stroke;
|
||||||
|
}
|
||||||
|
|
||||||
|
anchor_list = anchor_list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (anchor_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (anchor_list)
|
if (pref_anchor && gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), gdisp,
|
||||||
|
coords->x,
|
||||||
|
coords->y,
|
||||||
|
GIMP_HANDLE_CIRCLE,
|
||||||
|
pref_anchor->position.x,
|
||||||
|
pref_anchor->position.y,
|
||||||
|
TARGET,
|
||||||
|
TARGET,
|
||||||
|
GTK_ANCHOR_CENTER,
|
||||||
|
FALSE))
|
||||||
{
|
{
|
||||||
dx = coords->x - ((GimpAnchor *) anchor_list->data)->position.x;
|
if (ret_anchor)
|
||||||
dy = coords->y - ((GimpAnchor *) anchor_list->data)->position.y;
|
*ret_anchor = pref_anchor;
|
||||||
|
if (ret_stroke)
|
||||||
if (mindist < 0 || mindist > dx * dx + dy * dy)
|
*ret_stroke = pref_stroke;
|
||||||
{
|
return TRUE;
|
||||||
mindist = dx * dx + dy * dy;
|
}
|
||||||
anchor = (GimpAnchor *) anchor_list->data;
|
else if (anchor && gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), gdisp,
|
||||||
}
|
coords->x,
|
||||||
|
coords->y,
|
||||||
if ((pref_mindist < 0 || pref_mindist > dx * dx + dy * dy) &&
|
GIMP_HANDLE_CIRCLE,
|
||||||
((GimpAnchor *) anchor_list->data)->type == preferred)
|
anchor->position.x,
|
||||||
{
|
anchor->position.y,
|
||||||
pref_mindist = dx * dx + dy * dy;
|
TARGET,
|
||||||
pref_anchor = (GimpAnchor *) anchor_list->data;
|
TARGET,
|
||||||
}
|
GTK_ANCHOR_CENTER,
|
||||||
|
FALSE))
|
||||||
anchor_list = anchor_list->next;
|
{
|
||||||
|
if (ret_anchor)
|
||||||
|
*ret_anchor = anchor;
|
||||||
|
|
||||||
|
/* *ret_stroke already set correctly. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ret_anchor)
|
||||||
|
*ret_anchor = NULL;
|
||||||
|
if (ret_stroke)
|
||||||
|
*ret_stroke = NULL;
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free (anchor_list);
|
|
||||||
|
|
||||||
if (pref_anchor)
|
|
||||||
anchor = pref_anchor;
|
|
||||||
|
|
||||||
if (ret_anchor)
|
|
||||||
*ret_anchor = anchor;
|
|
||||||
|
|
||||||
return (anchor != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -478,13 +478,26 @@ gimp_bezier_stroke_anchor_convert (GimpStroke *stroke,
|
|||||||
switch (feature)
|
switch (feature)
|
||||||
{
|
{
|
||||||
case GIMP_ANCHOR_FEATURE_EDGE:
|
case GIMP_ANCHOR_FEATURE_EDGE:
|
||||||
if (g_list_previous (anchor_list))
|
if (anchor->type == GIMP_ANCHOR_ANCHOR)
|
||||||
((GimpAnchor *) g_list_previous (anchor_list)->data)->position =
|
{
|
||||||
anchor->position;
|
if (g_list_previous (anchor_list))
|
||||||
|
((GimpAnchor *) g_list_previous (anchor_list)->data)->position =
|
||||||
|
anchor->position;
|
||||||
|
|
||||||
|
if (g_list_next (anchor_list))
|
||||||
|
((GimpAnchor *) g_list_next (anchor_list)->data)->position =
|
||||||
|
anchor->position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (g_list_previous (anchor_list) &&
|
||||||
|
((GimpAnchor *) g_list_previous (anchor_list)->data)->type == GIMP_ANCHOR_ANCHOR)
|
||||||
|
anchor->position = ((GimpAnchor *) g_list_previous (anchor_list)->data)->position;
|
||||||
|
if (g_list_next (anchor_list) &&
|
||||||
|
((GimpAnchor *) g_list_next (anchor_list)->data)->type == GIMP_ANCHOR_ANCHOR)
|
||||||
|
anchor->position = ((GimpAnchor *) g_list_next (anchor_list)->data)->position;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_list_next (anchor_list))
|
|
||||||
((GimpAnchor *) g_list_next (anchor_list)->data)->position =
|
|
||||||
anchor->position;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user