On Friday 14 September 2007 13:18:16 Adrian Custer wrote:
Hey Gabriel,
Could you update us with a brief blurb about how you decided to  
tackle
this?
sure! my attempt at the bottom of the message.
Jody suggested inkscape as one source of inspiration and I would
highly encourage this. Inkscape has one of the most intuitive  
interfaces
and has been the free software program that has gotten the most  
traction
with friends to whom I have suggested it. If you don't know it,  
one of
the things it does is have 2 modes of interaction with each object- a
whole object mode and a 'vertex' mode. That duality seems really
important for the editing tools going forward.
cool. I've installed and tried it.
Up till now, it doesn't seem to be that far from what it is (or  
could be)
possible with udig. The 2 modes of interactions with objects seem  
cool as
they're bassically  a way to modify the whole object or its parts  
(curves,
vertices, etc). Right now when you need to modify a geometry in  
uDig you have
only the vertex part of it, but I guess it shouldn't be that  
complicated to
add a object mode so you can have handles to operate on the whole  
object.
Regardles of that lack and the plenty of extra sub-modes Inkscape  
(and most
tools like that?) have and uDig doesn't, it doesn't seem impossible to
achieve that and I think we could be a big step closer with the  
extensions
we're developing.
Moreover, I found Inkscape uses the same approach I was thinking of  
as to have
a single tool for a single pourpose and when selected, enabling a tool
specific toolbar with the applicable modes. A difference could be  
most of
them in Inkscape are tailored to the edition of a shape when I'm  
more focused
in the possible modes while in the creation process of the shape.  
(i.e. the
process in Inkscape seems to be to create a simlpe shape and then  
apply a
number of modification to get to the desired one, while I'm trying  
to create
the desired one with the assistance of the tool's "modes").
Anyhow, I would love to
have an update on your thinking,
Ok, here it is what we got so far.
First, I've identified to main kinds of modes: those that adds  
behaviours on
top the the current tool default ones, and thos that need finer  
control over
the tool (i.e. taking full control of interactions while active).
My requirement was to create parallels, but I didn't wanted to  
create yet
another tool for it, as it would be nicer being drawing a  
linestring and at
any point decide that the next segment to add has to be parallel to  
another
one, whether that one belongs to the currently being edited  
geometry or a
segment from another feature in the same or other layer.
So, we already have something similar: snap behaviours. So I've  
identified the
following *representative* modes to use while creating a linestring  
(or a
polygon outline):
- snap to vertex: adds a behaviour to the default tool ones
- snap to line: adds a behaviour to the default tool ones
- ortho: : no extra behaviour, contributes an edit point Provider  
and changes
feedback (the point Provider restricts the target point to be  
orthogonal
regarding the last edit shape one, and the feedback shows the ortho  
segment
and the ortho axes centered at the mouse location)
- parallel: completelly replaces the current tool behaviours and  
takes control
of interaction and feedback
- arc: same as parallel
Note the benefit of extracting out the snapping as a mode: LineTool  
looses
responsabilities and gets way more simpler, and it is possible to  
easyly
enable/disable snapping with a single click or shortcut with no  
need to go to
the preferences page.
So right now we have a line tool with snap, snap to line, ortho and  
parallel
modes. Each of them adds or takes control of the interactions as  
needed and
sets their own feedback graphics.
Example: the parallel mode allows to select the reference line at  
any moment
using the snap area and the snap behaviour (current layer, all layers,
grid...) settled as prefference.
When the reference line segment is selected, the one being drawn is  
restricted
to the parallel passing through the last added edit shape point,  
and the
feedback action is to draw a pair of orthogonal axes centered at  
the mouse
location where one of them is parallel to the reference segment and  
the other
orthogonal to it.
This way, we tried to leverage the current interaction mechanisms  
found in
udig while adding temporal modifiers to an edit tool.
Now, implementation wise, its being done as follows:
To be able to meet deadlines I've implemented a new LineTool, which  
is almost
equal to the current one but with less responsabilities. It is  
intended to be
incorporated to uDig core when needed.
We found the blackboard as a great place for inter-plugin  
collaboration while
keeping the plugins decoupled. The strategy is to store the current
EditToolHandler on the blackboard for the modes to be able of  
taking control
of it.
As you know, the EditToolHandler holds the activators and  
behaviours that
compose an edit tool, and the list of activators and behaviours are  
allowed
to be modified.
whenever a mode is selected, it is free to contribute or replace the
behaviours of the edit tool handler held in the blackboard, as long  
as it
restores it to its original state once the mode is deactivated.  
This gives
enough freedom as to implement the representative modes stated  
above and
still keep things as simple as possible (other possible approaches  
meant
adding a lot of complexity to the current edit tools framework).
When a mode takes control, it can do three things:
- add or replace behaviours
- add or replace activators (generally used for feedback actions)
- change the currently being used IEditPointProvider
IEditPointProvider is the interface for abstracting out the  
obtention of the
point to add to a strategy object. This leads to a great  
simplification of
AddVertexCommand and allows its reuse.
So, AddVertexCommand now receives the point to add and adds it. No  
need to
perform the snap calculation nor any other.
So, whomever configures the AddVertexCommand just pass it the  
vertex to add,
and has to obtain it from an IEditPointProvider. For example, the
AddVertexWhileCreatingBehaviour takes the IEditPointProvider to use  
from the
map's blackboard.
When the parallel mode is selected, it sets an IEditPointProvider that
restricts the location of the point to add to the point where the line
parallel to the reference segment passing through the last edit  
shape point
crosses the normal to the line where the reference segment is  
contained and
that passes through the mouse location, and so on.
hmmm.. if I am not making it clear just let me know, I might put some
screenshots on the wiki and provide some more concreteness.
Regards,
Gabriel
--adrian