GUI Builders (was: More On Multiple Inheritance)

Matthew Tuck matty@box.net.au
Mon, 10 May 1999 21:54:48 +0930


Hans-Dieter.Dreier@materna.de wrote:

> If we use the instance layout of the target class for templates as well, a
> simple copy constructor can be used as a creation routine. As an additional
> benefit, editor (and debugger) can then be used to view "live" configured
> instance items as well as templates.

This strikes me as basically a prototyping scheme, at least on the
data.  You're talking about having templates (prototypes) which can have
the same impl but differ in their state.  And these can in turn be used
as a prototype for another template.

> Methods are almost always class items since all of the instances share the same
> method code. Message handlers are instance items, however. IMO it is a major
> design flaw to implement message handlers as class items since this effectively
> prohits reuse of that class. Message handlers often need to access the name
> space of the _instance_ rather than that of the _class_. If all the contacts to
> the instance's environment would have to take place by dynamic dispatch, such a
> class would be rather cumbersome to use.

I don't think so.  If the widget classes are set up to use observers,
the widgets are reusable and don't need to be written with any
particular message handler in mind.  Ideally the widget, handler and the
data are totally separate classes, providing more flexibility.  Hence
handlers should never need to be in the widget.  Java 1.0 joined them
together - they replaced that model with observers in 1.1.

> Dynamic creation of identically configured objects by a program is possible by
> calling the creation routine multiple times for a given template. In this case
> the instance created by the declaration might be unwanted;  we might want to be
> able to prevent automatic creation due to the declaration.

If this sort of thing ever happened, I would prefer it to be an
optimisation, I'm not sure I'd want to give it language status, even
though this sort of thing could really happen in any situation.

> We could do this by
> either adding a key word ("template") to the declaration or by adding a special
> outline item (folder) for such templates. The latter is better because the
> former would either disrupt the instance layout or leave a NULL reference gaping
> if used in the "instance items" section of a class.

I'm not sure what you're proposing here.  Could you elaborate?

I assume you're defining properties to be constant here.  Hence a copy
is unneeded and you can reuse the same object.  If you had properties
that were not constant, eg the text font might change due to a checkbox
somewhere else being chosen, you would not use that for a property but
instead have both fonts as a "initial font" property and "changed font"
property respectively.

Because a copy is unneeded you might keep a prototype repository where
you pass the prototype id and get the prototype back which could be
created lazily if desired or the whole lot could be loaded from a file
or whatever.  This wouldn't require any extra language facility.

You might want to keep the prototypes constant or the ability to change
a lot of widgets at once might be useful.  But there is certainly a
distinction between properties like font and transient properties like
widget state.

It would be very difficult to merge these into one widget prototype if
you actually had the message handler in the widget too.

>> So do these editors allow you to define a control that inherits the properties
>> of another control?
> Yes. Usually that will be the surrounding window.

When you say "surrounding window" do you mean "surrounding widget" or do
you mean it literally?

This is one example of allowing the choice between data (constant value
inherited at compile-time from another template) and get/sets (code for
getting the value from the surrounding widget).

Basically I could see the use both of inheriting from the surrounding
widget, e.g. pop-up help where you don't have anything more specific to
say, or another template and making small changes.  In essence the
latter could either be a GUI builder only concept (by fully filling in
all fields and ignoring the template inheritance relationships) or could
actually be used in the creation functions to copy and change a
template.

And if you could change these templates at run-time, would they be
embedding or delegation based, ie would changes to the parents effect
children that haven't overridden?  At the very least you'd need the
ability to create your own templates based on other templates at
run-time.

> <Window: MyToplevelWindow    // type 1 item>
>   Window Position            // type 3 item - you couldn't add this comment
>    Top: <0                   // type 2 item>
>    Left: <0>
>    Widht: <400>
>    Height: <300>
>   Window Style
>    Border? <true>
>    System Menu? <true>
>    ...

I would expect this to be merely one view of the GUI languages of
course.  A more graphical dragging and dropping alternative would be
another.

> I would suggest to keep that editor-related stuff in a separate class to be
> able to easily strip it for a release version of the program.

I would consider the "class" to be different in the sense of GUI
Builders and HLLs.  GUI builders have an editor element which is
actually a widget defined in the program/language library, whereas a HLL
has an editor element which is a language element.

Hence they're different things and so a separation is probably necessary
for that reason too.

This is a bit similar to a JavaBean, which defines things about how a
GUI Builder uses it.  I'm not up to date on what information it provides
however.

> You see the similarity to the GUI example above? Function declarations, class
> declarations, all that stuff could be made customisable as well. IMO the
> benefits would be huge: Everyone could make its own without having to touch the
> editor "core". Changes even at edit time were possible. You add a property: Just
> change and compile the editor supplement class and there it is, ready for use.
> This editor core would also be a (relatively) small affair instead of a big
> monolith. (You know I'm in favour of writing frameworks and filling the details
> in later, when actually needed).

I think this code should never be a part of the editor core since it's
view-oriented.  The editor core would:

o coordinate the shared UI (whatever that might be)
o coordinate adding and removing languages, translations and views
into/from the system
o coordinate translations (ie incremental compilation)
o coordinate views (ie ensuring changes made in one window are
immediately reflected in others)

It strikes me that these similarities are basically in the fact that
both the HLL structured view and the GUI Builder structured views are
both structured views.  Hence they should share a structured view
framework instead.  If you want to add these properties at edit time, by
all means do.  Exactly how these are detected, added and removed would
be defined by the specific view using the framework.

> Sure. The editor somehow needs to know which instance items to treat as
> properties. At first glance, I can think of several ways to do this:

Maybe you could choose all public fields?

> 1. Add a keyword (say, "property") to the instance item's declaration.
>    Only usable for simple cases since no specific customisation info can be
>    presented this way.
>    ...
>    Writing a keyword is much less work than writing a whole class.
>    ...

I wouldn't say that this action is common enough to warrant introducing
a new HLL feature on prototypes.  It's certainly useful for widgets and
probably some other classes, but at least for widgets I doubt they're
defined anywhere near as often as they're used.

> All of the above ways silently include the assumption that there is only one
> such "customisation set" for each class. This might be sufficient in most cases,
> but why should we accept that restriction right from the start?

If you chose them all it wouldn't be a restriction.

> Some people might prefer a simpler GUI builder that would not expose all of
> the available properties (and complexities), but still should be able to use
> the same underlying GUI classes. Also, legacy customisation sets could be kept
> for a while to allow updating source files.

Yes but this is chosen by the user, not by a computational procedure,
and hence choosing all we can at first might be acceptable as a default.

My thinking of a cset would be merely as a default set of properties
that appear.  The user could add and remove properties at will.  I
assume if they were not present, they would take a default value.

In this way you could also change csets, wherein all new properties in
the cset are added, and all old properties with the default value are
removed.

If you have manual add and remove facility for individual elements,
csets are essentially an add-on.  The primitive add-remove
functionality is more important.

Perhaps the editor would also automatically remove properties set to
their defaults at some stage.

> When I was looking for a device that could be used to distinguish CSs,
> constructors (or "creation functions") came to mind, since there may be many of
> them with different parameter sets and names. But after having it thought over a
> little bit, I'd refrain from that approach, because we need a bidirectional
> mapping: The property set stored with a declaration needs to be read as well as
> written by the editor.

A constructor shouldn't really be needed if the sets are compile-time
known and constant.  I'm not really sure that they should be a part of
the GUI language, rather than just set up through the editor, either.

-- 
     Matthew Tuck - Software Developer & All-Round Nice Guy
             mailto:matty@box.net.au (ICQ #8125618)
       Check out the Ultra programming language project!
              http://www.box.net.au/~matty/ultra/