/* TEACH GO_SCREEN_OBJECT                       Ben Rabau, 27th Aug 1993

This file refers to located objects in Poplog/GO. This is the most basic
class which allows objects to be represented on the screen in a specific
location and a specific coordinate system (see also TEACH * GO_LOCATED).

Most of this teach file will use screen objects of the go_polygon class
( see TEACH * GO_POLYGON ) to demonstrate the concepts of the go_located
mixin. Extra indications are given where methods of the go_polygon class
are used.

For more general detailed information see

HELP * GO
REF * GO

         CONTENTS - (Use <ENTER> g to access required sections)

 -- Requirements
 -- Example
 -- Manual drawing
 -- go_colourable
 -- Optimisations
 -- Depth
 -- Copy object
 -- Destroy object

 */

/*
-- Requirements -------------------------------------------------------
 */
;;; This requires the following files to be loaded:
uses go;
uses go_screen_object;

;;; It also requires an active go_pane (see TEACH * GO_PANE and
;;; TEACH * GO_RC_WINDOW):
go_init_rc();

/*
-- Example ------------------------------------------------------------
 */
;;; Create a polygon (see TEACH * GO_POLYGON) and visualise it on the
;;; newly created go_pane (see TEACH * GO_PANE/go_add_to):

vars poly1 = newgo_polygon();
go_add_to( poly1 , go_default_pane );

/*
-- Manual drawing -----------------------------------------------------
 */

;;; The go_add_to() method is the standard method to visualise objects. However
;;; the underlying methods can of course also be used. These methods do not
;;; keep track of the object's position and therefore do not allow any DM.
;;; Basically there are four methods:
    ;;; go_clear() the object
    go_clear( poly1 );

    ;;; go_draw() the object regardless of its current depth on the screen.
    ;;; This is the fastest way to visualise the object but it does not
    ;;; take into account any other objects, nor remembers its position.
    ;;; This needs the extra argument to know in which pane; the last
    ;;; created pane is accessible through "go_default_pane":
    go_draw( go_default_pane, poly1 );

    ;;; go_internal_redraw() the object with regard to the objects above
    ;;; it, but regardless of what is underneath. This can only be used
    ;;; if the object has not dramatically changed (and the background is
    ;;; still correct).
    go_internal_redraw( poly1 );

    ;;; go_redraw() the object with regard to the objects that are above it
    ;;; and below. This redraws the whole area of the bounding box of that
    ;;; object. This is usefull when the background is destorted because of
    ;;; the previous (bigger?) shape or because of filling of the object.
    go_redraw( poly1 );

;;; The above methods will be used in the next examples but the user is
;;; advised to come back to the above section once the other features are
;;; more familiar.

/*
-- go_colourable ------------------------------------------------------
 */

;;; A screen object can be coloured with its own set of foreground and
;;; background colours (see TEACH * GO_COLOURABLE). If the object can be
;;; filled (see TEACH * GO_FILLABLE) then the background will be drawn
;;; first using the background colour (methods go_bgdraw and go_bgcolour).
;;; The foreground will always be drawn in the foreground colour (methods
;;; go_fgdraw and go_bgcolour).

;;; The apearance can be changed through it's colour and filling attributes:
;;; To change the color of the outline:
'blue' -> go_fgcolour( poly1 );

;;; To change the color of the inside you need to make the object go_filled
;;; and assign a color to go_bgcolour():
'aquamarine' -> go_bgcolour( poly1 );
true -> go_filled( poly1 );

;;; The same colour methods also apply to the go_pane class:
'lightblue' -> go_bgcolour( go_default_pane );

;;; To return to the default settings you can use the boolean value false
;;; to indicate that an object inherits the foreground or background colour
;;; from the pane it is displayed in. This can of course not be used on the
;;; pane itself.
false -> go_fgcolour( poly1 );
false -> go_bgcolour( poly1 );

/*
-- Optimisations ------------------------------------------------------
 */
;;; All the above commands will all have immediate effects on the screen.

;;; Sometimes this can cause flashing because of numerous changes...
;;; You can go_group your own commands to avoid continuous updates on
;;; the screen. At a high level this can be done with the batch-commands
;;; on the pane:

go_batch_mode_on( go_default_pane );
    70 -> go_radius( poly1 );
    'red' -> go_fgcolour( poly1 );
    'yellow' -> go_bgcolour( poly1 );
    go_centre_to( 20,  50,  poly1 );   ;;; move to position x = 20, y = 50
go_batch_mode_off( go_default_pane );

;;; IMPORTANT NOTE: Currently this doesn't prevent the updates to be
;;; sent to the pixmap, the updates are only not shown at the time.
;;; This might still send too many update actions to the X-server.
;;; This can be reduced by setting the go_batch_mode_on directly on an
;;; object:


go_batch_mode_on( poly1 );
    70 -> go_radius( poly1 );
    'yellow' -> go_fgcolour( poly1 );
    'red' -> go_bgcolour( poly1 );
    go_centre_to(-20,  50,  poly1 );   ;;; move to position x = -20, y = 50
go_batch_mode_off( poly1 );

;;; If necessary both batch methods can e combined together.

;;; You can also make temporarily clear the object but some methods will
;;; redraw it automatically. You could also temporarily remove it from the
;;; pane, bu note that go_remove_from() followed by a go_add_to() also has
;;; the side-effect of putting the object on top of all other objects
;;; (see also go_raise).

    ;;; Using low-level methods like go_xloc() and go_yloc() which are
    ;;; not immediately reflected on the screen:
    go_clear( poly1 );
    50 -> go_xloc( poly1 ) ;           ;;; move to position x = 50
    10 -> go_yloc( poly1 ) ;           ;;; move to position y = 10

    'red' -> go_fgcolour( poly1 );     ;;; This automatically redraws


/*
-- Depth --------------------------------------------------------------
 */
;;; The objects on the screen all have a specific depth which results in
;;; a screen picture where objects can be moved under and over other
;;; objects (see TEACH * GO_DRAG). The depth can be influenced by
;;; raising or lowering the objects to the front or the back of the screen.
vars poly3, poly4;

;;; lets create two new object on top of the old one:
newgo_polygon() -> poly3;
newgo_polygon() -> poly4;

;;; Use two new colors to distinguish them (Note: go_filled is a method
;;; from the go_fillable mixin, see TEACH * GO_FILLABLE):
'gold'  ->  go_bgcolour( poly3 );
'brown' ->  go_bgcolour( poly4 );
 true   ->> go_filled( poly3 ) -> go_filled( poly4 );

;;; Make them slightly smaller to see the underlying objects (Note:
;;; go_radius is a method from go_polygon, see TEACH * GO_POLYGON):
go_radius( poly1 ) - 5 -> go_radius( poly3 );
go_radius( poly3 ) - 5 -> go_radius( poly4 );

;;; Move on top of poly1
go_centre_to( go_xcentre( poly1 ) - 10, go_ycentre( poly1 ), poly3 );
go_add_to( poly3 , go_default_pane );

go_centre_to( go_xcentre( poly1 ) + 20, go_ycentre( poly1 ), poly4 );
go_add_to( poly4 , go_default_pane );

;;; To put the earliest go_polygon (poly1) on top:
go_raise( poly1, go_default_pane );

;;; To go_lower it to the back:
go_lower( poly1, go_default_pane );

;;; To put the go_middle one on top:
go_raise( poly3, go_default_pane );


/* REMINDER */
;;; Now that most of the methods have been explained it is advisable to
;;; retry the different manual go_draw methods to see the differences.
;;; Especially the difference between go_internal_redraw() and go_redraw() as
;;; explained in the section: MANUAL DRAWING above.

    ;;; go_internal_redraw() does not redraw the underlying objects nor
    ;;; the background:
    false -> stored_go_filled( poly1 );  ;;; make transparent without redrawing
    go_internal_redraw( poly1 );

    ;;; go_redraw() first erases and then redraws; so the filling will
    ;;; be erased!
    go_redraw( poly1 );

    ;;; Note that all this is done correctly by the go_filled() method:
    true  -> go_filled( poly1 );
    false -> go_filled( poly1 );
    true  -> go_filled( poly1 );

/*
-- Copy object --------------------------------------------------------
 */
;;; You can copy an object with go_copy_object()
vars poly5 = go_copy_object( poly3 );

;;; This will put the copy exactly where the original was so it is not
;;; immediately apparent. To move it a little do:
go_centre_to( go_xcentre(poly3) + 10, go_ycentre(poly3) + 10, poly5 );

/*
-- Destroy object -----------------------------------------------------
 */
;;; You can destroy objects with: go_destroy_object()
go_destroy_object( poly3 );

;;; Or the whole pane:
go_destroy_object( go_default_pane );


;;; Note that all the variables which still hold refences to either
;;; the go_default_pane or any other object, might prevent the
;;; data from being garbage-collected.

;;; If it hasn't already dissapeared assign false to any of the global
;;; variables you have used and do:
false ->> poly1 ->> poly2 ->> poly3 ->> poly4 -> poly5;
sysgarbage();


;;; eof;

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