% This file was created automatically from gobject.msk.
% DO NOT EDIT!
\Chapter{Graphic Sheets - Basic graphic operations}

This chapter describes how graphics are accessed in {\XGAP} via the lowest
library functions for graphic sheets. These functions are used in all other 
parts of {\XGAP} and you normally only need to know them if you want to
display other things than graphic posets and subgroup lattices.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Graphic Sheet Objects}

To access any graphics in {\XGAP} you first have to create a *graphic*
*sheet* object. Such objects are linked internally to windows on the
screen. You do *not* have to think about redrawing, resizing and other
organizing stuff. The graphic sheet object is a {\GAP} object
in the category `IsGraphicSheet' and should be saved because it is needed
later on for all graphic operations.


\>GraphicSheet( <title>, <width>, <height> ) O

creates  a  graphic  sheet with  title  <title> and dimension <width>  by
<height>.  A graphic sheet  is the basic  tool  to draw something,  it is
like a piece of  paper on which you can  put your graphic objects, and to
which you  can attach your  menus.   The coordinate $(0,0)$ is  the upper
left corner, $(<width>-1,<height>-1)$ the lower right.

It is  possible to  change the  default behaviour of   a graphic sheet by
installing methods (or   sometimes  called callbacks) for   the following
events.  In order to  avoid  confusion with  the {\GAP} term  ``method'' the
term ``callback'' will be used in the following.  For example, to install
the function `MyLeftPBDownCallback' as callback for the left mouse button
down  event of a graphic sheet <sheet>,  you have  to call
`InstallCallback' as follows.

\begintt
gap> InstallCallback( sheet, "LeftPBDown", MyLeftPBDownCallback );
\endtt

{\XGAP} stores for each graphic sheet a list of callback keys and a list
of callback functions for each key. That means that when a certain 
callback key is triggered for a graphic sheet then the corresponding
list of callback functions is called one function after the other. The
following keys have predefined meanings which are explained below:
  `Close', `LeftPBDown', `RightPBDown', `ShiftLeftPBDown', 
  `ShiftRightPBDown', `CtrlLeftPBDown', `CtrlRightPBDown'.
All of these keys are strings. You can install your own callback 
functions for new keys, however they will not be triggered automatically.

\>Close( <sheet> )!{Callback}

  the function will be called as soon as the user selects ``close graphic
  sheet'',  the installed  function gets  the graphic sheet <sheet> to
  close as argument.

\>LeftPBDown( <sheet>, <x>, <y> )

  the function will be called as soon as  the user presses the left mouse
  button inside  the   graphic sheet, the  installed   function  gets the
  graphic sheet <sheet>,  the <x> coordinate and  <y> coordinate of the
  pointer as arguments.

\>RightPBDown( <sheet>, <x>, <y> )

  same  as `LeftPBDown' except that the  user has pressed the right mouse
  button.

\>ShiftLeftPBDown( <sheet>, <x>, <y> )

  same  as `LeftPBDown' except that the  user has  pressed the left mouse
  button together with the $SHIFT$ key on the keyboard.

\>ShiftRightPBDown( <sheet>, <x>, <y> )

  same as  `LeftPBDown' except that the  user has pressed the right mouse
  button together with the $SHIFT$ key on the keyboard.

\>CtrlLeftPBDown( <sheet>, <x>, <y> )

  same  as `LeftPBDown' except that the  user has pressed  the left mouse
  button together with the $CTRL$ key on the keyboard.

\>CtrlRightPBDown( <sheet>, <x>, <y> )

  same as `LeftPBDown'  except that the  user has pressed the right mouse
  button together with the $CTRL$ key on the keyboard.



Here is the documentation for the operations to control the callback 
functions:

\>InstallCallback( <sheet>, <key>, <func> ) O

Installs a new callback function for the sheet <sheet> for the key <key>.
Note that the old functions for this key are *not* deleted.


\>RemoveCallback( <sheet>, <func>, <call> ) O

Removes an old callback. Note that you have to specify not only the 
<key> but also explicitly the <func> which should be removed from the 
list!


\>Callback( <sheet>, <key>, <args> ) O

Executes all callback functions of the sheet <sheet> that are stored under
the key <func> with the argument list <args>.



Every graphic object in {\XGAP} can be <alive> or not. This is controlled
by the filter `IsAlive'. Being <alive> means that the object can be used
for further operations. If for example the user closes a window by a 
mouse operation the corresponding graphic sheet object is no longer 
<alive>.


\>IsAlive( <gobj> ) F

This filter controls if a graphic object is <alive>, meaning that it can
be used for further graphic operations.



The following operations apply to graphic sheets:

\>Close( <sheet> ) O

The graphic sheet <sheet> is closed which means that the corresponding
window is closed and the sheet becomes <not alive>.


\>Resize( <sheet>, <width>, <height> ) O

The <width> and <height> of the sheet <sheet> are changed. That does *not* 
automatically mean that the window size is changed. It may also happen
that only the scrollbars are changed.


\>WindowId( <sheet> ) A

Every graphic sheet has a unique number, its <window id>. This is mainly
used internally.


\>SetTitle( <sheet>, <title> ) O

Every graphic sheet has a title which appears somewhere on the window.
It is initially set via the call to the constructor `GraphicSheet' and
can be changed later with this operation.


\>SaveAsPS( <sheet>, <filename> ) O

Saves the graphics in the sheet <sheet> as postscript into the file
<filename>, which is overwritten, if it exists.


\>FastUpdate( <sheet>, <flag> ) O

Switches the `UseFastUpdate' filter for the sheet <sheet> to the
boolean value of <flag>. If this filter is set for a sheet, the screen
is no longer updated completely if a graphic object is moved or
deleted.  You should call `FastUpdate( <sheet>, true )' before you
start large rearrangements of the graphic objects and 
`FastUpdate( <sheet>, false )' at the end.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Graphic Objects in Sheets}

All graphics within graphic sheets are so called graphic objects. They 
are {\GAP} objects in the category `IsGraphicObject'. These objects are
linked internally to the actual graphics within the window. You can 
modify these objects via certain operations which leads to the
corresponding change of the real graphics on the screen. The types of
graphic objects supported in {\XGAP} are: boxes, circles, discs, diamonds,
rectangles, lines, texts, vertices and connections. Vertices are compound
objects consisting of a circle, rectangle oder diamond with a short text
inside. They remember their connections to other vertices. That means
that if for example the position of a vertex is changed, the line which 
makes the connection to some other vertex is also changed automatically.
For every graphic object there is a constructor which has the same name 
as the graphic object (e.g. `Box' is the constructor for boxes).



\>IsGraphicObject( <gobj> ) C

This is the category in which all graphic objects are.



\bigskip%

*Constructors:*

\>Box( <sheet>, <x>, <y>, <w>, <h> ) O
\>Box( <sheet>, <x>, <y>, <w>, <h>, <defaults> ) O

creates a new graphic object,  namely a filled black  box, in the graphic
sheet <sheet> and  returns a {\GAP} record describing  this  object.  The
four   corners     of  the    box    are   $(<x>,<y>)$,  $(<x>+<w>,<y>)$,
$(<x>+<w>,<y>+<h>)$, and $(<x>,<y>+<h>)$.

Note that the box is $<w>+1$ pixel wide and $<h>+1$ pixels high.

If a record <defaults> is given and contains a component `color' of value
<color>, the  function works like the first version  of  `Box', except 
that the color of the box will be <color>.  See "Color Models" for how 
to select a <color>.

See "operations for graphic objects" for a list of operations
that apply to boxes.

Note that `Reshape' for boxes takes three parameters, namely the box
object, the new width, and the new height of the box.


\>Circle( <sheet>, <x>, <y>, <r> ) O
\>Circle( <sheet>, <x>, <y>, <r>, <defaults> ) O

creates a new graphic object, namely a black circle, in the graphic sheet
<sheet> and returns a {\GAP} record describing this object. The center
of the circle is $(<x>,<y>)$ and the radius is $<r>$.

If a record <defaults> is given and contains a component `color' of value
<color>, the  function works like the first version  of  `Circle', except 
that the color of the circle will be <color>.  See "Color Models" for how 
to select a <color>. If the record contains a component `width' of value
<width>, the line width of the circle is set accordingly.

See "operations for graphic objects" for a list of operations
that apply to circles.

Note that `Reshape' for circles takes two parameters, namely the circle
object, and the new radius of the circle.


\>Disc( <sheet>, <x>, <y>, <r> ) O
\>Disc( <sheet>, <x>, <y>, <r>, <defaults> ) O

creates a new graphic object, namely a disc (a black filled circle), 
in the graphic sheet
<sheet> and returns a {\GAP} record describing this object. The center
of the disc is $(<x>,<y>)$ and the radius is $<r>$.

If a record <defaults> is given and contains a component `color' of value
<color>, the  function works like the first version  of  `Disc', except 
that the color of the disc will be <color>.  See "Color Models" for how 
to select a <color>. 

See "operations for graphic objects" for a list of operations
that apply to discs.

Note that `Reshape' for discs takes two parameters, namely the disc
object, and the new radius.


\>Diamond( <sheet>, <x>, <y>, <w>, <h> ) O
\>Diamond( <sheet>, <x>, <y>, <w>, <h>, <defaults> ) O

creates a new graphic object, namely a black diamond, in the graphic sheet
<sheet> and returns a {\GAP} record describing this object. The left
corner of the diamond is $(<x>,<y>)$, the others are $(<x>+<w>,<y>-<h>)$,
$(<x>+<w>,<y>+<h>)$, and $(<x>+2<w>,<y>)$.

If a record <defaults> is given and contains a component `color' of value
<color>, the  function works like the first version  of  `Diamond', except 
that the color of the diamond will be <color>.  See "Color Models" for how 
to select a <color>. If the record contains a component `width' with 
integer value <width>, the line width is set accordingly.

See "operations for graphic objects" for a list of operations
that apply to diamonds.

Note that `Reshape' for diamonds takes three parameters, namely the diamond
object, and the new <width> and <height> values.


\>Rectangle( <sheet>, <x>, <y>, <w>, <h> ) O
\>Rectangle( <sheet>, <x>, <y>, <w>, <h>, <defaults> ) O

creates a new graphic object,  namely a black  rectangle, in the graphic
sheet <sheet> and  returns a {\GAP} record describing  this  object.  The
four   corners     of  the    box    are   $(<x>,<y>)$,  $(<x>+<w>,<y>)$,
$(<x>+<w>,<y>+<h>)$, and $(<x>,<y>+<h>)$.

Note that the rectangle is $<w>+1$ pixel wide and $<h>+1$ pixels high.

If a record <defaults> is given and contains a component `color' of value
<color>, the  function works like the first version  of  `Rectangle', 
except 
that the color of the rectangle will be <color>.  See "Color Models" for 
how 
to select a <color>. If the record contains a component `width' with 
integer value <width>, the line width is set accordingly.

See "operations for graphic objects" for a list of operations
that apply to rectangles.

Note that `Reshape' for rectangles takes three parameters, namely the 
rectangle object, and the new <width> and <height> values.


\>Line( <sheet>, <x>, <y>, <w>, <h> ) O
\>Line( <sheet>, <x>, <y>, <w>, <h>, <defaults> ) O

creates a new graphic object,  namely a black  line, in the graphic
sheet <sheet> and  returns a {\GAP} record describing  this  object.  The
line has the end points $(<x>,<y>)$ and $(<x>+<w>,<y>+<h>)$.

If a record <defaults> is given and contains a component `color' of value
<color>, the  function works like the first version  of  `Line', except 
that the color of the line will be <color>.  See "Color Models" for how 
to select a <color>. If the record contains a component `width' with 
integer value <width>, the line width is set accordingly. If the record
contains a component `label' with a string value <label>, a text object
is attached as a label to the line.

See "operations for graphic objects" for a list of operations
that apply to lines.

Note that `Reshape' for lines takes three parameters, namely the 
line object, and the new <w> and <h> value. `Change' for
lines in contrast takes five parameters, namely the line object and all 
four coordinates like in the original call.


\>Text( <sheet>, <font>, <x>, <y>, <str> ) O
\>Text( <sheet>, <font>, <x>, <y>, <str>, <defaults> ) O

creates a new graphic object, namely the string <str> as a black text,
in the graphic sheet <sheet> and returns a {\GAP} record describing
this object.  The text has the baseline of the first character at
$(x,y)$.

If a record <defaults> is given and contains a component `color' of value
<color>, the  function works like the first version  of  `Text', except 
that the color of the text will be <color>.  See "Color Models" for how 
to select a <color>. 

See "operations for graphic objects" for a list of operations
that apply to texts.

Note that `Reshape' for texts takes two parameters, namely the 
text object, and the new font. Use `Relabel' to change the string of the
text.




\bigskip%

*Operations for graphic objects:*

\>Connection( <vertex>, <vertex> ) O
\>Connection( <vertex>, <vertex>, <defaults> ) O

Connects two vertices with a line.
The second variation can get a <defaults> record for the actual line. The
same entries as in the <defaults> record for lines are allowed.


\>Disconnect( <vertex>, <vertex> ) O

Deletes connection between two vertices.



\>Draw( <object> ) O

This operation (re-)draws a graphic object on the screen. You normally
do not need to call this yourself. But in some rare cases of object
overlaps you could find it useful.


\>`Delete( <sheet>, <object> )'{Delete![gobject]}@{`Delete'!`[gobject]'} O
\>`Delete( <object> )'{Delete![gobject]}@{`Delete'!`[gobject]'} O

Deletes a graphic object. Calls `Destroy' first, so the graphic object
is no more <alive> afterwards. The object is deleted from the list of
objects in its graphic sheet. There is no way to reactivate such an
object afterwards.


\>Destroy( <object> ) O

Destroys a graphic object. It disappears from the screen and will not be 
<alive> any more after this call.
Note that <object> is *not* deleted from the list of objects in its
graphic sheet <sheet>.  
This makes it possible to `Revive' it again.
In order to delete <object> from <sheet>,
use `Delete( <sheet>, <obj> )', which calls `Destroy' for <obj>.


\>Revive( <object> ) O

Note that <object> must be in the list of objects in its graphic sheet!
So this is only possible for `Destroyed', not
for `Deleted' graphic objects.


\>`Move( <object>, <x>, <y> )'{Move![gobject]}@{`Move'!`[gobject]'} O

Changes the position of a graphic object absolutely. It must be <alive>
and will be moved at once on the screen.


\>MoveDelta( <object>, <dx>, <dy> ) O

Changes the position of a graphic object relatively. It must be <alive>
and will be moved at once on the screen.


\>PSString( <object> ) O

Creates a postscript string which describes the graphic object. Normally
you do not need to call this because it is only used internally if the
user exports the whole graphic sheet to encapsulated postscript.


\>PrintInfo( <object> ) O

This operation prints debugging info about a graphic object.


\>`Recolor( <object>, <col> )'{Recolor![gobject]}@{`Recolor'!`[gobject]'} O

Changes the color of a graphic object. See "Color Models" for how 
to select a <color>. 


\>`Reshape( <object>, ... )'{Reshape![gobject]}@{`Reshape'!`[gobject]'} O

Changes the shape of a graphic object. The parameters depend on the type
of the object. See the descriptions of the constructors for the actual
usage.


\>`\\in'{in!for graphic objects}@{`in'!for graphic objects}

This infix operation needs a vector of two integers to its left and a graphic
object to its right (``vector of two integers'' means a list of two
integers e.g. `[15,9]'). It determines, if the position given by the two
integer coordinates is inside (e.g. for boxes) or on (e.g. for lines) the
graphic objects. Returns a boolean value.
\>Change( <object>, ... ) O

Changes the shape of a graphic object. The parameters depend on the type
of the object. See the descriptions of the constructors for the actual
usage.


\>`Relabel( <object>, <str> )'{Relabel![gobject]}@{`Relabel'!`[gobject]'} O

Changes the label of a graphic object. The second argument must always
be a string.


\>`SetWidth( <object>, <w> )'{SetWidth![gobject]}@{`SetWidth'!`[gobject]'} O

Changes the line width of the graphic object. The line width <w> must be
a relatively small integer.


\>`Highlight( <vertex> )'{Highlight![gobject]}@{`Highlight'!`[gobject]'} O
\>`Highlight( <vertex>, <flag> )'{Highlight![gobject]}@{`Highlight'!`[gobject]'} O

In the first form this operation switches the highlighting status of a
vertex to ON. In the second form the <flag> decides about ON or OFF.
Highlighting normally means a thicker line width and a change in color.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Colors in XGAP}

\label{Color Models}

Depending on the type of display you are using, there may be more or
fewer colors available. You should write your programs always such that
they work even on monochrome displays. In {\XGAP} these differences can
be read off from the so called ``color model''. The global variable
`COLORS' contains all available information.


\>`COLORS' V

The variable  `COLORS' contains a list  of available colors.  If an entry
is `false' this  color is not available  on your screen.  Possible colors
are: `"black"', `"white"', `"lightGrey"', `"dimGrey"', `"red"', `"blue"',
and `"green"'.

The  following example opens   a new graphic sheet  (see "GraphicSheet"),
puts  a black box (see  "Box") onto it and  changes its color.  Obviously
you need a color display for this example.

\begintt
gap> sheet := GraphicSheet( "Nice Sheet", 300, 300 );
<graphic sheet "Nice Sheet">
gap> box := Box( sheet, 10, 10, 290, 290 );
<box>
gap> Recolor( box, COLORS.green );
gap> Recolor( box, COLORS.blue );
gap> Recolor( box, COLORS.red );
gap> Recolor( box, COLORS.lightGrey );
gap> Recolor( box, COLORS.dimGrey );
gap> Close(sheet);
\endtt

The component `model' is always a string. It is `monochrome', if the 
display does not support colors. It is `gray' if we only have gray shades
and `colorX' if we have colors. The ``X'' can be either 3 or 5, depending
on how many colors are available.




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Operations for Graphic Objects}

The following table gives an overview over the supported graphic objects and 
the functions which are applicable respectively:

Here are the supported graphic object types: `Box', `Circle', `Disc', 
`Diamond', `Rectangle', `Line', `Text', `Vertex'.

These functions apply to all graphic object types:
`Draw', `Delete', `Destroy', `Revive', `Move', `MoveDelta', `PSString',
`PrintInfo', `ViewObj', `Recolor', `Reshape', `\\in', `WindowId'

In addition, the operation `Relabel' applies to objects of types `Line',
`Text', and `Vertex'; the operation `SetWidth' applies to objects of types
`Diamond', `Rectangle', `Circle', and `Line'. There is also `Change' for a
`Line' and `Highlight' for a `Vertex'.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Global Information}

There are some global data structures which can and should be consulted if 
certain information is needed. The first (about color handling) was already 
described in section "Color Models". The second is for vertices:

\>`VERTEX'{VERTEX!record}@{`VERTEX'!record} V

  This globally bound record contains the following components:

\beginitems
`circle' & integer value for the vertex type ``circle''

`diamond' & integer value for the vertex type ``diamond''

`rectangle' & integer value for the vertex type ``rectangle''

`radius' & radius in pixels of a vertex on the screen

`diameter' & diameter in pixels of a vertex on the screen
\enditems

\bigskip%

The third structure is about the available fonts. 

\>`FONTS' V

This globally bound record has the following components: `tiny', `small', 
`normal', `large', `huge' and `fonts'. The first 5 are itself records each
for one available font. They have components `name' for the name of the font
and `fontInfo', which is a list of 3 integers. The first is the maximal size
of a character above the baseline in pixels, the second is the maximal size
of a character below the baseline in pixels, and the third is the width
in pixels of *all* characters, because it is always assumed, that the
fonts are non-proportional.

\>FontInfo( <font> ) O

Returns the information about the font <font>. The result is a triple
of integers. The first number is the maximal size
of a character above the baseline in pixels, the second is the maximal size
of a character below the baseline in pixels, and the third is the width
in pixels of *all* characters, because it is always assumed, that the
fonts are non-proportional. Use this function rather than accessing
the component `fontInfo' of a font object directly!



\bigskip%

There is another global structure:

\>`BUTTONS' V

This record contains the following components: `left' and `right' contain a
number for the left resp. right mouse button. `shift' and `ctrl' contain
codes for the respective keys on the keyboard.

\bigskip%

You should always use these global data instead of hardwiring any integers into
your code.
