/* TEACH GO_DEMO                                    Ben Rabau, 11th Dec 1992

This file shows an examples of some of the objects which can be visualised.
They can be dragged around as described in TEACH * GO_DRAG, be changed
and manipulated as described in TEACH * GO  and TEACH * MAKE_EDITABLE.


For more general detailed information see

HELP * GO
REF * GO

 */
;;; Requires the following file to be loaded:
uses go;
;;; Other files will be autoloaded if necessary (e.g. LIB * go_rectangle).
;;; See REF * AUTOLOAD/PRAUTOLOADWARN
;;; If you would like to monitor the autoloading please do:
/*
    sysprautoloadwarn -> prautoloadwarn;
 */
;;; If you no longer want to see autoloading messages please do:
/*
    erase -> prautoloadwarn;
 */
;;; If you want to avoid autoloading then you need to load at least:
/*
    uses go_square
    uses go_rectangle
    uses go_oblong
    uses go_polyline
    uses go_polyarrow
    uses go_circle
    uses go_text_input
    uses go_rc_window
 */

;;; It also requires the GO window to be active:
go_init_rc();

;;; From now on (until another pane is used) the new go_pane onbject
;;; will be accessed by the global variable: go_default_pane (see also
;;; (REF * GO_VARS/go_default_pane). This allows us to change for
;;; instance the background colour:
'navajo white' -> go_bgcolour( go_default_pane );

;;; We now make a few graphical objects.

vars a_rectangle = instance go_rectangle;
    go_bgcolour  = 'slateblue';
    go_filled    = true;
    go_width     = 50;
    go_height    = 15;
endinstance;

vars an_icon           = instance go_bitmap;
    go_fgcolour        = 'white';
    go_bgcolour        = 'gray50';
    go_iconname        = '$usepop/pop/x/ved/bitmaps/ref_48.xbm';
    go_bounding_width  = 48;
    go_bounding_height = 48;
endinstance;

vars arc1          = instance go_arc;
    go_bgcolour    = 'gold' ;
    go_filled      = true;
    go_linewidth   =  5;
    go_start_angle = 20;
    go_arc         = 50;
endinstance;

vars a_square   = instance go_square;
    go_bgcolour = 'slateblue';
    go_filled   = true;
    go_radius   = 25;
endinstance;

vars circ1      = instance go_circle;
    go_bgcolour = 'gold';
    go_filled   = true;
    go_radius   = 20;
endinstance;

vars a_triangle  = instance go_polygon;
    go_bgcolour  = 'gray50';
    go_filled    = true;
    go_npoints   =  3;
    go_radius    = 25;
endinstance;

vars an_oblong   = instance go_oblong;
    go_bgcolour  = 'gold';
    go_filled    = true;
    go_linewidth =  2;
    go_height    = 30;
    go_width     = 50;
endinstance;

vars arc2          = instance go_arc;
    go_bgcolour    = 'gray';
    go_filled      = true;
    go_linewidth   =   5;
    go_start_angle = 200;
    go_arc         =  50;
endinstance;

vars a_logo      = instance go_polygon;
    go_bgcolour  = 'slateblue';
    go_filled    = true;
    go_regular   = false;
    go_world_coords
                 = [80 40  70 70  40 25  10 70  0 40  30 55  40 0  50 55];
endinstance;

vars a_pentagon  = instance go_polygon;
    go_bgcolour  = 'gold';
    go_filled    = true;
    go_npoints   =  5;
    go_radius    = 25;
endinstance;

vars a_text_input     = instance go_text_input;
    go_label          = 'Input: ____';
    go_bounding_width = 100;
endinstance;

vars a_diamond  = instance go_polygon;
    go_bgcolour  = 'gray50';
    go_filled    = true;
    go_npoints   =  4;
    go_linewidth =  2;
    go_xscale    =  0.5;
    go_radius    = 25;
endinstance;

;;; store all these items; and display them in a big go_circle:
vars the_items = [%
            a_rectangle,
            an_icon,
            arc1,
            a_square,
            circ1,
            a_triangle,
            an_oblong,
            arc2,
            a_logo,
            a_pentagon,
            a_text_input,
            a_diamond
                  %];

vars item_group = newgo_group();

define do_group();
lvars item;
    go_batch_mode_on( go_default_pane );
    for item in the_items do
        go_add_to( item, item_group );
    endfor;
    go_batch_mode_off( go_default_pane );
enddefine;

define do_ungroup();
lvars item;
    go_batch_mode_on( go_default_pane );
    for item in the_items do
        go_remove_from( item , item_group );
    endfor;
    go_batch_mode_off( go_default_pane );
enddefine;

do_group();

vars bigrad = 210;
define show_circular_group( ang );
lvars ang;
lvars item, diff_ang=(360 div length(the_items));
    go_clear( item_group );
    for item in the_items do
        go_centre_to( round(bigrad*cos(ang)), round(bigrad*sin(ang)), item);
        (ang - diff_ang) mod 360 -> ang;
    endfor;
    go_redraw( item_group );
enddefine;

show_circular_group( 0 );
go_add_to( item_group, go_default_pane );

;;; TEXT

vars the_O   = newgo_polygon();
    9 -> go_npoints( the_O );
    12 -> go_linewidth( the_O );
    'light sea green' -> go_fgcolour( the_O );
    70 -> go_radius( the_O );
    go_centre_to( 40, 80, the_O );
    go_add_to( the_O, go_default_pane );

vars the_G    = newgo_polyarrow();
    10 -> go_linewidth( the_G );
    'dark green' -> go_fgcolour(the_G);
    [27 119 -37 156 -94 127 -118 75 -102 23 -63 1 -21 1 19 25 19 61 -27 76]
    -> go_world_coords( the_G );
    go_add_to( the_G, go_default_pane );

#_IF DEF go_animator_button_key
    ;;; We use the predefined version of the animator_button to prevent
    ;;; costly recompilation in objectclass for a new class definition.
#_ELSE
define :class go_animator_button;
    isa go_mouse_sensitive go_labelled go_oblong;
enddefine;

;;; The first call to a method of this new class will compile the methods.
;;; If you want them to be compiled before calling them you can always call
;;; the optimise function (REF * optimise_objectclass):
optimise_objectclass( "all" );
;;; link_all_methods();
#_ENDIF

vars a_button= newgo_animator_button();
    20 -> go_label_x_offset( a_button );
    'Animate' -> go_label( a_button );
    2 -> go_linewidth( a_button );
    'red' -> go_fgcolour( a_button );
    go_centre_to( 0, -60, a_button );
    go_add_to( a_button, go_default_pane );

;;; Create a group representing a dark blue box with some white text in:
vars text_group = instance go_group;
    endinstance;
    go_add_to( text_group, go_default_pane );

vars text_bg = newgo_rectangle();
    'darkslateblue' -> go_bgcolour( text_bg );
    true -> go_filled( text_bg );
    175 -> go_width( text_bg );
    50 -> go_height( text_bg );
    go_centre_to( 0, -100, text_bg );
    go_add_to( text_bg, text_group );

vars label1     = newgo_text();
    'Graphical Objects' -> go_label( label1 );
    'white' -> go_fgcolour( label1 );
    go_centre_to( go_xcentre(text_bg), go_ycentre(text_bg)+10, label1 );
    go_add_to( label1, text_group );

vars label2     = newgo_text();
    'Library' -> go_label( label2 );
    'white' -> go_fgcolour( label2 );
    go_centre_to( go_xcentre(text_bg), go_ycentre(text_bg)-10, label2 );
    go_add_to( label2, text_group );

vars group_button= newgo_animator_button();
    15 -> go_label_x_offset( group_button );
    'Ungroup' -> go_label( group_button );
    go_centre_to( 0, -160, group_button );
    go_add_to( group_button, go_default_pane );

;;; Show a bit of movement:
vars current_big_angle = 0, current_small_angle = 0;

;;; Rotate all small objects in a big go_circle:
define show_animation();
    (current_big_angle+10) mod 360 -> current_big_angle;
    applist( go_panes, go_batch_mode_on);
    show_circular_group( current_big_angle );
    applist( go_panes, go_batch_mode_off);
    5e5 -> sys_timer(show_animation);
enddefine;



vars procedure stop_animation;

define start_animation(event_data, obj);
lvars event_data;
    stop_animation  -> go_mouse_up_action( 1, a_button );
    'Stop' -> go_label( a_button );
    5e5 -> sys_timer(show_animation);
enddefine;

define stop_animation(event_data, obj);
lvars event_data;
    false -> sys_timer(show_animation);
    start_animation -> go_mouse_down_action( 1, a_button );
    'Animate' -> go_label( a_button );
enddefine;

vars procedure do_the_ungrouping; ;;; defined below
define do_the_grouping(event_data, obj);
lvars event_data, obj;
    'Ungroup' -> go_label( group_button );
    do_group();
    do_the_ungrouping -> go_mouse_down_action( 1, group_button );
enddefine;

define do_the_ungrouping(event_data, obj);
lvars event_data, obj;
    'Group' -> go_label( group_button );
    do_ungroup();
    do_the_grouping -> go_mouse_down_action( 1, group_button );
enddefine;

;;; Initialise without animation:
'Animate' -> go_label( a_button );
true -> go_live_object( a_button );
true -> go_live_object( group_button );

;;; Old style event handlers:
;;; start_animation -> go_select_action( a_button );

;;; New style event handler
start_animation -> go_mouse_down_action( 1, a_button );
do_the_ungrouping -> go_mouse_down_action( 1, group_button );
;;; Rotates as long as the mouse is held down...
stop_animation  -> go_mouse_up_action( 1, a_button );

--- C.all/lib/proto/go/teach/go_demo
--- Copyright University of Sussex 1993. All rights reserved.
