Work in progress on the new cage tool. This is more a description of the solutions model than a true specification.
note to nitpicks: no, the ‘i’s have not been dotted, but usability is up by a factor of 18.
The main goal of this interaction design is to make the mode switch—of either editing the cage (a polygon) or deforming the underlying image—as natural and unnoticeable as possible.
trouble in paradise
The cage tool works internally with 2 cages, the initial source cage and the destination cage, same number of points: there are just vectors between them. Changing the source cage triggers the same horribly expensive initial calculation as when closing the polygon.
Translation: for users this looks like one cage: there is a starting set-up of this cage and a bunch of changes to deform the pixels (the vectors), which gives the current cage (== destination cage) that matches how the image is deformed.
For users there are 3 reasons to change the 'cage' (which triggers internally a source cage edit and a recalc):
- somethin was inside/outside the cage and it should not be;
- add/delete poly-points, which is the same as adding flexibility or complexity for users;
- get poly-points closer/farther from pixels for more/less control over these pixels.
now let’s look at the pure user needs, i.e. simply the most logical way to accomplish the 3 tasks above at different moments of a cage life-cycle:
|1. inside <-> outside||2. add/delete poly-points||3. closer/farther|
|while building cage||correct by moving one or more existing poly-points; or insert some more poly-points ( see next cell -> ) to create a ‘detour’||insert a poly-point on an existing edge and move it to the right place; ‘just’ delete an unwanted poly-point||move one or more existing poly-points|
|right after closing cage||same as above row|
|one or two deforms after closing the cage||for poly-points that either itself or their nearest-neighbour have been moved-to-deform: see source cage and correct by moving one or more poly-points; for all other points: 'just' correct by moving one or more poly-points||insert a poly-point on an existing edge and move it to the right place; ‘just’ delete an unwanted poly-point||for poly-points that either itself or their nearest-neighbour have been moved-to-deform: see source cage and move one or more poly-points; for all other points: 'just' correct by moving one or more poly-points|
|oodles of deforms after closing the cage||same as above row|
Conclusions from above table:
- making corrections ‘right after closing cage’ (row 2) is a continuation of the building cage stage for users. The UI handling should also be a ‘continuation’ of the building stage, before deforming starts;
- once deforming has started, it is a whole new ball game;
- adding and deleting poly-points (column 2) is best done right there-and-then, no need for users to go back to the source cage view;
- once deforming has started, any poly-point moving in column 1 and 3 is best done in source cage view.
About editing the initial (source) cage or the current (destination) cage: Yes, in both cases actually the source cage is edited, but it is trivial to transfer deltas between the source and destination cages because there is only linear vectors between them. Because both source and destination cages are inputs to a system, there is no need to run through the (inverse) system transform to get from one to another.
It must be avoided to recalculate the source cage too often, it is done when:
- users leave source cage view and there have been changes to the poly-points (move, add, or delete);
- users have added/deleted at least one poly-point in normal (that is destination cage, for source cage see point above) view, from that moment an Update button is shown (preferably on the canvas); once that update button is clicked (users will find out that that is costly), the recalculation starts.
Stay tuned for the fallout of this on the work below…
before the polygon
The only user-noticeable state shall be the polygon creation state. Some guidelines:
- creating the polygon shall be analogous to creating one with the free-poly select tool, including:
- hit backspace to erase the last created poly-point;
- adjustment of the position of any poly-point while creating;
- closing the polygon by hitting return; double-click to create a final poly-point and close; hit the starting poly-point;
- really, really really check out the spec, source and developer (Enselic) of the free-poly tool to get this right.
after the close
After the polygon is closed, user shall be able to edit any poly-point or deform the underlying image (layer) in any give order, by simply doing it.
note: edit handles and edges shown in current experimental and really not working fat-3-pix style: to be solved
The core of the solution is that each poly-point has two handles attached to it:
- the edit handle, same as used for creating the polygon;
- the deform handle:
- looks both in shape and in fill color (only black and white allowed, btw. for max contrast) different than the edit handle;
- the diamond shape (a square, 45° rotated) gives a good shape contrast and move kind of feeling; also only block 1/4 of the edit handle;
- always positioned on the outside of the polygon, its angle being half the angle that the two edges leading up to the poly-point have.
the simple rule
Moving (i.e. click - drag - release) the edit handle shall move the poly point by the same vector, change the cage but not deform the image;
moving the deform handle handle shall move the poly point by the same vector, change the cage and deform the image.
- clicking on either handle of a poly-point selects it;
- click - drag - release on either handle of a poly-point selects it;
- both of the above are cleanly defined event in GIMP (AFAIK);
- when a poly-point is selected, both its handles highlight; there is absolutely no concept of either handle being selected, the poly-point is selected and so are both handles (concurrency principle);
A poly-point becomes deselected when:
- another poly-point is selected;
- a deselect is done by clicking outside the polygon on the canvas.
(see also multi-select, below)
Multi-selection is optional. It all works without it, but better with it.
Multi-selection shall be based on the multi select model of the icon grid view of a file browser. This includes:
- using <shift-click> to add poly-points to the multi-selection;
- using <ctrl-click> to toggle (add or delete) poly-points to the multi-selection;
- rubber-banding from outside the polygon to start a new multi-selection;
- using <shift> with rubber-banding from outside the polygon to add poly-points to the multi-selection;
- using <ctrl> with rubber-banding from outside the polygon to toggle (first poly-point hit determines the mode—add or delete—for all points enclosed in the rubber-band rectangle) poly-points;
Both moving modes (edit and deform) and delete operate on multi-selections.
At this moment I am reserving click-and-dragging the mouse inside the polygon (as would be done for rubber-banding from inside the polygon) for future use.
Starting from the radius of an edit handle, if users click within half this radius from a polygon edge, then:
- a poly-point is added to this edge (the closest from the click in ambiguous cases), closest to where the click was (use projection normal to the edge);
- this poly-point is selected (so in case of a mistake a delete can be made swiftly);
- a click - drag - release creates the point and moves it into the desired position.
The selected poly-point (or multi-selected poly-points) are deleted by hitting the backspace or delete key.
end of a polygon
By pressing <enter> the polygon is removed from the canvas, all deformation calculations made using this polygon are finalised and a new polygon can be created in the cage tool.
By pressing <escape> the polygon is removed from the canvas, all deformation calculations made using this polygon are reverted and a new polygon can be created in the cage tool.
the finer points of undo
During the period that a polygon exists, the following actions are undo-able one by one, back to the moment the polygon closed:
- moving (either mode: edit and deforms), also of multi-selects (all at once);
- add poly-point;
- delete poly-point, also of multi-selects (all at once).