[comp.windows.interviews] IsA

soh@andromeda.trl.OZ.AU (kam hung soh) (06/07/91)

I'm working on a graph editor based on Idraw (and using the Unidraw
toolkit).  In my editor, the type of manipulator created depends on the
object that the mouse pointer started from.  For example:

1. If I hold down and release the mouse button on nothing, a node is
created.

2. If I hold down and drag from a node to another node, an edge is
created between the two nodes

3. If I hold down and drag from nothing, a bounding box is made and
objects can be grouped together.

The tool that creates these manipulators can store state information so
that it knows how to interpret the manipulator, but this is a little
kludgy to me.  It seems much cleaner if the tool could ask the
manipulator what class it is (using IsA() and ClassId()) and decide
what to do.  At the moment, because manipulators are not derived from
the Persistent class, they do not have these virtual functions.

Your opinions?

Regards,

Soh, Kam Hung      email: h.soh@trl.oz.au     tel: +61 3 541 6403 
Telecom Research Laboratories, POB 249 Clayton, Victoria 3168, Australia 

vlis@lurch.stanford.edu (John Vlissides) (06/22/91)

> I'm working on a graph editor based on Idraw (and using the Unidraw
> toolkit).  In my editor, the type of manipulator created depends on the
> object that the mouse pointer started from.  For example:
> 
> 1. If I hold down and release the mouse button on nothing, a node is
> created.
> 
> 2. If I hold down and drag from a node to another node, an edge is
> created between the two nodes
> 
> 3. If I hold down and drag from nothing, a bounding box is made and
> objects can be grouped together.
> 
> The tool that creates these manipulators can store state information so
> that it knows how to interpret the manipulator, but this is a little
> kludgy to me.  It seems much cleaner if the tool could ask the
> manipulator what class it is (using IsA() and ClassId()) and decide
> what to do.  At the moment, because manipulators are not derived from
> the Persistent class, they do not have these virtual functions.

Manipulators are transient objects that tools use to define their
direct manipulation semantics.  Therefore there is no mechanism for
storing and retrieving manipulators.  

I'm not sure why you think it's cleaner for a tool to switch the code
it executes based on the type of manipulator.  A tool will create
exactly one manipulator for a given situation; it therefore knows that
it will interpret exactly the same manipulator.  You want to encode
the information in the manipulator, not the tool.  For example the
manipulator can define two operations:

    boolean Grouped();
    Selection* Selections();

In your case #1 above, Grouped returns false, and the Selections
operation returns nil (or an empty selection object).  The tool
interprets this as a node creation manipulation and creates the
appropriate command (probably PasteCmd).

In case #2, Grouped returns false, and Selections returns a selection
object containing two nodes.  The tool interprets this as an edge
creation operation and creates a command that connects the nodes.
(There will be at least two nodes, but you could allow more.)

In case #3, Grouped returns true, and Selections returns the selected
node views.  The tool interprets this as a group operation on the
selected nodes.

Thus the tool has all the information it needs to interpret the
manipulation correctly.

(An aside: Ideally, Selections would return a const Selection* because
you don't want to construct a new Selection object each time it's
called and depend on the caller to delete it.  Therefore Selections
would return a pointer to a Selection object that the manipulator
keeps internally.  But since the Selection class doesn't use const
member functions currently, you wouldn't be able to do anything with
the const Selection*!)
--
John Vlissides
Computer Systems Lab
Stanford University
vlis@interviews.stanford.edu