{Begin SubSec Interactive Display Functions} {Title Interactive Display Functions} {Text The following functions allow the user to interactively specify positions or regions on the display screen. {FnDef {Name GETPOSITION} {Args WINDOW CURSOR} {Text Returns a {lisp POSITION} that is specified by the user. {fn GETPOSITION} waits for the user to press and release the left button of the mouse and returns the cursor position at the time of release. If {arg WINDOW} is a {lisp WINDOW}, the position will be in the coordinate system of {arg WINDOW}'s display stream. If {arg WINDOW} is {lisp NIL}, the position will be in screen coordinates. If {arg CURSOR} is a {lisp CURSOR}, the cursor will be changed to it while {fn GETPOSITION} is running. If {arg CURSOR} is {lisp NIL}, the value of the system variable {var CROSSHAIRS}{index CROSSHAIRS Var} will be used as the cursor. }} {FnDef {Name GETBOXPOSITION} {Args WIDTH HEIGHT ORGX ORGY WINDOW PROMPTMSG} {Text Allows the user to position a "ghost" region of size {arg WIDTH} by {arg HEIGHT} on the screen, and returns the {lisp POSITION} of the lower left corner of the region. If {arg PROMPTMSG} is non-{lisp NIL}, {Fn GETBOXPOSITION} first prints it in the {var PROMPTWINDOW}. {Fn GETBOXPOSITION} then changes the cursor to a box (using the global variable {index BOXCURSOR Var}{var BOXCURSOR}). If {arg ORGX} and {arg ORGY} are numbers, they are taken to be the original position of the region, and the cursor is moved to the nearest corner of that region. A ghost region is locked to the cursor so that if the cursor is moved, the ghost region moves with it. If {arg ORGX} and {arg ORGY} are numbers, the corner of the region formed by ({arg ORGX} {ARG ORGY} {ARG WIDTH} {ARG HEIGHT}) that is nearest the cursor position is locked, otherwise the lower left corner is locked. The user can change to another corner by holding down the right button. With the right button down, the cursor can be moved across the screen without effect on the ghost region frame. When the right button is released, the mouse will snap to the nearest corner, which will then become locked to the cursor. (The held corner can be changed after the left or middle button is down by holding both the original button and the right button down while the cursor is moved to the desired new corner, then letting up just the right button.) When the left or middle button is pressed and released, the lower left corner of the region at the time of release is returned. If {arg WINDOW} is a {lisp WINDOW}, the returned position will be in {arg WINDOW}'s coordinate system; otherwise it will be in screen coordinates. Example: {lispcode (GETBOXPOSITION 100 200 NIL NIL NIL "Specify the position of the command area.")} prompts the user for a 100 wide by 200 high region and returns its lower left corner in screen coordinates. }} {FnDef {Name GETREGION} {Args MINWIDTH MINHEIGHT INITREGION NEWREGIONFN NEWREGIONFNARG} {Text Lets the user specify a new region and returns that region in screen coordinates. {fn GETREGION} prompts for a region by displaying a four-pronged box next to the cursor arrow at one corner of a "ghost" region. If the user presses the left button, the corner of a "ghost" region opposite the cursor is locked where it is. Once one corner has been fixed, the ghost region expands as the cursor moves. To specify a region: (1) Move the ghost box so that the corner opposite the cursor is at one corner of the intended region. (2) Press the left button. (3) Move the cursor to the position of the opposite corner of the intended region while holding down the left button. (4) Release the left button. Before one corner has been fixed, one can switch the cursor to another corner of the ghost region by holding down the right button. With the right button down, the cursor changes to a "forceps" and the cursor can be moved across the screen without effect on the ghost region frame. When the right button is released, the cursor will snap to the nearest corner of the ghost region. After one corner has been fixed, one can still switch to another corner. To change to another corner, continue to hold down the left button and hold down the right button also. With both buttons down, the cursor can be moved across the screen without effect on the ghost region frame. When the right button is released, the cursor will snap to the nearest corner, which will become the moving corner. In this way, the region may be moved all over the screen, before its size and position is finalized. The size of the initial ghost region is controlled by the {arg MINWIDTH}, {arg MINHEIGHT} and {arg INITREGION} arguments. The ghost region will be {arg MINWIDTH} wide and {arg MINHEIGHT} high. If {arg MINWIDTH} or {arg MINHEIGHT} is {lisp NIL}, 0 is used. Thus, for a call to {lisp GETREGION} with no arguments specified, there will be no initial ghost region. The cursor will be in the lower right corner of the region, if there is one. If {arg INITREGION} is a {lisp REGION} and the user presses the middle button, the corner of {arg INITREGION} farthest from the cursor position is fixed and the corner nearest the cursor is locked to the cursor. {arg MINWIDTH} and {arg MINHEIGHT}, if given, are the smallest {lisp WIDTH} and {lisp HEIGHT} that the returned region will have. The ghost image will not get any smaller than {arg MINWIDTH} by {arg MINHEIGHT}. If {arg NEWREGIONFN} is non-{lisp NIL}, it will be called to determine values for the positions of the corners. This provides a way of "filtering" prospective regions; for instance, by restricting the region to lie on an arbitrary grid. When the user is specifying a region, the region is determined by two of its corners, one that is fixed and one that is tracking the cursor. Each time the cursor moves or a mouse button is pressed, {arg NEWREGIONFN} is called with three arguments: {arg FIXEDPOINT}, the position of the fixed corner of the prospective region; {arg MOVINGPOINT}, the position of the opposite corner of the prospective region; and {arg NEWREGIONFNARG}. {arg NEWREGIONFNARG} allows the caller of {fn GETREGION} to pass information to the {arg NEWREGIONFN}. The first time a button is pressed and when the user changes the moving corner via right buttoning, {arg MOVINGPOINT} is {lisp NIL} and {arg FIXEDPOINT} is the position the user selected for the fixed corner of the new region. In this case, the position returned by {arg NEWREGIONFN} will be used for the fixed corner instead of the one proposed by the user. For all other calls, {arg FIXEDPOINT} is the position of the fixed corner (as returned by the previous call) and {arg MOVINGPOINT} is the new position the user selected for the opposite corner. In these cases, the value of {arg NEWREGIONFN} is used for the opposite corner instead of the one proposed by the user. In all cases, the ghost region is drawn with the values returned by {arg NEWREGIONFN}. {arg NEWREGIONFN} can be a list of functions in which case they are called in order with each being passed the result of calling the previous and the value of the last one used as the point. }} {FnDef {Name GETBOXREGION} {Args WIDTH HEIGHT ORGX ORGY WINDOW PROMPTMSG} {Text Performs the same prompting as {fn GETBOXPOSITION} and returns the {lisp REGION} specified by the user instead of the {lisp POSITION} of its lower left corner. }} }{End SubSec Interactive Display Functions} {Begin SubSec Menus} {Title Menus} {Text A menu is basically a means of selecting from a list of items. The system provides common layout and interactive user selection mechanisms, then calls a user-supplied function when a selection has been confirmed. The two major constituents of a menu are a list of items and a "when selected function." The label that appears for each item is the item itself for non-lists, or its {lisp CAR} if the item is a list. In addition, there are a multitude of different formatting parameters for specifying font, size, and layout. When a menu is created, its unspecified fields are filled with defaults and its screen image is computed and saved. Menus can be either pop up or fixed. If fixed menus are used, the menu must be included in a window. {FnDef {Name MENU} {Args MENU POSITION RELEASECONTROLFLG} {Text This function provides menus that pop up when they are used. It displays {arg MENU} at {arg POSITION} (in screen coordinates) and waits for the user to select an item with a mouse key. Before any mouse key is pressed, the item the mouse is over is boxed. After any key is down, the selected menu item is video reversed. When all keys are released, {arg MENU}'s {lisp WHENSELECTEDFN} field is called with four arguments: (1) the item selected, (2) the menu, (3) the last mouse key released ({lisp LEFT}, {lisp MIDDLE}, or {lisp RIGHT}), and (4) the reverse list of superitems rolled through when selecting the item and {fn MENU} returns its value. If no item is selected, {fn MENU} returns {lisp NIL}. If {arg POSITION} is {lisp NIL}, the menu is brought up at the value from {arg MENU}'s {lisp MENUPOSITION} field, if it is a {lisp POSITION}, or at the current cursor position. The orientation of {arg MENU} with respect to the specified position is determined by its {lisp MENUOFFSET} field. If {arg RELEASECONTROLFLG} is {lisp NIL}, this process will retain control of the mouse. In this case, if the user lets the mouse key up outside of the menu, {lisp MENU} return {lisp NIL}. (Note: this is the standard way of allowing the user to indicate that they do not want to make the offered choice.) If {arg RELEASECONTROLFLG} is non-{lisp NIL}, this process will give up control of the mouse when it is outside of the menu so that other processes can be run. In this case, clicking outside the menu has no effect on the call to {lisp MENU}. If the menu is closed (for example, by right buttoning in it and selecting "{lisp Close}" from the window menu), {lisp MENU} returns {lisp NIL}. Programmers are encouraged to provide a menu item such as "cancel" or "abort" which gives users a positive way of indicating "no choice". }} {FnDef {Name ADDMENU} {Args MENU WINDOW POSITION DONTOPENFLG} {Text This function provides menus that remain active in windows. {fn ADDMENU} displays {arg MENU} at {arg POSITION} in {arg WINDOW} ({arg POSITION} is defaulted as in {fn MENU} except that it is in window coordinates). {arg MENU} is added to the {lisp MENU} property of {arg WINDOW}. The {lisp CURSORINFN} and {lisp BUTTONEVENTFN} of {arg WINDOW} are replaced with {fn MENUBUTTONFN},{index MENUBUTTONFN Fn} so that {arg MENU} will be active. {lisp RESHAPEFN} of {arg WINDOW} is set to restore {arg MENU}'s image when the window is reshaped. {fn MENUREPAINTFN} is added as a {lisp REPAINTFN} on {arg WINDOW} to update the menu image if the window is redisplayed. When an item is selected, the value of the {lisp WHENSELECTEDFN} field of {arg MENU} is called with three arguments: (1) the item selected, (2) the menu, and (3) the mouse key that the item was selected with ({lisp LEFT}, {lisp MIDDLE}, or {lisp RIGHT}). If the {lisp WHENSELECTEDFN} of {arg MENU} is {lisp NIL}, it will be set to {fn BACKGROUNDWHENSELECTEDFN} which calls {fn EVAL.AS.PROCESS} ({PageRef Fn EVAL.AS.PROCESS}) instead of {fn EVAL}. More than one menu can be put in a window, but a menu can only be added to one window at a time. If {arg WINDOW} is not given, a window is created at {arg POSITION} (in screen coordinates) that is the size of {arg MENU}. If a window is created, it will be opened unless {arg DONTOPENFLG} is non-{lisp NIL}. {fn ADDMENU} returns the window into which {arg MENU} is placed. {fn ADDMENU} uses the following window properties: {lisp MENU}, {lisp REPAINTFN}, {lisp CURSORMOVEDFN}, {lisp BUTTONEVENTFN} and {lisp CURSORINFN}. }} {FnDef {Name DELETEMENU} {Args MENU CLOSEFLG FROMWINDOW} {Text This function removes {arg MENU} from the window {arg FROMWINDOW}. If {arg MENU} is the only menu in the window and {arg CLOSEFLG} is non-{lisp NIL}, its window will be closed (by {fn CLOSEW}). If {arg FROMWINDOW} is {lisp NIL}, the list of currently open windows is searched for one that contains {arg MENU}. If none is found, {fn DELETEMENU} does nothing. }} {note examples!! (with figures if possible)} {Begin SubSec Menu Fields} {Title Menu Fields} {Text A menu is a datatype with the following fields: {Def {Type (Menu Field)} {Name ITEMS} {Text The list of items to appear in the menu. If an item is a list, its {lisp CAR} will appear in the menu. If the item (or its {lisp CAR}) is a bitmap, the bitmap will be displayed in the menu. The default selection functions interpret each item as a list of three elements: a label, a form whose value is returned upon selection, and a help string that is printed in the prompt window when the user presses a mouse key with the cursor pointing to this item. The default subitem function interprets the fourth element of the list. If it is a list whose {lisp CAR} is the atom SUBITEMS {index SUBITEMS}, the {lisp CDR} is taken as a list of subitems. }} {Def {Type (Menu Field)} {Name SUBITEMFN} {Text A function to be called to determine if an item has any subitems. If an item has subitems and the user rolls the cursor out the right of that item, a submenu with that item's subitems in it pops up. If the user selects one of the items from the submenu, the selected subitem is handled as if it were selected from the main menu. If the user rolls out of the submenu to the left, the submenu is taken down and selection resumes from the main menu. An item with subitems is marked in the menu by a grey, right pointing triangle following the label. The function is called with two arguments: (1) the menu and (2) the item. It should return a list of the subitems of this item if any. (Note: it is called twice to compute the menu image and each time the user rolls out of the item box so it should be moderately efficient. The default {lisp SUBITEMFN}, {fn DEFAULTSUBITEMFN},{index DEFAULTSUBITEMFN Fn} checks to see if the item is a list whose fourth element is a list whose {fn CAR} is {lisp SUBITEMS} and if so, returns the {fn CDR} of it. For example: {lispcode (create MENU ITEMS _ '(A (B 'B "help string for B" (SUBITEMS B1 B2 B3))))} will create a menu with items {lisp A} and {lisp B} in which {lisp B} will have subitems {lisp B1}, {lisp B2} and {lisp B3}. }} {Def {Type (Menu Field)} {Name WHENSELECTEDFN} {Text A function to be called when an item is selected. The function is called with three arguments: (1) the item selected, (2) the menu, and (3) the mouse key that the item was selected with ({lisp LEFT}, {lisp MIDDLE}, or {lisp RIGHT}). The default function {fn DEFAULTWHENSELECTEDFN}{index DEFAULTWHENSELECTEDFN Fn} evaluates and returns the value of the second element of the item if the item is a list of at least length 2. If the item is not a list of at least length 2, {fn DEFAULTWHENSELECTEDFN} returns the item. }} {Def {Type (Menu Field)} {Name WHENHELDFN} {Text The function which is called when the user has held a mouse key on an item for {var MENUHELDWAIT}{index MENUHELDWAIT Var} milliseconds (initially 1200). The function is called with three arguments: (1) the item selected, (2) the menu, and (3) the mouse key that the item was selected with ({lisp LEFT}, {lisp MIDDLE}, or {lisp RIGHT}). {lisp WHENHELDFN} is intended for prompting users. The default is {fn DEFAULTMENUHELDFN}{index DEFAULTMENUHELDFN Fn} which prints (in the prompt window) the third element of the item or, if there is not a third element, the string "This item will be selected when the button is released." }} {Def {Type (Menu Field)} {Name WHENUNHELDFN} {Text If {lisp WHENHELDFN} was called, {lisp WHENUNHELDFN} will be called: (1) when the cursor leaves the item, (2) when a mouse key is released, or (3) when another key is pressed. The function is called with the same three argument values used to call {lisp WHENHELDFN}. The default {lisp WHENUNHELDFN} is the function {fn CLRPROMPT} ({PageRef Fn CLRPROMPT}), which just clears the prompt window. }} {Def {Type (Menu Field)} {Name MENUPOSITION} {Text The position of the menu to be used if the call to {fn MENU} or {fn ADDMENU} does not specify a position. For popup menus, this is in screen coordinates. For fixed menus, it is in the coordinates of the window the menu is in. The point within the menu image that is placed at this position is determined by {lisp MENUOFFSET}. If {lisp MENUPOSITION} is {lisp NIL}, the menu will be brought up at the cursor position.{note awk.} }} {Def {Type (Menu Field)} {Name MENUOFFSET} {Text The position in the menu image that is to be located at {lisp MENUPOSITION}. The default offset is (0,0). For example, to bring up a menu with the cursor over a particular menu item, set its {lisp MENUOFFSET} to a position within that item and set its {lisp MENUPOSITION} to {lisp NIL}.{note awk.} }} {Def {Type (Menu Field)} {Name MENUFONT} {Text The font in which the items will be appear in the menu. Default is the value of {var MENUFONT}{index MENUFONT Var}, initially Helvetica 10. }} {Def {Type (Menu Field)} {Name TITLE} {Text If non-{lisp NIL}, the value of this field will appear as a title in a line above the menu. }} {Def {Type (Menu Field)} {Name MENUTITLEFONT} {Text The font in which the title of the menu will be appear. If this is {lisp NIL}, the title will be in the same font as window titles. If it is {lisp T}, it will be in the same font as the menu items. }} {Def {Type (Menu Field)} {Name CENTERFLG} {Text If non-{lisp NIL}, the menu items are centered; otherwise they are left-justified. }} {Def {Type (Menu Field)} {Name MENUROWS}} {Def {Type (Menu Field)} {Name MENUCOLUMNS} {Text These fields control the shape of the menu in terms of rows and columns. If {lisp MENUROWS} is given, the menu will have that number of rows. If {lisp MENUCOLUMNS} is given, the menu will have that number of columns. If only one is given, the other one will be calculated to generate the minimal rectangular menu. (Normally only one of {lisp MENUROWS} or {lisp MENUCOLUMNS} is given.) If neither is given, the items will be in one column. }} {Def {Type (Menu Field)} {Name ITEMHEIGHT} {Text The height of each item box in the menu. If not specified, it will be the maximum of the height of the {lisp MENUFONT} and the heights of any bitmaps appearing as labels. }} {Def {Type (Menu Field)} {Name ITEMWIDTH} {Text The width of each item box in the menu. If not specified, it will be the width of the largest item in the menu. }} {Def {Type (Menu Field)} {Name MENUBORDERSIZE} {Text The size of the border around each item box. If not specified, 0 (no border) is used. }} {Def {Type (Menu Field)} {Name MENUOUTLINESIZE} {Text The size of the outline around the entire menu. If not specified, a maximum of 1 and the {lisp MENUBORDERSIZE} is used. }} {Def {Type (Menu Field)} {Name CHANGEOFFSETFLG} {Text (popup menus only) If {lisp CHANGEOFFSETFLG} is non-{lisp NIL}, the position of the menu offset is set each time a selection is confirmed so that the menu will come up next time in the same position relative to the cursor. This will cause the menu to reappear in the same place on the screen if the cursor has not moved since the last selection. This is implemented by changing the {lisp MENUOFFSET} field on each use. If {lisp CHANGEOFFSETFLG} is the atom {lisp X} or the atom {lisp Y}, only the X or the Y coordinate of the {lisp MENUOFFSET} field will be changed. For example, by setting the {lisp MENUOFFSET} position to (-1,0) and setting {lisp CHANGEOFFSETFLG} to {lisp Y}, the menu will pop up so that the cursor is just to the left of the last item selected. This is the setting of the window command menus. }} The following fields are read only. {Def {Type (Menu Field)} {Name IMAGEHEIGHT} {Text Returns the height of the entire menu. }} {Def {Type (Menu Field)} {Name IMAGEWIDTH} {Text Returns the width of the entire menu. }} }{End SubSec Menu Fields} {Begin SubSec Miscellaneous Menu Functions} {Title Miscellaneous Menu Functions} {Text {FnDef {Name MAXMENUITEMWIDTH} {Args MENU} {Text Returns the width of the largest menu item label in the menu {arg MENU}. }} {FnDef {Name MAXMENUITEMHEIGHT} {Args MENU} {Text Returns the height of the largest menu item label in the menu {arg MENU}. }} {FnDef {Name MENUREGION} {Args MENU} {Text Returns the region covered by the image of {arg MENU} in its window. }} {FnDef {Name WFROMMENU} {Args MENU} {Text Returns the window {arg MENU} is located in, if it is in one; {lisp NIL} otherwise. }} {FnDef {Name DOSELECTEDITEM} {Args MENU ITEM BUTTON} {Text Calls {arg MENU}'s {lisp WHENSELECTEDFN} on {arg ITEM} and {arg BUTTON}. It provides a programmatic way of making a selection. It does not change the display. }} {FnDef {Name MENUITEMREGION} {Args ITEM MENU} {Text Returns the region occupied by {arg ITEM} in {arg MENU}. }} {FnDef {Name SHADEITEM} {Args ITEM MENU SHADE DS/W} {Text Shades the region occupied by {arg ITEM} in {arg MENU}. If {arg DS/W} is a display stream or a window, it is assumed to be where {arg MENU} is displayed. Otherwise, {fn WFROMMENU} is called to locate the window {arg MENU} is in. Shading is persistent, and is reapplied when the window the menu is in gets redisplayed. To unshade an item, call with a {arg SHADE} of 0. }} }{End SubSec Miscellaneous Menu Functions} {Begin SubSec Examples of Menu Use} {Title Examples of Menu Use} {Text {lispcode (MENU (create MENU ITEMS _ '((YES T) (NO (QUOTE NIL))) ))} Creates a menu with items {lisp YES} and {lisp NO} in a single vertical column. If {lisp YES} is selected, {lisp T} will be returned. Otherwise, {lisp NIL} will be returned. {lispcode (MENU (create MENU TITLE _ "Foo?" ITEMS _ '((YES T "Adds the Foo feature.") (NO 'NO "Removes the Foo feature.")) CENTERFLG _ T))} Creates a menu with a title {lisp Foo?} and items {lisp YES} and {lisp NO} centered in a single vertical column. The strings following the {lisp YES} and {lisp NO} are help strings and will be printed if the cursor remains over one of the items for a period of time. This menu differs from the one above in that it distinquishes the {lisp NO} case from the case where the user clicked outside of the menu. If the user clicks outside of the menu, {lisp NIL} is returned. {LispCode (create MENU ITEMS _ '(1 2 3 4 5 6 7 8 9 * 0 #) CENTERFLG _ T MENUCOLUMNS _ 3 MENUFONT _ (FONTCREATE 'HELVETICA 10 'BOLD) ITEMHEIGHT _ 15 ITEMWIDTH _ 15 CHANGEOFFSETFLG _ T)} Creates a touch-tone-phone number pad with the items in 15 by 15 boxes printed in Helvetica 10 bold font. If used in pop up mode, its first use will have the cursor in the middle. Subsequent use will have the cursor in the same relative location as the previous selection. {LispCode (SELECTQ [MENU (COND ((type? MENU FOOMENU) {it (* use previously computed menu.)} FOOMENU) (T {it (* create and save the menu)} (SETQ FOOMENU (create MENU ITEMS _ '((A 'A-SELECTED "prompt string for A") (B 'B-SELECTED "prompt string for B"] (A-SELECTED {it (* if A is selected)} (DOATHING)) (B-SELECTED {it (* if B is selected)} (DOBTHING)) (PROGN {it (* user selected outside the menu)} NIL)))} This expression displays a pop up menu with two items, {lisp A} and {lisp B}, and waits for the user to select one. If {lisp A} is selected, {lisp DOATHING} is called. If {lisp B} is selected, {lisp DOBTHING} is called. If neither of these is selected, the form returns {lisp NIL}. The purpose of this example is to show some good practices to follow when using menus. First, the menu is only created once, and saved in the variable {lisp FOOMENU}. This is more efficient if the menu is used more than once. Second, all of the information about the menu is kept in one place, which makes it easy to understand and edit. Third, the forms evaluated as a result of selecting something from the menu are part of the code and hence will be known to masterscope (as opposed to the situation if the forms were stored as part of the items). Fourth, the items in the menu have help strings for the user. Finally, the code is commented (always worth the trouble). {note more examples!} }{End SubSec Examples of Menu Use} }{End SubSec Menus} {Begin SubSec Grid Functions} {Title Grid Functions} {Text A Grid is a partitioning of an arbitrary coordinate system (hereafter referred to as the "source system") into rectangles. This subsection describes functions that operate on Grids. It includes functions to draw the outline of a Grid, to translate between positions in a source system and Grid coordinates (the coordinates of the rectangle which contains a given position), and to shade Grid rectangles. A Grid is defined by its "unit grid", a region (called a GridSpec) which is the origin rectangle of the Grid in terms of the source system. Its {lisp LEFT} is the X-coordinate of the left edge of the origin rectangle, its {lisp BOTTOM} is the Y-coordinate of the bottom edge of the origin rectangle, its {lisp WIDTH} is the width of the grid rectangles, and its {lisp HEIGHT} is the height of the grid rectangles. {FnDef {Name GRID} {Args GRIDSPEC UNITSWIDE UNITSHIGH GRIDBORDER DISPLAYSTREAM GRIDSHADE} {Text Outlines the grid defined by {arg GRIDSPEC} which is {arg UNITSWIDE} rectangles wide and {arg UNITSHIGH} rectangles high on {arg DISPLAYSTREAM}. Each box in the grid has a border within it that is {arg GRIDBORDER} points on each side; so the resulting lines in the grid are 2*{arg GRIDBORDER} thick. If {arg GRIDBORDER} is the atom {lisp POINT}, instead of a border the lower left point of each grid rectangle will be turned on. If {arg GRIDSHADE} is non-{lisp NIL}, it should be a texture and the border lines will be drawn in that shade. }} {FnDef {Name SHADEGRIDBOX} {Args X Y SHADE OPERATION GRIDSPEC GRIDBORDER DISPLAYSTREAM} {Text Shades the grid rectangle ({arg X},{arg Y}) of {arg GRIDSPEC} with texture {arg SHADE} using {arg OPERATION} on {arg DISPLAYSTREAM}. {arg GRIDBORDER} is interpreted the same as for {fn GRID}. }} The following two functions map from the X,Y coordinates of the source system into the Grid X,Y coordinates: {FnDef {Name GRIDXCOORD} {Args XCOORD GRIDSPEC} {Text Returns the Grid X-coordinate (in the Grid specified by {arg GRIDSPEC}) that contains the source system X-coordinate {arg XCOORD}. }} {FnDef {Name GRIDYCOORD} {Args YCOORD GRIDSPEC} {Text Returns the Grid Y-coordinate (in the Grid specified by {arg GRIDSPEC}) that contains the source system Y-coordinate {arg YCOORD}. }} The following two functions map from the Grid X,Y coordinates into the X,Y coordinates of the source system: {FnDef {Name LEFTOFGRIDCOORD} {Args GRIDX GRIDSPEC} {Text Returns the source system X-coordinate of the left edge of a Grid rectangle at Grid X-coordinate {arg GRIDX} (in the Grid specified by {arg GRIDSPEC}). }} {FnDef {Name BOTTOMOFGRIDCOORD} {Args GRIDY GRIDSPEC} {Text Returns the source system Y-coordinate of the bottom edge of a Grid rectangle at Grid Y-coordinate {arg GRIDY} (in the Grid specified by {arg GRIDSPEC}). }} }{End SubSec Grid Functions} l!GACHA l!z¸