InterActor - A Unified Graphical Model

Author: Martyn Cutcher

email martyn@cutthecrap.biz

website www.cutthecrap.biz

What is InterActor?

InterActor originated back in 1989 as part of "The HyperView Project". This was an Apple Mac based software development that married a novel graphical environment with an even more novel new language. The name "InterActor" indicated that complex interactive systems could best be understood as a number of interactions with simpler semi-autonomous elements - "Actors".

The current version of InterActor has been implemented using Java2D and provides the same powerful graphical model but linked to Java rather than the asynchronous "scheme-derived" language of the original.

Cut The Crap

Most GUI systems, such as Java Swing, MFC, MacApp etc..., structure the interface using parent-child graphical elements. For example, a "button" component will be placed on a "form" or "container" component. The "button" will reference its "parent" and hold state such as its "x" and "y" co-ordinates where it should be displayed. The "parent" will simply maintain a list (in z-order usually) of its "child" components.

InterActor was conceived after analysing a number of diverse systems and seeking to understand what makes them work.

It was realised that the direct association of the parent-child structure was creating complexity when designing different interaction styles. What was needed was a "slot".

The idea is very simple. Rather than adding a "child" component to a "parent" container directly, you would instead create a "slot" structure in the "parent" and set its content to be that of the "child". The "slot" contains the "placement" information - such as position, scale, etc...

It should be clear that this level of indirection in no way restricts conventional parent-child functionality, but it does enable a few things.

Interface Replacement

This was a key concept, in part inspired from Apple's HyperCard.

In order for a computer to convey some "new" graphical information, the current interface must be modified. One way to view this is that certain elements are "updated", another view is that the "old" element is "replaced" with some new element.

Consider a "checkbox" example:

If the checkbox is "unchecked" it will display an "unchecked" graphic, when it is "checked" it will display a "checked" graphic. We can have a model where the "checkbox" chooses which graphic to display dependent on its state, OR, we can have a model where its graphic is "replaced" when its state is changed.

This is a beautiful concept, and if you haven't got it yet then read over that paragraph until you have.

For those familiar with the MIT ACT language there is a direct analogy here with the "become" statement, an "interface" is modified by "becoming" a new interface - and then considering that a large "GUI" is a federation of many smaller "GUIs".

Presentations

Computer-based presentations - Power Point based for example - are a great example of "replacement" interfaces.

Presentation Slides "replace" each other as the presentation continues.

Animation

Animation models such as Macromedia's have very similar structures to InterActor slots.

A "Cast" member is placed in a "channel" in a specific "frame". It is given a transformation matrix and a number of other attributes. But this is not contained in the cast member it is specified within a "placement" structure.

Multiple-Desktops

Xerox Rooms was one of the first desktop managers. The "same" application window could exist in several different desktop "rooms". This was achieved by specifying "placements" for each room, allowing the "room manager" to manipulate the appearance correctly.

InterActor

By using a "slot" or "placement" structure, InterActor based interfaces are able to deliver not only conventional GUIs but also "presentation" and "animation" style interactions.

Empowering Java 2D

The Java 2D demos are pretty neat. But I haven't seen much that really takes advantage of the functionality in real applications.

The InterActor model provides "declarative" methods that aid a number of graphical presentation techniques.

Probably the most significant of these is the ability to specify various "transformation" with a "slot". For example - Scale. It is straightforward to "zoom-in/out" on specific elements by simply setting the scale value of a "slot".

Animation - IAMovie

That InterActor provides a rendering model to support a broad class of graphical interactions should now be clear. IAMovie is an InterActor class derived from IAShape that provides an interface to directly support animations.

Animation Model

An animation is comprised of a sequence of "frames".

A "movie" has a "frame-rate" that defines the default "frame-delay".

A specific "frame" can have an explicit "delay".

A "movie" has a number of "channels".

"Channels" define "placement" that has a direct correlation with InterActor slot state.

How The Animation Is Rendered

When the IAMovie is created, it creates a "slot" for each "channel".

As the movie "plays", it copies the "channel" state for each "frame" into the associated InterActor "slots", and then updates the screen. It then pauses for the set "frame-delay" until rendering the next "frame".

If a "frame-delay" is set to "-1", the movie will "pause" until "resumed".

An IAMovie Example

We will create a movie that displays two strings: "IAMovie" and then "created using InterActor".

The effect we will describe is of the string "IAMovie" moving in from the right, rotating and reducing in scale from 4.0 to 1.0.

The movie should then pause waiting for the user to "click" on the movie.

Then the string "created using InterActor" will appear using an "alpha" transformation.

Here is the code for the movie:

InterActor ia = new Helper(true, 400, 300);
IAMovie mv = new IAMovie(ia, 
                         40 /* frame */,
                         2 /* channels */,
                         20 /* frame rate */,
                         400 /* width */,
                         300 /* height */ );

// The "cast"
IAText movtxt = new IAText(ia, "IAMovie", IAText.H1_FONT);
IAText crtxt = new IAText(ia, "created using InterActor", IAText.H2_FONT);

// we want white text on a black background
mv.setColors(null, Color.black, null); // pen, fill, pen-style
movtxt.setColors(Color.white, null, null);
crtxt.setColors(Color.white, null, null);

// define first transition - format channel, startFrame, endFrame
mv.setChannelContent(0, 0, 19, movtxt);
mv.setChannelLocation(0, 0, 19, 400, 60, 60, 60); // x1, x2, y1, y2
mv.setChannelRotation(0, 0, 19, 0.0f, (float) (2 * Math.PI)); // 360 rotation
mv.setChannelScale(0, 0, 19, 6.0f, 2.0f); //

mv.setFrameDelay(19, -1); // user input

// define second transition
mv.maintainChannel(0, 19, 39); // keep the "IAMovie" text

mv.setChannelContent(1, 20, crtxt);
mv.setChannelLocation(1, 20, 39, 60, 200);
mv.setChannelAlpha(1, 20, 39, 0.0f, 1.0f);

mv.setFrameDelay(39, ,-1);

mv.setUserControl(true);

The next stage is to display the movie, so now is a good time to consider....

Why A "Unified" Model Is Relevant

Not only is the IAMovie an IAShape derived InterActor component, so too are the "cast" members that populate its "channel" slots from one frame to the next. It is perfectly possibly to define movies that include other movies as cast members (though circularity is NOT allowed).

To render the movie we shall add to the "root" InterActor shape and "play" it, but while we are at it we shall also define a control that can be used to "scale" the movie.

The "scaling" is achieved in exactly the same way as scaling the channels in the movie itself - simply by changing the "scale" transformation value of the slot.

An InterActor widget - IAScale provides this simple behaviour, you create it by specifying a "slot" to control, by default its "scale" values range from 0.25 to 4.0 but you can specify your own scale factors if you wish.

... continuing from where we left off:

IAShape root = ia.getRootShape();

IASlot mvslot = root.addChild(50, 50, mv);

root.addChild(50, 26, new IAScaleSlot(mvslot));

And here is an applet that renders the movie described above. You will need Java2D. so unless you have a plugin installed you won't see anything.

You'll have to click on the movie to get it going and to resume when it pauses.

You can also try enlarging and reducing the movie:

InterActor Slots And Display List Rendering

Although a developer is free to specialize InterActor IAShape derived classes and to override the paintSelf method, this is not the recommended approach for most tasks.

For example, suppose that you wanted to draw a red rectangle at the top of your shape.

You could specialize the paintSelf method, but far simpler would simply be to add a simple IAShape object:

// add red rect to "myshape"
IAShape r = new IAShape(ia, 0, 12, IAShape.GEOM_INHERIT_WIDTH + IAShape.GEOM_ALIGN_TOP);
r.setColors(null, Color.red, null);

myshape.addChild(0, 0, r);

This is a very significant point:

That the same approach to separate an interface into a number of distinct rendered components, should also be used in the rendering of each component.

Rather than writing special code to display a component, different graphic elements are simply added/replaced to modify its appearance.

Swing/AWT Integration

The InterActor class derives from JApplet so can be rendered directly as an applet or can be hosted within any AWT Container.

It may be possible to derive an IAContainer that would allow Swing components to be contained within InterActor, but no attempts have yet been made to test this possibility.

How Can I Get InterActor?

InterActor is provided as part of the full Cut The Crap distribution and can be downloaded from www.cutthecrap.biz/software/downloads.html along with other Cut The Crap software.

Is It Free To Use?

InterActor is released as "shareware". It is not restricted in any way. Developers are of course encouraged to visit the payments page and pay for a license.

Purchase of a full license for the Cut The Crap Software will remove any obligation to make an additional shareware contribution.