HELP GO_CLASSES                                           B.Rabau Apr 1993

The Graphical Objects library (GO) is described in TEACH * GO.

This help file concentrates on giving an overview of the available classes
in the GO library.


    _______WARNING: This  is  the  first  version of  a  class  library  of
    graphical objects and is distributed with this release of Poplog
    for evaluation and comment. As a  result of feedback and in  the
    interests of  better  integration with  Poplog,  the  facilities
    described may be modified. While all reasonable endeavours  will
    be made to limit incompatible changes, programs which use  these
    facilities may require modification to run on later versions.


Base-classes of GO
------------------
There are three base-classes in the GO system:
    1. go_shell
           Top level class representing a basic window which can hold one
           or graphics subwindows represented by the go_pane class.
           (see also: REF * go_shell and TEACH * GO_SHELL)
    2. go_pane
           Class which is an object oriented wrapper around the XpwGraphic
           widget (see HELP * XpwGraphic). It represents a graphics sub-
           window which normally exists in a go_shell object and which
           contains one or more go_screen_objects.
           (see also: REF * go_pane and TEACH * GO_PANE)
    3. go_screen_object
           Class describing all graphical objects which can be visualised
           on a go_pane and manipulated by Direct Manipulation (DM) on the
           screen.

See REF * GO_BASECLASSES.

Hierarchy of classes
--------------------
These three base classes have a number of subclasses which are visualised
in the following hierarchy. The classes are briefly explained in TEACH * GO.

    go_shell

    go_pane
       \__go_window_pane
             \__go_rc_window

    go_screen_object
       \__go_arc
             \__go_circle
       \__go_area
       \__go_bitmap
       \__go_group
       \__go_text
             \__go_text_input
       \__go_point
             \__go_edit_point
       \__go_polygon
             \__go_polyline
                   \__go_polyarrow
             \__go_rectangle
                   \__go_oblong
             \__go_square

For each of the classes there is a TEACH file and a REF entry. For
example: TEACH * GO_SQUARE and REF * go_square

See REF * GO_BASECLASSES, * GO_MIXINS and * GO_SUBCLASSES.


Users Class-Hierarchy
---------------------
If you have added specialised classes, you can reprint this hierarchy at
runtime by using:

    define class_before( first_key, second_key );
    lvars first_key, second_key;
        ;;; Sort class keys by their name
        alphabefore( class_name(first_key), class_name(second_key) );
    enddefine;

    define go_show_subclass_hierarchy( class, indent );
    lvars class, indent, key, children = infs_of_objectclass(class);
        ;;; Show hierarchy of classes in GO with increasing indentation
        for key in syssort( children, class_before ) do
             sp( indent * 6 ); pr( ' \\__'); npr( class_name(key) );
             go_show_subclass_hierarchy( key, indent + 1 );
        endfor;
    enddefine;

    define go_show_class_hierarchy();
    lvars class,
          toplevel = [% go_screen_object_key, go_pane_key, go_shell_key %];
        ;;; Show sub-class hierarchy for each top level class in GO:
        for class in toplevel do
            pr( '\n    '); npr( class_name(class) );
            go_show_subclass_hierarchy( class, 1 );
        endfor;
    enddefine;

    go_show_class_hierarchy();


Mixins
------
The above hierarchies do not contain any mixins. Most classes do inherit
a substantial number of data (slots) and behaviour (methods) from a number
of shared mixins. These mixins represent a concept which is not a complete
class. They cannot be used directly as an object in GO.

These mixins never inherit from any other classes or mixins and thus they
are sealed units. To be safe, a mixin should not overwrite any methods from
other classes, however, a number of mixins add behaviour to existing methods
by using the call_next_method() feature of Objectclass. These mixins need to
be inherited before any other classes, and will get special attention below.
As a general rule:
    IT IS ALWAYS BEST TO INHERIT MIXINS BEFORE CLASSES:
    Example:
        isa   <mixinclass>  <objectclass>
    Rather than:
        isa  <objectclass>  <mixinclass>

The usage of Mixins  is rather difficult to show in a consice printed
hierarchy. A procedure go_show_mixin_hierarchy() is given below, to print
out the full hierarchy for each class in GO in the format:

    go_arc
         \__go_fillable (in: go_arc)
             \__go_colourable (in: go_screen_object)
                 \__go_located (in: go_screen_object)

The above shows that the class go_arc inherits from three mixins which
are inherited in the super classes go_arc and go_screen_object. If a mixin
inadvertedly inherits from other classes (in which case it should be a
class rather than a mixin), a warning appears of the form:

    go_window_pane
         \__go_pane (in: go_window_pane)
            Warning: Mixin go_pane inherits from other classes!
             \__go_located (in: go_pane)
                 \__go_composite (in: go_pane)
                     \__go_short_print (in: go_pane)

In this case go_pane should be defined as a class and not as a mixin, since
it inherits from: go_located, go_composite and go_short_print.

See REF * GO_MIXINS.


Special Mixin go_short_print
----------------------------
The special mixin "go_short_print" is defined in the top level library file
go.p. This mixin is added to avoid printing endless loops while printing
out instances of the GO library. This will probably be phased out as new
print features are added in Objectclass.

If a class inherits this mixin the method print_object() will be overwritten
and just print the data key of the class. The slots of those classes are
not shown, each slot can be printed out separately by using the form:
    <slot name>( <instance> ) =>


Users Mixin-Hierarchy
---------------------
If you have added specialised mixins, you can reprint this hierarchy at
runtime by using:

    define class_before( first_key, second_key );
    lvars first_key, second_key;
        alphabefore( class_name(first_key), class_name(second_key) );
    enddefine;

    vars go_show_indent = 0;  ;;; Global var used in go_show_mixin_hierarchy

    define go_show_submixin_hierarchy( class );
    lvars class, key, supers = supers_of_objectclass(class);
        if ismixinclass(class) and not(supers == []) then
             sp( go_show_indent * 4 );
             printf('Warning: Mixin %P inherits from other classes!\n',
                    [% class_name(class) %] );
        endif;
        for key in supers do
             if ismixinclass( key ) then
                 sp( go_show_indent * 4 ); pr(' \\__');pr( class_name(key) );
                 pr(' (in: '); pr( class_name(class) ); npr(')');
                 go_show_indent + 1 -> go_show_indent;
             endif;
             go_show_submixin_hierarchy( key );
        endfor;
    enddefine;

    define go_find_all_infs( class ) -> infs;
    lvars class, infs = infs_of_objectclass(class), key, inf;
        for key in infs do
            for inf in go_find_all_infs(key) do
                unless member( inf, infs ) do
                    inf :: infs -> infs;
                endunless;
            endfor;
        endfor;
    enddefine;

    define go_show_mixin_hierarchy();
    lvars class, key,
          toplevel = [% go_screen_object_key, go_pane_key, go_shell_key %];
        ;;; Show mixin-hierarchy for each top level class in GO:
        for class in toplevel do
            for key in syssort( go_find_all_infs( class ), class_before ) do
                2 -> go_show_indent;
                pr( '\n    '); npr( class_name(key) );
                go_show_submixin_hierarchy( key );
            endfor;
        endfor;
    enddefine;

    go_show_mixin_hierarchy();


Slots and Methods
-----------------
A complete list of methods and slots defined in the classes of GO is given
in REF * GO_OVERVIEW.

    define go_find_all_mixins( class, mixins ) -> new_mixins;
    lvars class, mixins, new_mixins = mixins;
    lvars supers = supers_of_objectclass(class), key;
        for key in supers do
            for super in go_find_all_mixins(key) do
                if ismixinclass(super) and not(member(super, new_mixins)) do
                    super::new_mixins -> new_mixins;
                endunless;
            endfor;
        endfor;
    enddefine;
--- C.all/lib/proto/go/help/go_classes
--- Copyright University of Sussex 1993. All rights reserved.
