An Interactive Editor for the Statecharts Graphical Language

Stephen Edwards

Previous Next

Architecture


  1. The StateImage Class
  2. The TransImage Class
  3. The StateDialog and TransDialog Classes
  4. The major classes and their relationships are shown here. The State and Trans store non-derived information; these alone are stored and retrieved from disk. Instances of the StateImage and TransImage classes, derived from instances of State and Trans, describe how states and transitions are currently being displayed. The View class surrounds a canvas widget with the additional information required of a particular view of the database, including a list of all StateImage and TransImage instances displayed on the canvas. The Editor class surrounds a View instance, and is responsible for tool selection, controlling what appears in the View, and so forth.

    The State Class

    The State class contains The interesting methods defined on the State class are

    The StateImage Class

    The StateImage class contains The interesting methods defined on the StateImage class are

    The Trans Class

    The Trans class contains The interesting methods defined on the Trans class are

    The TransImage Class

    The TransImage class is analogous to the StateImage class, and stores similar data: the master Trans, the View, a list of canvas IDs for the transition, and a list of canvas IDs for the selection handles. The methods are for the most part similar, although the methods for bindings behave in very different ways.

    The View Class

    The View class can be thought of as a wrapper for the canvas widget. The canvas widget has much, but not all of the required functionality. The biggest omission in the canvas widget is a way to go from canvas objects to objects in the database. I also wanted a zoom feature, something the canvas widget doesn't do elegantly.

    The View class contains

    The interesting methods defined on View are The system could be extended to support different ways of displaying part of the database. The equivalent of the StateImage and TransImage classes would be added, and a variation of the View class would be needed. Class inheritance would be perfect here: some aspects of the View class would be useful for all canvas-oriented views, such as the object ID-to-object arrays and the selection mechanism, but others, such as the zoom mechanism, are view-specific.

    The StateDialog and TransDialog Classes

    The constructor for the StateDialog class takes a State object as an argument and creates a non-modal dialog that can edit the attributes (name, name font, name color, box fill color, and outline stipple) of that state. The dialog's two buttons are Apply, which copies the attributes in the dialog to the database, changing all views in which the state appears, and Dismiss, which ends the dialog.

    The TransDialog class behaves similarly, except it edits transition-specific attributes.

    Bindings

    There are currently four tools: the arrow tool for moving, selecting, and stretching things; the state tool for creating new states; the arc tool for creating new transitions; and the text tool for editing the text attached to states and transitions. Really, these tools are different ways of interpreting key and mouse events.

    New tools are defined using the newtool procedure:

    newtool arrow @$bmd/arrow.xbm left_ptr
    
    The arguments are the name of the tool, the bitmap to display on the tool palette, and the cursor to display in the canvas.

    The mapping between my names for bindings and X's are defined with an array:

    set bindings(B1) 
    set bindings(B1Release) 
    
    This gives the program a list of all possible bindings. The procedure called when an event occurs is defined in a two-step process:
    bindproc {%v %x %y} {view x y} {
      set object [$view currentObject]
      if { $object != "" } {
        if { [ $object info method arrowB1motion \
               -body ] != "" } {
            $object arrowB1motion \
               $x $y [$view currentData]
        }
      }
    }
    bindto arrow B1Motion
    bindto arrow ShiftB1Motion
    bindto state B2Motion
    
    This scheme allows the same procedure to be called for multiple events across multiple tools. In this example, the actual arguments of the bound procedure are the view and the coordinates where the event occurred (%v %x %y), the formal arguments are view, x, and y (variable names in the procedure), and the given procedure is bound to the arrow tool's B1Motion event, the arrow tool's ShiftB1Motion (mouse movement with both the first button and shift key held down), and the state tool's B2Motion event.

    The procedure in this example first asks the View on which object (image) the event occurred. For example, if the user was dragging a handle on a StateImage, it would return that particular StateImage. Next, if there is an object there, it checks to see if there is a method arrowB1motion defined on the object. If so, it invokes the method, passing the coordinates of the event and the type (currentData) of the canvas object (e.g., NWHandle, spline, etc.).

    Some actions are best done to the entire selected set, others are best done to a single object. Both schemes can be implemented in this framework. For example, dragging a state should move all selected states. When the method for arrowB1motion is given an event coming from the outline of a state, it invokes the move method on all the selected states explicitly. Dragging handle, on the other hand, only affect the state or transition whose handle it is.


    Last updated 941202

    Written by Stephen Edwards.