Difference between revisions of "GSoC2009 Node Tool Rewrite"
(→Node actions: add node snapping) |
m (→Node actions) |
||
Line 287: | Line 287: | ||
|- | |- | ||
|Weld nodes | |Weld nodes | ||
| | |When no endnode joins can be made, joining non-end nodes welds them into one with averaged position | ||
|{{no}} | |{{no}} | ||
|{{yes}} | |{{yes}} |
Revision as of 08:11, 14 January 2010
This page tracks the progress of the node tool rewrite project which is a part of the Google Summer of Code 2009. This project is being implemented by Krzysztof Kosiński, and the mentor is Bulia Byak. This page will be kept updated with the current status of the student's code (it may not reflect the code in the trunk).
The current version of the code can be checked out from Launchpad:
bzr checkout lp:~tweenk/inkscape/gsoc-node-tool
Implementation details
Control points (Knots) are represented by a new class called ControlPoint, reusing the SPCtrl canvas item of SPKnot, but with a different set of signals. A set of control points that can edit something is called a Manipulator. For paths, there will be three classes: PathManipulator (edits a single path, but is not standalone), MultiPathManipulator (edits everal paths at once and allows multipath operations on them) and SinglePathManipulator (edits only one path and can be used to edit path parameters of path effects).
A subclass of ControlPoint, SelectableControlPoint, can belong to a ControlPointSelection. Control points selections are a reusable selection metaphor. Each point is bound to a selection that it can be part of or not; there can be multiple simultaneously active selections for different kinds of points. Having separate selections means that the points will be dragged separately. The event context is responsible for handling selection by rubberband, and a separate selector component is provided for this.
ControlPoint virtual methods
Control points have two important virtual methods: - setPosition(), which takes a Geom::Point in desktop coordinates and updates the position without side effects - move(), which updates the position with side effects, like realigning the second handle of a smooth node or recomputing the handles of auto nodes.
ControlPoint signals
Control
- signal_grabbed - start of drag. Emitted when there was a click and a move larger than drag tolerance.
- signal_dragged - emitted when the point is dragged to a new position. The new position parameter is passed by reference and can be changed by handlers before the position is updated. When the signal completes the new position is set using the move() method.
- signal_ungrabbed - end of drag.
- signal_clicked - single click on the control point, sent on release of the mouse button; return true to indicate that the click was handled
- signal_doubleclicked - double click, sent on release; return true to indicate it was handled
All the signals above have an event parameter that allows the handlers to take different actions based on the details of the event that caused the emission of the signal.
Order of emission of drag signals is always as follows:
- signal_grabbed
- signal_dragged
- signal_dragged
- signal_dragged
- ...
- signal_dragged
- signal_ungrabbed
Additional features
Control points automatically enable forced redraws while dragging to ensure smooth updates and handle drag tolerance. There's also a transferGrab() method that allows to drag a different point that the one that was initially clicked for dragging; this is used to implement dragging out handles.
Examples of implementation
- Dragging out handles: the grabbed handler of a node shows the handle and calls its transferGrab() method if Shift is pressed.
- Constrained dragging: a handler for the dragged signal modifies the new position parameter it was passed, based on the information from the event.
- Handle dragging: updating opposite handles in smooth nodes and smooth handles at ends of linear segments is done in an overridden move() method.
Feature Checklist
Selection
Feature | Description | Old tool | New tool |
---|---|---|---|
Object selection | Selecting objects to node-edit (incl. Shift-click, Alt-click); ignores groups | Yes | Yes |
Shape editor | Selecting objects that are not paths shows their manipulators. This is unlikely to get fixed correctly during GSoC, as it requires at least partially rewriting the shape tools, but some short-term hack will be added. | Yes | Yes |
Gradient editors | Control points for gradients are displayed when the preference setting is enabled | Yes | Yes |
Selecting single nodes | Whether selecting single nodes with left-click works correctly. | Yes | Yes |
Select segment | Click on a path segment to select adjacent nodes. Also works with Shift | Yes | Yes |
Selecting multiple nodes | Shift-click to toggle selection of a node | Yes | Yes |
Select all | Ctrl+A selects all nodes in subpaths that have something selected, Ctrl+Alt+A selects all nodes | Yes | Yes |
Deselect | Esc or click outside of selected paths to deselect | Yes | Yes |
Multi-path selection | Selecting nodes in two or more different paths; all per-node actions work on all selected nodes | No | Yes |
Rubberband selector | Selecting nodes by dragging anywhere to draw a selection rectangle | Yes | Yes |
Prev/Next node | Tab to select next node, Shift+Tab to select previous | Yes | Yes |
Invert selection | ! key inverts node selection in selected subpaths, Alt+! in the whole path | Yes | Yes |
Grow / shrink selection | Scrolling the mouse wheel when a selected node is hovered over causes the selection to propagate from this node to adjacent nodes in the path (without Ctrl) or to geometrically closest nodes (with Ctrl) | Yes | Yes |
Preserve selection on undo | An attempt is made to preserve the node selection when undoing / redoing | Yes | Yes |
Transform handles | Whether transform handles can be toggled for sets of nodes (needs sensible behavior when one node is selected). Should have 3 settings: never show handles, show for 2+ nodes (default), always show | No | Yes |
Node transforms
Feature | Description | Old tool | New tool |
---|---|---|---|
Move | Moving selections of nodes | Yes | Yes |
Move with keyboard | arrows, Shift+arrows, Alt+arrows, Shift+Alt+arrows | Yes | Yes |
Scale with mouse | Scaling node sets with the mouse | No | Yes |
Scale with keyboard | Scaling nodes with >, <; Alt scales by one pixel | Yes | Yes |
Scale handles with keyboard | When only one node is selected, > and < scale its handles | Yes | partial |
Rotate with mouse | Rotating node sets with the mouse | No | Yes |
Rotate with keyboard | Rotate nodes with [, ]; Alt rotates by one pixel | Yes | Yes |
Rotate handles with keyboard | When only one node is selected, [, ] rotate its handles | Yes | partial |
Skew with mouse | Skewing node sets with the mouse | No | Yes |
Skew with keyboard | Tentative keybinding: / and \ to skew horizontally (corners move by nudgedistance), Ctrl skews vertically, Shift = x10, Alt = one pixel | No | No |
Flip nodes | v for vertical flip, h for horizontal, mouseovered node is the center | Yes | Yes |
Constrained dragging | Ctrl to restrict movement to axes | Yes | Yes |
Move along handles | Ctrl+Alt to restrict node movement to the handle lines | Yes | Yes |
Sculpting | Alt to move selected nodes depending on their distance from the cursor and tablet pen pressure | Yes | No |
Affect handles | Ability to specify whether handles should be transformed (toggle button) | No | No |
Rotation center snapping | Rotation center snaps to the geometric center of the bounding box, its corners, sides and nodes | No | No |
Node types
Feature | Description | Old tool | New tool |
---|---|---|---|
Read node types | Read and store node type information | Yes | Yes |
Basic (cusp, smooth, symmetric) | The second handle is modified according to the node type | Yes | Yes |
Auto nodes | Handles are recalculated according to neighboring node positions | Yes | Yes |
Smooth nodes at ends of linear segments | When a smooth node appears on the end of a linear segment, its handle should remain colinear with the segment when the node or the handle are dragged | Yes | Yes |
Set node type | Node type can be set and the handles are updated | Yes | Yes |
Restrict end node types | It is not possible to create a nonsensical auto or symmetric end node | No | Yes |
Node actions
Feature | Description | Old tool | New tool |
---|---|---|---|
Add node with mouse | Double-click on a path segment to add node | Yes | Yes |
Insert nodes | Insert a node in the middle of each selected segment (Insert, Shift+I, toolbar) | Yes | Yes |
Delete nodes | Del to remove nodes while trying to preserve shape; hold Control to leave adjacent handles alone | Yes | Yes |
Join nodes | Join two end nodes into one | Yes | Yes |
Weld nodes | When no endnode joins can be made, joining non-end nodes welds them into one with averaged position | No | Yes |
Join multiple nodes | Joining more than two endnodes at once is possible, using a pairwise nearest neighbor algorithm | No | Yes |
Mouseover join | If a node is mouseovered when joining nodes, its position is used as the position for the joined node | Yes | Yes |
Mouseover weld | The mouseovered node in a welded node selection will be used as the position of the joined node | No | Yes |
Multi-path node join | Joining nodes in different paths works correctly | No | Yes |
Break nodes | Break subpaths into pieces at the selected nodes | Yes | Yes |
Align nodes | Alignment actions in Align and Distribute dialog | Yes | Yes |
Snap nodes | Nodes snap according to snap settings when transformed | Yes | Yes |
Cycle node type | Ctrl+click to cycle between node types | Yes | Yes |
Segment actions
Feature | Description | Old tool | New tool |
---|---|---|---|
Curve drag | Dragging a segment changes its appearance | Yes | Yes |
Join segment | Connect two end nodes with a segment | Yes | Yes |
Weld segments | Joining segments when non-end nodes are selected replaces each contiguous segment selection with one segment | No | No |
Multi-path segment join | Join between subpaths in different paths | No | Yes |
Delete segment | Remove a path segment between two nodes | Yes | Yes |
Improved segment deletion | Arbitrary number of segments can be deleted at once; selected segments at the start and end of subpath are trimmed | No | Yes |
Display
Feature | Description | Old tool | New tool |
---|---|---|---|
Flash path outline | Outline promptly flashes when hovering over paths when no path is selected | Yes | Yes |
Selected path outline | Outline of the selected path is drawn when the "show outline" toggle button is on | Yes | Yes |
Curve drag cursor | The cursor changes when hovering over a curve to indicate that it will be dragged | Yes | Yes |
Smooth redraws | Dragging doesn't cause excessive tearing or other artifacts | Yes | Yes |
Status bar tips | Display the number of selected nodes and information on how to use the controls in the status bar | Yes | Yes |
Smart tips | The displayed status bar tip depends on the modifier state and the state of the mouseovered control point; tips are short, so that most are visible in full on a 1024x768 screen | No | Yes |
Path direction | Small arrows on the outline optionally visualize the direction of the path | No | Yes |
Color-coded outlines | Red outlines for normal paths, green for clipping paths, blue for masks - configurable in prefs | hardcoded colors | yes, but no pref UI |
Handles
Feature | Description | Old tool | New tool |
---|---|---|---|
Handle display | Handles are displayed on the selected nodes and their neighbors | Yes | Yes |
Flip handles | v for vertical flip, h for horizontal | Yes | Yes |
Lock handle length | Alt to move handles while preserving length | Yes | Yes |
Drag out handles | Shift + mouse drag to drag out a handle that coincides with a node | Yes | Yes |
Retract handles by dragging | Drag a handle near its node to hide it; Retracting both handles of a Bezier segment makes it a line | No | Yes |
Retract handles with click | Ctrl+click retracts a handle | Yes | Yes |
Restrict movement | Ctrl to restrict handle movements to ~15 degree angle increments from axis-aligned and the original angle | Yes | Yes |
Snap handles | Handles can be snapped to other snap targets | No | No |
Copy / paste handles | Ability to copy and paste handles between nodes | No | No |
Extras
Feature | Description | Old tool | New tool |
---|---|---|---|
Drag tolerance | Drags shorter than a configurable distance are regarded as clicks | Yes | Yes |
Clip / mask editing | Buttons to edit the clipping and masking paths in place | Yes | Yes |
Simultaneous clip / mask editing | Buttons to edit masks and clipping paths are toggle buttons that show or hide the editing controls for them | No | Yes |
Resilient simultaneous editing | Not possible to e.g. join between mask and base path | No | No |
Multi mask edit | Can edit the clipping and masking paths of several items at once | No | Yes |
Grouped masks | Can handle groups used as clipping paths or masks | No | Yes |
Mask transform | Clipping path / mask outline is drawn in the correct place when the object that has it is transformed after applying the mask | No | Yes |
Mask transform undo | Undoing a move of the masked object when node-editing the mask moves the outline to the correct place | No | No |
Support for objectBoundingBox | Clipping paths and masks with units set to "objectBoundingBox" instead of the default "userSpaceOnUse" are handled correctly | No | No |
Reverse subpaths | Shift+R and the menu reverse action only reverse the subpaths that have at least one selected node | No | Yes |
Drag stroke width | Ctrl-dragging on a curve causes the stroke width to be adjusted | No | No |
Path effect param editing | Button to to edit the next path parameter of the selected live path effect | Yes | Yes |
Prefs page | Node tool preferences page with various settings | Yes | Yes |
Bugfixes / feature requests
Bugfix | Description | Old tool | New tool |
---|---|---|---|
Bug #290870 | Regression: Curve dragging via Node Tool sometimes won't work | No | No |
Bug #379817 | Node tool behaviour different and wrong in 0.47 compared to 0.46 | No | Yes |
Bug #380726 | display a ghost path | No | No |
Inkscape key guide for the node tool - more detailed description of the old node tool's features and keybindings