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