/* TEACH GO_PANE                                Ben Rabau, 27th Aug 1993

This file shows an examples of the go_window_pane and go_rc_window class
which allow connection of GO to a XpwGraphic widget.

See HELP * XpwGraphic for more details on this graphical X-windows
widget. Since rc_windows use XpwGraphics widgets, they can also be
extended with Graphical Objects. See HELP * RC_GRAPHIC for more details
on the other features of rc_windows.

Graphical Objects can be created, visualised and manipulated in these
panes.

For more general information see:

TEACH * GO
HELP * GO
REF * GO


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

 -- INTRODUCTION
 -- DIRECT ATTACHMENT TO XpwGraphic WIDGETS
 -- VISUALISATION OF OBJECTS IN A GO_PANE
 -- ATTACHMENT TO RC_GRAPHIC WIDGETS
 -- GLOBAL VARIABLE go_panes
 -- MULTI WINDOW
 -- GENERAL METHODS
 -- DIMENSIONS OF rc_go_window OBJECTS
 -- DESTROYING A go_pane OBJECT

 */

/*  -------------------------------------------------------------------  *
-- INTRODUCTION -------------------------------------------------------
 *  -------------------------------------------------------------------  */

;;; Requires the following files to be loaded:
uses go;
uses go_pane;
uses go_window_pane;
uses go_rc_window;

;;; A pane is the part of the window in which the graphics will
;;; appear. It is the window without the header and any other
;;; attributes which are attached to it (resize objects, scroll
;;; bars, etc.).

;;; In GO the go_window_pane class contains the handler to that physical
;;; window (an XpwGraphic widget) in a slot "the_go_window".

;;; If you want a shell (the window with title bar and borders) around
;;; the go_window_pane, then you can either use the go_rc_window or the
;;; go_shell class (see TEACH * GO_SHELL).

/* --------------------------------------------------------------------  *
-- DIRECT ATTACHMENT TO XpwGraphic WIDGETS ----------------------------
 * --------------------------------------------------------------------  */

;;; If you have already created your own XpwGraphic window you can
;;; attach it to a go_window_pane instance by assigning it to the
;;; slot "the_go_window". Suppose the handle to that window is on the
;;; stack, then the following attaches it:
/*
    vars pane = newgo_window_pane();
    /* XpwGraphic widget on stack */ -> the_go_window( pane );
 */
;;; For the purpose of this demo we will make it ourselves easy and use
;;; the XpwGraphic widget attached to an rc_window.

rc_start();
vars pane = newgo_window_pane();
rc_window -> the_go_window( pane );

;;; From now on you can visualise screen objects (TEACH * GO_SCREEN_OBJECT)
;;; in this pane. However, none of the characteristics of drawing in the
;;; rc_graphic package are copied.

/*  -------------------------------------------------------------------  *
-- VISUALISATION OF OBJECTS IN A GO_PANE ------------------------------
 *  -------------------------------------------------------------------  */

;;; First make an object (see TEACH * GO_POLYGON):
vars poly1 = instance go_polygon; go_filled = true; endinstance;

;;; Then visualise the go_polygon (see also MANUAL DRAWING below). The
;;; go_add_to() method will go_draw the object on the screen and remember
;;; where it is on the screen and in relation to other existing objects.
;;; The new object always appears on top of everything else.
go_add_to( poly1 , pane );

;;; Because of the way this pane has been created (see remark above), the
;;; origin of the pane is still in (0,0). We can move it to the middle of
;;; the pane (defaults to dimension 500x500) if we do:
(250,250) -> go_position_of_origin(pane);

;;; The same effect, moving the origin, can be obtained by holding the
;;; mouse down in the pane (not over an object) and then dragging the
;;; mouse outside the pane. The pane will "scroll" to catch up with
;;; mouse (see TEACH * GO_LIVE/go_edit_drag_action and LIB * GO_PANE).

;;; A few more examples of changes to the coordinate system of a go_pane:
vars i;
for i from 1 to 20 do go_xorigin(pane) - 10 -> go_xorigin(pane); endfor;
for i from 1 to 20 do go_xorigin(pane) + 10 -> go_xorigin(pane); endfor;

;;; or
for i from 1 by  0.2 to 3 do go_xscale(pane) + i -> go_xscale(pane); endfor;
for i from 3 by -0.2 to 1 do go_xscale(pane) - i -> go_xscale(pane); endfor;


;;; Note that if anything goes wrong during this demo you can refresh
;;; the screen by doing:
go_refresh();

;;; If the dragging of the objects suddenly goes wrong, you can try:
go_reinit();

;;; The object can be removed with:
go_remove_from( poly1 , go_default_pane );

;;; A new object can also appear below everything else by using:
vars poly2 = instance go_polygon; go_filled = true; endinstance;
go_add_to( poly2 , go_default_pane );
go_annex_to( poly1 , go_default_pane );

;;; For more information of objects in a pane see TEACH * GO_SCREEN_OBJECT.

/*  -------------------------------------------------------------------  *
-- ATTACHMENT TO RC_GRAPHIC WIDGETS -----------------------------------
 *  -------------------------------------------------------------------  */

;;; GO can be used to extend the RC_GRAPHIC windows (rc_window) and
;;; a special subclass has been created for this purpose: go_rc_window
;;; This go_rc_window class can be created by doing:

vars rc_pane = newgo_rc_window();

;;; A higher level command: "go_init_rc();" can be used instead. This
;;; hides the pane object but allows access through the global variable
;;; "go_default_pane" (see REF * GO_VARS/go_default_pane).

;;; The underlying rc_window can be retrieved either by the global
;;; variable rc_window or by:

the_go_window( rc_pane ) =>

;;; This class will mirror all the RC_GRAPHIC settings at creation
;;; time, and any changes to the pane will also be reflected in the
;;; rc_window. E.g. a change in the scale of the GO pane will also
;;; be reflected in other RC commands:

2 -> go_xscale( rc_pane );
rc_xscale =>             /* will also be 2 */

;;; Since many attributes can change in between pure RC commands (e.g.
;;; the setting of foreground and background colours when drawing lines)
;;; these updates are not immediately mirrored in the pane. This
;;; preserves to independent nature of the Graphical Objects and RC.

3 -> rc_xscale;
go_xscale( rc_pane ) =>   /* will still be 2 */

;;; The pane can reincorporate any changes done to the rc_window by
;;; calling a simple update procedure: go_copy_from_rc().

go_copy_from_rc( rc_pane );
go_xscale( rc_pane ) =>   /* will now also be 3 */

;;; If you are using multi-windows with GO and you  want to change
;;; your RC environment back to a previous rc_window, you can either
;;; use LIB * RC_CONTEXT or do:
    ;;; Suppose you had made a change like:
    4 -> rc_xscale;
the_go_window( rc_pane ) -> rc_window;
go_copy_to_rc( rc_pane );
rc_xscale =>        /* will be reset to 3 */

;;; CAUTION: please check RC_CONTEXT and LIB * GO_RC_WINDOW to see
;;; whether all relevant global variables are reset. The definition
;;; of go_copy_to_rc() does for instance NOT include rotation (see
;;; LIB * RC_ROTATE_XY).

/* --------------------------------------------------------------------  *
-- GLOBAL VARIABLE go_panes -------------------------------------------
 * --------------------------------------------------------------------  */

;;; A list of all current panes is available in the global variable
;;; go_panes:
go_panes =>

/* --------------------------------------------------------------------  *
-- MULTI WINDOW -------------------------------------------------------
 * --------------------------------------------------------------------  */

;;; You can have as many panes as you want at the same time, each of
;;; which are separate items. Note that they might appear on top of each
;;; other.

vars rc_pane2 = newgo_rc_window();

;;; You can now put objects in it (see TEACH * GO):
uses go_polygon;

vars obj = newgo_polygon();

;;; To visualise an object in the pane which is created or manipulated
;;; most recently you can do:
go_add_to( obj , go_default_pane );

;;; This relies on the go_value of the global variable "go_default_pane".
;;; Since we just created pane 2 it should be set to this:
go_default_pane == rc_pane =>
go_default_pane == rc_pane2 =>

;;; If you want you can change this value manualy:
rc_pane -> go_default_pane;

;;; But it is better to do
go_add_to( obj, rc_pane );

;;; We have now shown the same object in two windows, since this object
;;; only has one World Coordinate representation, it will move in
;;; both panes at the same time (note the different scales). E.g.:
go_centre_to( 10, 10, obj );

;;; As a small demo, you can make a Zoom window from an existing pane
;;; by doing (maybe after having created a few more items):
vars blue_zoom_pane;
go_copy_object( rc_pane2 ) -> blue_zoom_pane;

2 -> go_scale( blue_zoom_pane );
'aquamarine' -> go_bgcolour( blue_zoom_pane );
'blue' -> go_fgcolour( blue_zoom_pane );

;;; Note that the default scales are normally x=1; y=-1; so the new
;;; window might have objects which move in different directions.

/* --------------------------------------------------------------------  *
-- GENERAL METHODS ----------------------------------------------------
 * --------------------------------------------------------------------  */

;;; Other methods are the same as for any object in GO:
;;;       - go_destroy_object()
;;;       - go_xorigin()            (World Coordinates)
;;;       - go_yorigin()            (World Coordinates)
;;;       - go_xcentre()            (World Coordinates)
;;;       - go_ycentre()            (World Coordinates)
;;;       - go_xloc()               (World Coordinates)
;;;       - go_yloc()               (World Coordinates)
;;;       - go_bounding_width()     (World Coordinates)
;;;       - go_bounding_height()    (World Coordinates)
;;;       - go_bounding_box()       (World Coordinates)
;;;       - go_safe_region()        (Screen Coordinates)

;;; Specific methods for panes are:
;;;       - go_window_xloc()        (Screen Coordinates)
;;;       - go_window_yloc()        (Screen Coordinates)
;;;       - go_window_width()       (Screen Coordinates)
;;;       - go_window_height()      (Screen Coordinates)

/* --------------------------------------------------------------------  *
-- DIMENSIONS OF rc_go_window OBJECTS ---------------------------------
 * --------------------------------------------------------------------  */

;;; The location and size of the go_window_pane can normally only be
;;; changed through the manageing widget which is either a go_shell or
;;; a go_rc_window object (which is a special case of a shell).

;;; The rc_go_window objects can be resized as other GO objects. The
;;; bounding box allows you to reset the size of the pane and shell
;;; on the screen. Note however that these are expressed in world
;;; coordinates (therfore the scale is important!).
go_bounding_width( rc_pane ) =>
100 -> go_bounding_width( rc_pane );

;;; The corresponding methods in screen coordinates are:
go_window_width( rc_pane ) =>
100 -> go_window_width( rc_pane );

;;; As you can see the xscale makes the window width different from the
;;; bounding width...

;;; Sometimes you will want to move the location of a pane in the shell
;;; around it. By default however the location is (0,0) i.e. the top left
;;; hand corner:
go_window_xloc( rc_pane ) =>
go_window_yloc( rc_pane ) =>

;;; In a go_shell class you will be able to update these locations (see
;;; TEACH * GO_SHELL), however in the special case of a rc_go_window object
;;; this is not possible!

/* --------------------------------------------------------------------  *
-- DESTROYING A go_pane OBJECT ----------------------------------------
 * --------------------------------------------------------------------  */

;;; The normal go_destroy_object() method applies for go_pane objects.
;;; If the pane is in a go_shell object or a user defined shell, then
;;; only the Graphics pane will dissapear. In the case of a go_rc_window
;;; object the whole rc_window dissapears as well:
go_destroy_object( rc_pane );

;;; A higher level destroy procedure destroys all go_shell and go_pane
;;; objects currently in use (see REF * GO_VARS/go_shells and /go_panes):
go_shells =>
go_panes =>
go_destroy();
;;; eof

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