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>
|
||||
|
||||
* app/config/gimpconfig.[ch]: added new function
|
||||
|
@ -82,10 +82,12 @@ static void gimp_vector_tool_cursor_update (GimpTool *tool,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp);
|
||||
|
||||
static gboolean gimp_vector_tool_on_handle (GimpTool *tool,
|
||||
static gboolean gimp_vector_tool_on_handle (GimpTool *tool,
|
||||
GimpCoords *coords,
|
||||
GimpAnchorType preferred,
|
||||
GimpAnchor **ret_anchor);
|
||||
GimpDisplay *gdisp,
|
||||
GimpAnchor **ret_anchor,
|
||||
GimpStroke **ret_stroke);
|
||||
|
||||
static void gimp_vector_tool_draw (GimpDrawTool *draw_tool);
|
||||
|
||||
@ -228,16 +230,31 @@ gimp_vector_tool_button_press (GimpTool *tool,
|
||||
GimpVectorOptions *options;
|
||||
GimpAnchor *anchor = NULL;
|
||||
GimpStroke *stroke = NULL;
|
||||
GimpAnchorType preferred = GIMP_ANCHOR_ANCHOR;
|
||||
|
||||
vector_tool = GIMP_VECTOR_TOOL (tool);
|
||||
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 (gimp_tool_control_is_active (tool->control) && gdisp != tool->gdisp)
|
||||
{
|
||||
/* gimp_tool_pop_status (tool); */
|
||||
}
|
||||
|
||||
vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
|
||||
|
||||
if (vector_tool->vectors &&
|
||||
gdisp->gimage != GIMP_ITEM (vector_tool->vectors)->gimage)
|
||||
gimp_vector_tool_clear_vectors (vector_tool);
|
||||
@ -245,46 +262,45 @@ gimp_vector_tool_button_press (GimpTool *tool,
|
||||
if (vector_tool->vectors &&
|
||||
gimp_tool_control_is_active (tool->control) && gdisp == tool->gdisp)
|
||||
{
|
||||
/* if the cursor is in one of the handles,
|
||||
* the new function will be moving or adding a new point or guide
|
||||
*/
|
||||
if (state & GDK_CONTROL_MASK && !(state & GDK_SHIFT_MASK))
|
||||
preferred = GIMP_ANCHOR_CONTROL;
|
||||
|
||||
anchor = gimp_vectors_anchor_get (vector_tool->vectors, coords, &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))
|
||||
if (gimp_vector_tool_on_handle (tool, coords,
|
||||
preferred, gdisp, &anchor, &stroke))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
if (state & GDK_MOD1_MASK)
|
||||
/* Maybe convert to edge */
|
||||
if (state & GDK_CONTROL_MASK && state & GDK_SHIFT_MASK)
|
||||
{
|
||||
gimp_stroke_anchor_convert (stroke, anchor,
|
||||
GIMP_ANCHOR_FEATURE_EDGE);
|
||||
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
|
||||
}
|
||||
}
|
||||
|
||||
/* doublecheck if there are control handles at this anchor */
|
||||
anchor = gimp_vectors_anchor_get (vector_tool->vectors,
|
||||
coords, &stroke);
|
||||
/* if the selected anchor changed, the visible control
|
||||
* points might have changed too */
|
||||
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->cur_stroke = stroke;
|
||||
@ -361,7 +377,9 @@ gimp_vector_tool_button_press (GimpTool *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)
|
||||
vector_tool->cur_anchor = anchor;
|
||||
|
||||
@ -412,11 +430,24 @@ gimp_vector_tool_motion (GimpTool *tool,
|
||||
GimpVectorOptions *options;
|
||||
GimpAnchor *anchor;
|
||||
|
||||
/* While moving:
|
||||
* (SHFT) -> restrict movement
|
||||
*/
|
||||
|
||||
vector_tool = GIMP_VECTOR_TOOL (tool);
|
||||
options = GIMP_VECTOR_OPTIONS (tool->tool_info->tool_options);
|
||||
|
||||
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)
|
||||
{
|
||||
case VECTORS_MOVING:
|
||||
@ -438,10 +469,13 @@ static gboolean
|
||||
gimp_vector_tool_on_handle (GimpTool *tool,
|
||||
GimpCoords *coords,
|
||||
GimpAnchorType preferred,
|
||||
GimpAnchor **ret_anchor)
|
||||
GimpDisplay *gdisp,
|
||||
GimpAnchor **ret_anchor,
|
||||
GimpStroke **ret_stroke)
|
||||
{
|
||||
GimpVectorTool *vector_tool;
|
||||
GimpStroke *stroke = NULL;
|
||||
GimpStroke *pref_stroke = NULL;
|
||||
GimpAnchor *anchor = NULL;
|
||||
GimpAnchor *pref_anchor = NULL;
|
||||
GList *list, *anchor_list = NULL;
|
||||
@ -453,49 +487,90 @@ gimp_vector_tool_on_handle (GimpTool *tool,
|
||||
{
|
||||
if (ret_anchor)
|
||||
*ret_anchor = NULL;
|
||||
|
||||
if (ret_stroke)
|
||||
*ret_stroke = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while ((stroke = gimp_vectors_stroke_get_next (vector_tool->vectors, stroke))
|
||||
!= NULL)
|
||||
{
|
||||
list = gimp_stroke_get_draw_anchors (stroke);
|
||||
anchor_list = g_list_concat (anchor_list, list);
|
||||
anchor_list = gimp_stroke_get_draw_anchors (stroke);
|
||||
|
||||
list = gimp_stroke_get_draw_controls (stroke);
|
||||
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;
|
||||
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 ((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;
|
||||
}
|
||||
|
||||
anchor_list = anchor_list->next;
|
||||
if (ret_anchor)
|
||||
*ret_anchor = pref_anchor;
|
||||
if (ret_stroke)
|
||||
*ret_stroke = pref_stroke;
|
||||
return TRUE;
|
||||
}
|
||||
else 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))
|
||||
{
|
||||
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
|
||||
|
@ -478,13 +478,26 @@ gimp_bezier_stroke_anchor_convert (GimpStroke *stroke,
|
||||
switch (feature)
|
||||
{
|
||||
case GIMP_ANCHOR_FEATURE_EDGE:
|
||||
if (g_list_previous (anchor_list))
|
||||
((GimpAnchor *) g_list_previous (anchor_list)->data)->position =
|
||||
anchor->position;
|
||||
if (anchor->type == GIMP_ANCHOR_ANCHOR)
|
||||
{
|
||||
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;
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user