|
|
|
|
||
|
DEFINITION MODULE DMWindIO; (******************************************************************* Module DMWindIO ('Dialog Machine' DM_V3.0) Copyright (c) 1985-2006 by Andreas Fischlin, Alex Itten and ETH Zurich. Purpose Provides routines for window related input and output on behalf of a 'Dialog Machine' program. Remarks Method: This module supports mouse input, (object selection, dragging), scrolling (clicking the mouse within particular regions of the scrollbar) text output (pen positioning with cardinal numbers), pixel graphics (pen positioning with integer numbers), turtle graphics, and graphics output via so-called user coordinates (pen positioning with real numbers) within windows as managed by module DMWindows. There exists in fact just one pen while making output within the working area of a window. The various coordinate systems (see below) are provided just for the application programmer's convenience. This module belongs to the 'Dialog Machine'. Programming o Design Andreas Fischlin 16/12/1985 o Implementation Andreas Fischlin 16/12/1985 Alex Itten 22/12/1986 ETH Zurich Systems Ecology CHN E 35.1 Universitaetstrasse 16 8092 Zurich SWITZERLAND URLs: <mailto:RAMSES@env.ethz.ch> <http://www.sysecol.ethz.ch> <http://www.sysecol.ethz.ch/SimSoftware/RAMSES> Last revision of definition: 27/04/1993 AF *******************************************************************) FROM DMWindows IMPORT Window, RectArea, RestoreProc; FROM SYSTEM IMPORT BYTE, ADDRESS; (***********************************************) (*##### Object selection and dragging #####*) (***********************************************) (* Notes: The following procedures work only in the current front window. A double click is defined as a click which has occurred within a certain time span elapsed since the last time the mouse button has been released (can be adjusted by the user via the control panel). A double click always implies a single mouse click. Note that every click, in particular also the first click of a double click, will result in an user event. This means that in case of a double click DMMaster will call the installed MouseHandler for a WindowContent event twice, i.e. first for the first click, second for the succeeding second click (the double click). Routines testing for a single mouse click will always return TRUE for the first, those testing the double click will return TRUE only at the second click. Hence your application must always treat the double click in a way which implies a preceeding single mouse click. E.g. treat an object as selected and invert it upon first click always and if the next click is a double click (it comes quickly enough and approximately at the same location (within ±3 pixels)) open the currently selected object. In case you support double clicks and dragging you should always call the procedure Drag as soon you have detected a single mouse click. Whether you have actually dragged can be found out by setting a «has been dragged» flag in the afterDragP procedure, which will be never called in case the user has not actually dragged. The Dialog Machine detects the intent of the user to drag by observing the mouse movements and assumes that the user did not drag if he releases the mouse button still within ±3 pixels of the vicinity of the last mouse click. *) TYPE MouseModifiers = (ordinary, (*mouse button only*) cmded, (*Command key pressed also*) opted, (*Option key pressed also*) shifted, (*Shift key pressed also*) capsLock, (*Caps Lock key pressed also*) controlled); (*Control key pressed also*) ClickKind = SET OF MouseModifiers; DragProc = PROCEDURE (INTEGER, INTEGER); PROCEDURE PointClicked(x,y: INTEGER; maxDist: INTEGER): BOOLEAN; (* Tests whether the mouse has been clicked within distance maxDist from point (x,y) in cartesian (pixel) coordinates of the currently active window. This procedure returns true only once; it will return false after having reported true until the event occurs anew. Implementation restriction: maxDist must be < 256! *) PROCEDURE RectClicked(rect: RectArea): BOOLEAN; (* Tests whether the mouse has been clicked within the rectangle rect with lower left corner at (rect.x,rect.y), width rect.w, and height rect.h in cartesian (pixel) coordinates of the currently active window. This procedure returns true only once; it will return false after having reported true until the event occurs anew. *) PROCEDURE PointDoubleClicked(x,y: INTEGER; maxDist: INTEGER): BOOLEAN; (* Tests whether the mouse has been clicked twice in short sequence (actual time determined by desk accesory "Control Panel") within distance maxDist from point (x,y) in cartesian (pixel) coordinates of the currently active window. This procedure returns true only once; it will return false after having reported true until the event occurs anew. Implementation restriction: maxDist must be < 256! *) PROCEDURE RectDoubleClicked(rect: RectArea): BOOLEAN; (* Tests whether the mouse has been clicked twice in short sequence (actual time determined by desk accesory "Control Panel") within the rectangle rect with lower left corner at (rect.x,rect.y), width rect.w, and height rect.h in cartesian (pixel) coordinates of the currently active window. This procedure returns true only once; it will return false after having reported true until the event occurs anew. *) PROCEDURE GetLastClick(VAR x,y: INTEGER; VAR click: ClickKind): BOOLEAN; (* Get position of last single click within currently active window content in cartesian (pixel) coordinates. The variable click indicates whether a modifying key (e.g. shift, option, or command) has been pressed simultaneously with the double click. This procedure returns correct values only once; it will destroy this information and can return correct values only if the mouse is clicked again. NOTE: This procedure returns TRUE only if the last click was not a double click, i.e. was either the first click of a double click or any other single click. *) PROCEDURE GetLastDoubleClick(VAR x,y: INTEGER; VAR click: ClickKind): BOOLEAN; (* Get position of last double click (shortly after and in vicinity of previous click) within currently active window content in cartesian (pixel) coordinates. The variable click indicates whether a modifying key (e.g. shift, option, or command) has been pressed simultaneously with the double click. This procedure returns correct values only once; it will destroy this information and can return correct values only if the mouse is clicked again. NOTE: This procedure returns TRUE only if the last click was really a double click, i.e. was the second click of a double click. *) PROCEDURE GetCurMousePos(VAR x,y: INTEGER); (* Get current mouse position in cartesian (pixel) coordinates of the current output window (Note: This procedure does not return the coordinates where the mouse has been clicked, but where it is right now! Hence, a typical usage is from within a drag procedure. *) PROCEDURE GetLastMouseClick(VAR x,y: INTEGER; VAR click: ClickKind); (* Get position of last mouse click within currently active window content in cartesian (pixel) coordinates. The variable click indicates whether a modifying key (e.g. shift, option, or command) has been pressed simultaneously with the mouse click. NOTE: This procedure returns correct values many times and will not destroy this information unless the mouse is clicked again and it assigns values always regardless whether the click is the second click of a double click or not (compare above with GetLastClick and GetLastDoubleClick). *) PROCEDURE DoTillMButReleased(p: PROC); (* Execute procedure p as long as the mouse button is not released *) PROCEDURE Drag(duringDragP,afterDragP: DragProc); (* Calls during dragging repeatedly procedure duringDragP (draws typically the outline of the object to be dragged once relative to the coordinates (x,y) representing a mouse position) till the mouse button is released. Attempts to call procedure SetMode within the drag procedure are ignored since module DMWindows also uses this procedure to erase the object at the old position if the mouse is still moved. Releasing the mouse button indicates the end of the dragging process, which results in a single call to the procedure afterDragP. Actual parameters are the coordinates x and y of the point, where the button has been released. Procedure afterDragP typically removes object at old position and draws object fully at the new location. Attempts to drag the object outside of window u fail, i.e. the object is jumping back at its old position. *) (***************************) (*##### Scrolling #####*) (***************************) (* If you have created a window which contains scrollbars using the procedure DMWindows.CreateWindow, the scrollbars will initially be inactive. You must first define the actual content size of your document by means of the procedure SetContSize. Then you must assign a scrolling procedure to define how the Dialog Machine should handle a scrolling event. You may choose between the auto scroll mechanism offered by the Dialog Machine and your own scrolling procedure. The program structure of a module using the auto scroll mechanism may look like this: ================ Example ================= MODULE MyModule; FROM DMMaster IMPORT RunDialogMachine; FROM DMWindows IMPORT Window, CreateWindow, WindowKind, ScrollBars, RectArea, CloseAttr, ZoomAttr, WindowFrame, WFFixPoint, NoBackground; FROM DMWindIO IMPORT SetContSize, SetScrollStep, SetScrollProc, AutoScrollProc; VAR myWindow: Window; PROCEDURE MyDrawing( w: Window ); BEGIN (* your drawings here *) END MyDrawing; PROCEDURE MakeWindow; VAR frame: WindowFrame; contentRect: RectArea; BEGIN WITH frame DO x := 20; y := 20; w := 200; h := 200; END; CreateWindow( myWindow, GrowOrShrinkOrDrag, WithBothScrollBars, WithCloseBox, WithZoomBox, bottomLeft, frame, "My Window", MyDrawing ); WITH contentRect DO x := 0; y := 0; (* content rect should be larger *) w := 300; h := 300; (* than window frame! *) END; SetContSize( myWindow, contentRect ); SetScrollStep( myWindow, 50, 10 ); SetScrollProc( myWindow, AutoScrollProc ); END MakeWindow; BEGIN NoBackground; MakeWindow; RunDialogMachine; END MyModule. Machine' eventually repeatedly during the scrolling done by the user, i.e. only once if the user clicks in the page up or down scroll bar region, only once if the user drags the scroll box to a new location, and repeatedly after every small scroll step in case the user presses the mouse button in the scroll up or scroll down arrows. Usually this procedure calls GetScrollBoxPos or GetScrollBoxChange and then it adjusts and reconstructs the window content by calling MoveOriginTo and drawing procedures or ScrollContent and UpdateWindow. *) PROCEDURE SetContSize(u: Window; contentRect: RectArea); (* Defines the actual content size of your document. If your document is larger than the window, the contentRect defines the maximum area over which you can scroll. In this case the scrollbars will become active otherwise they will become inactive. The x coordinate of the contentRect belongs to the left most position and x+w to the right most position of the horizontal scrollbar. The y coordinate of the contentRect belongs to the lowest position and y+h to the highest position of the vertical scrollbar. *) PROCEDURE GetContSize(u: Window; VAR contentRect: RectArea); PROCEDURE SetScrollStep(u: Window; xStep, yStep: INTEGER); (* Defines the minimum scroll distance by which the content of a window will be scrolled if the user clicks the down or up arrow of a scrollbar. If the user clicks into the page up or page down area of a scrollbar (e.g. grey region), then the scrolling distance is equal to the current window size minus the size of one scroll step. *) PROCEDURE GetScrollStep(u: Window; VAR xStep, yStep: INTEGER); PROCEDURE SetScrollBoxPos(u: Window; posX,posY: INTEGER); PROCEDURE GetScrollBoxPos(u: Window; VAR posX,posY: INTEGER); (* These procedures set respectively return the current position of the scroll boxes of the scrollbars relative to the defined contentRect of your document. *) PROCEDURE GetScrollBoxChange(u: Window; VAR changeX,changeY: INTEGER); (* Returns the relative change of the scrollbox position since the last calling of GetScrollBoxChange or GetScrollBoxPos. *) PROCEDURE AutoScrollProc(u: Window); (* Assign this procedure to your window, if you want to use the auto scroll mechanism of the Dialog Machine. It scrolls the current visible part of the window, moves the coordinate system origin and calls the restore procedure of the window for the regions which could not be filled automatically. If the auto update mechanism is used together with this auto scrolling mechanism, the whole information stored in the offscreen bitmap is used to update the window. However, the latter combination is not recommended, because the scrolling may not always be handled consistently. *) PROCEDURE SetScrollProc(u: Window; scrollP: RestoreProc); (* Assigns a scroll procedure to the window u to handle scrolling events. This procedure is called by the 'Dialog Machine' eventually repeatedly during the scrolling done by the user, i.e. only once if the user clicks in the page up or down scroll bar region, only once if the user drags the scroll box to a new location, and repeatedly after every small scroll step in case the user presses the mouse button in the scroll up or scroll down arrows. Usually this procedure calls GetScrollBoxPos or GetScrollBoxChange and then it adjusts and reconstructs the window content by calling MoveOriginTo and drawing procedures or ScrollContent and UpdateWindow. *) PROCEDURE GetScrollProc(u: Window; VAR scrollP: RestoreProc); PROCEDURE ScrollContent(u: Window; dx,dy: INTEGER); (* Scrolls the content of the window u dx pixels to the right and dy pixels upwards. This procedure doesn't change the pixel coordinate system of the window u, it simply moves the entire content of the window to different coordinates. The space created by the scroll is erased and an update event is generated for it. CAUTION: If you use this procedure, any drawing operation within a scroll procedure should be done by your update procedure only, otherwise the update procedure will overwrite your drawings right after it handled the scroll event. Call UpdateWindow afterwards to handle the update event and to fill the empty space generated by this procedure. Note: This procedure may be clipped to a clipping rectangle in order to scroll only the content of this rectangle (see SetClipping). *) PROCEDURE MoveOriginTo(u: Window; x0,y0: INTEGER); (* Moves origin to point (x0,y0) defined in old, i.e. current cartesian (pixel) coordinates (default origin is lower left corner of current WindowFrame). *) (********************************) (*##### General Output #####*) (********************************) VAR WindowIODone: BOOLEAN; (*indicates success of an input/output routine*) PROCEDURE SelectForOutput(u: Window); (*switches all subsequent output related actions to window u*) PROCEDURE CurrentOutputWindow(): Window; (*returns current output window*) TYPE PaintMode = (replace, paint, invert, erase); (* replace : Destination := Source paint : Destination := Destination OR Source invert : Destination := Destination XOR Source erase : Destination := Destination AND NOT Source (1 = black and 0 = white ) *) Hue = [0..359]; (* = degrees. See HSV model below *) GreyContent = (light, lightGrey, grey, darkGrey, dark); Saturation = [0..100]; (* percent *) (* According to the Hue-Saturation-Value (HSV) color model by Ivan Dum. see Fundamentals of interactive Computer Graphics p. 613 ff. On black-and-white displays (like the Macintosh's), Hue, GreyContent and Saturation are not supported. Any call of one of these color procedures has no effect. *) Color = RECORD hue: Hue; greyContent: GreyContent; saturation: Saturation; END; PatLine = BYTE; Pattern = ARRAY [0..7] OF PatLine; VAR pat: ARRAY [light..dark] OF Pattern; (* predefined patterns, which may be used to simulate the GreyContent on an black-and-white display. *) black, white, red, green, blue, cyan, magenta, yellow : Color; (* these are 8 predefined colors, which may be used for defining colors. These are READ ONLY VARIABLES! Don«t change their values *) PROCEDURE SetMode(mode: PaintMode); (* Set one of the four modes for every output procedure e.g. Dot, LineTo, MoveBy, Circle etc. and all text drawing procedures in current output window *) PROCEDURE GetMode(VAR mode: PaintMode); PROCEDURE SetBackground(c: Color; pat: Pattern); (* Set the color and the background pattern of any Window background. On a black-and-white Display the parameter c has no effect. The default background color is white and the default background pattern is pat[light]. *) PROCEDURE GetBackground(VAR c: Color; VAR pat: Pattern); (* Returns the current background color and pattern of the current output window. *) PROCEDURE SetColor(c: Color); (* Set the color for all subsequent drawing in current output window. On a black-and-white display this procedure has no effect. The default color is black. *) PROCEDURE GetColor(VAR c: Color); (* Returns the current color of the current output window. *) PROCEDURE SetPattern(p: Pattern); (* Set the current pen pattern to p. This pattern will be used by all line drawing routines e.g. LineTo, MoveBy, UCLineTo, CloseAndFillPolygon and Circle if filled is FALSE. The procedure Dot is not affected by this procedure. *) PROCEDURE GetPattern(VAR p: Pattern); (* Returns the current pattern of the current output window. *) (**************************************************************** Each window knows at least two reference systems: a grid with cells of character size (determined by current font) and cartesian coordinates with the origin at the lower left corner. The cells of the character based grid are referenced by line and column with the upper left corner being (1,1). The maximum dimensions of the grid are determined by the current window size. Attempts to write below the bottom of the window result in the call of procedure EOWAction as previously assigned (default EOWAction is ScrollUp by one line). The grid system can only be referenced correctly with a non-proportional font such as Monaco. Otherwise, i.e. if a proportional font is used, cell coordinates just denote the position of the leftmost character in the string. The cell into which the last character drawn falls has to be determined by means of procedure DMWindIO.GetPos. The width of a cell is constant and corresponds to the average number of pixels a character of the current font occupies. Hence, this grid can provide a rough estimate to position strings within the window, and helps to align text. Each window possesses a current position for both reference systems: The caret denotes the current cell in the character grid, the pen is at the current graphic output point. *****************************************************************) PROCEDURE IdentifyPos(x,y: INTEGER; VAR line,col: CARDINAL); (* Identify line and column corresponding to the position (x,y). Returns (0,0) if (x,y) outside window. *) PROCEDURE IdentifyPoint(line,col: CARDINAL; VAR x,y: INTEGER); (* Identify point (x,y) corresponding to lower left corner of character position (line,col) *) PROCEDURE MaxCol(): CARDINAL; (*current maximum column*) PROCEDURE MaxLn(): CARDINAL; (*current maximum line*) PROCEDURE CellWidth(): INTEGER; (*current char cell width in pixels*) PROCEDURE CellHeight(): INTEGER; (*current char cell height in pixels*) PROCEDURE BackgroundWidth(): INTEGER; (*background width in pixels*) PROCEDURE BackgroundHeight(): INTEGER; (*background height in pixels*) PROCEDURE SetEOWAction(u: Window; action: PROC); (* Assign procedure action, which is to be called if an attempt is made to make output beyond the bottom of the window (EOW = End Of Window), e.g. calling DMWindIO.WriteString after a DMWindIO.WriteLn has been called when the caret was on line MaxLn(). The default action is ScrollContent(0,CellHeight()). *) PROCEDURE GetEOWAction(u: Window; VAR action: PROC); PROCEDURE EraseContent; PROCEDURE RedrawContent; (* Forces the redrawing of the whole content of the current output window by means of it's current restore procedure. *) PROCEDURE SetClipping(cr: RectArea); (* Clips any drawing outside rectangle with lower left corner (cr.x,cr.y), width cr.w, and height cr.h in current output window *) PROCEDURE GetClipping(VAR cr: RectArea); (* Returns current clipping rectangle *) PROCEDURE RemoveClipping; (* Resets previously set clipping rectangle in current output window *) (********************************) (*##### Textual Output #####*) (********************************) TYPE WindowFont = (Chicago, Monaco, Geneva, NewYork); LaserFont = (Times, Helvetica, Courier, Symbol); FontStyles = (bold, italic, underline); FontStyle = SET OF FontStyles; PROCEDURE SetWindowFont(wf: WindowFont; size: CARDINAL; style: FontStyle); PROCEDURE GetWindowFont(VAR wf: WindowFont; VAR size: CARDINAL; VAR style: FontStyle); PROCEDURE SetLaserFont(lf: LaserFont; size: CARDINAL; style: FontStyle); PROCEDURE GetLaserFont(VAR lf: LaserFont; VAR size: CARDINAL; VAR style: FontStyle); (* Returns current window or laser font and attributes *) PROCEDURE SetPos(line,col: CARDINAL); (* Upper left corner = (1,1) *) PROCEDURE GetPos(VAR line,col: CARDINAL); PROCEDURE ShowCaret(on: BOOLEAN); (* TRUE: a triangular caret is shown at current pen position. All text routines moves the caret. These reoutines are: SetPos, Write, WriteLn, WriteString and all number writing procedures. FALSE: the caret will be hidden *) PROCEDURE Invert(on: BOOLEAN); (*true: write subsequent text inverted, false: stop inverting text*) PROCEDURE Write(ch: CHAR); (* Write at the current position the character ch. ASCII BS (= 10C; back space a position), FF (= 14C; calls ClearWindow), LF (= 12C; move down one line, same col), CR (= 15C; WriteLn), CAN (= 30C; delete till end of line), EOL (= 36C; WriteLn), and DEL (= 177C; backspace and delete last char) are interpreted. *) PROCEDURE WriteLn; (* = Write(EOL) *) PROCEDURE WriteString(s: ARRAY OF CHAR); PROCEDURE StringArea (s: ARRAY OF CHAR; VAR a: RectArea; VAR baseLine,sepSpace: INTEGER); (* Returns for the given string s the area the letters will occupy (a.h = ascent + descent) and the baseLine (= descent). <------------------ a.w ----------------------> ----------------------------------------------- | ^ | | | sepSpace (left blank between lines) | | v | |-----------******----------------------------| | * ^ | CharHeigth | * * **** | | | * * * | | | * * * a.h | |-----*-----******--baseLine--------------|---| | * ^ | | | * baseLine | | | | * v v | a.y > -**-------------------------------------------- ^ a.x The routine assumes that the string s will be written at the current pen location and returns these values as a.x and a.y (≈ lower, left corner of the character cell). The value sepSpace corresponds to the amount of pixels which are left blank between lines of text (≈ Inside Macintosh leading). If you wish to clear an area "around" the string, blank an area which adds twice sepSpace, once above and once below the string. Note that CharHeight returns a.h+sepSpace. *) PROCEDURE StringWidth (VAR s: ARRAY OF CHAR): INTEGER; PROCEDURE WriteVarString(VAR s: ARRAY OF CHAR); (* To support output as efficiently as possible, above procedures allow to pass strings as VAR parameters. Otherwise WriteVarString is equivalent to WriteString and StringWidth is similar to StringArea. However, in contrast to StringArea, procedure StringWidth returns just the width of the string s in pixels, instead of the whole, string enclosing rectangle as returned by StringArea (see above). Experience shows, that during writing in a proportional font, the width is the most frequently required value; hence, StringWidth may be sufficient and there are only rare cases where StringArea is actually needed. *) PROCEDURE WriteCard(c,n: CARDINAL); PROCEDURE WriteLongCard(lc: LONGCARD; n: CARDINAL); PROCEDURE WriteInt(c: INTEGER; n: CARDINAL); PROCEDURE WriteLongInt(li: LONGINT; n: CARDINAL); (* Write number with at least n character. Insert leading blanks if necessary *) PROCEDURE WriteReal(r: REAL; n,dec: CARDINAL); PROCEDURE WriteLongReal(lr: LONGREAL; n,dec: CARDINAL); (* Write real number with at least n characters and dec decimals. Insert leading blanks if necessary *) PROCEDURE WriteRealSci(r: REAL; n,dec: CARDINAL); PROCEDURE WriteLongRealSci(lr: LONGREAL; n,dec: CARDINAL); (* Write real number with at least n characters and dec decimals in scientific notation. Insert leading blanks if necessary *) (***************************************************************** NOTE: Not only do all write procedures move the caret position, but also the pen position! *****************************************************************) (*********************************) (*##### Graphics Output #####*) (*********************************) (*---------------------------------------*) (*===== Pixel oriented graphics =====*) (*---------------------------------------*) (* Origin is at lower left corner of window. Non visible Pen at current output location. Cartesian coordinates in pixels. *) PROCEDURE SetPen(x,y: INTEGER); (*does not draw*) PROCEDURE GetPen(VAR x,y: INTEGER); (*get current pen position*) PROCEDURE SetBrushSize(width,height: INTEGER); (* affects all subsequent drawing *) PROCEDURE GetBrushSize(VAR width,height: INTEGER); (* Draw subsequently lines with a brush of width and height (in pixels) as specified. The brush is moved along the cordinate system with its upper left corner positioned exactly at the current pen position. The width and the height define the number of pixels actually drawn to the right and below the upper left corner. This means that drawing lines e.g. by means of procedured LineTo will result in a movement of the upper left corner of the brush along the line specified by LineTo (see below) and painting during this movement every pixel touched by the brush as given by its dimensions. The default size DMWindIO uses is (1,1). See module DMPrinting for hair line styles, which are only supported on PostScript printers, since they can't be drawn on a screen with a brush size < (1,1). *) PROCEDURE Dot(x,y: INTEGER); PROCEDURE LineTo(x,y: INTEGER); (*Draw line from current to new pen position (x,y)*) PROCEDURE Circle(x,y: INTEGER; radius: CARDINAL; filled: BOOLEAN; fillpat: Pattern); (* Draw circle with centre at position (x,y), radius radius, and fill it with the pattern fillpat if filled = TRUE *) PROCEDURE Area(r: RectArea; pat: Pattern); (* Paint the rectangular area at x,y of width w and height h with pattern pat *) PROCEDURE CopyArea(sourceArea: RectArea; destx,desty: INTEGER); (* copy rectangular area sourceArea into rectangle area at (destx,desty) *) PROCEDURE MapArea(sourceArea,destArea: RectArea); (* Map rectangular source area at (sourceArea.x,sourceArea.y) with width (sourceArea.w), and height (sourceArea.h) into destination rectangle at (destArea.x,destArea.y) with width destArea.w and height destArea.h. Note: sizes of source and destination rectangles may be different, but in order to obtain optimal results avoid overlapping. *) PROCEDURE DisplayPredefinedPicture(fileName: ARRAY OF CHAR; pictureID: INTEGER; f: RectArea); (* Displays a predefined picture read from a Macintosh resource of the type "PICT" with ID = pictureID contained in the resource fork of the file fileName. In the case that the fileName passed is empty, the default search strategy to find the resource is followed. The picture is displayed within the rectangle f. If the picture has been predefined to a different size, the display is scaled to fit exactly the enclosing rectangle f. If w and h of the RectArea are equal to zero, then the picture will be drawn in its original size at the position specified by x and y of RectArea. *) PROCEDURE GetPredefinedPictureFrame(fileName: ARRAY OF CHAR; pictureID: INTEGER; VAR f: RectArea); (* Returns the rectangle in which the predefined picture has been stored. This procedure is typically called before calling DisplayPredefinedPicture when the picture's size is needed for computations, e.g. when it shall be centered or otherwise formatted. *) PROCEDURE StartPolygon; PROCEDURE CloseAndFillPolygon(pat: Pattern); (* Allows the drawing of a polygon by multiple calls to LineTo, MoveBy, or PlotTo between calling StartPolygon and CloseAndFillPolygon in order to fill it with pattern pat (Must not be nested and each StartPolygon must be matched with a CloseAndFillPolygon) *) PROCEDURE DrawAndFillPoly ( nPoints : CARDINAL; VAR x, y : ARRAY OF INTEGER; VAR withEdge : ARRAY OF BOOLEAN; VAR edgeColors: ARRAY OF Color; isFilled : BOOLEAN; fillColor : Color; fillPattern : Pattern ); (* In contrast to CloseAndFillPolygon which always fills and draws a frame this procedure allows to define for each individual edge the attributes, such as the drawing of a connecting line (withEdge) between corners, and the color to be used (edgeColors). Moreover it can be controlled whether the polygon is filled or not (transparent polygon) (isFilled). Finally if filled it is not only possible to control the pattern (fillPattern) but also the color (fillColor) *) (* The following objects provide means to use Macintosh QuickDraw output routines via the coordinate systems supported by this module. The technique is to convert a position defined relative to a supported coordinate system into the coordinates used by QuickDraw before passing the values to the QuickDraw routine. Use this feature only with utmost care! Note: The routines are supported only on the Macintosh version of the "Dialog Machine" and their usage will defy the portability of the client. Note: It remains the programmer's responsibility to ensure the correct output to the update copy of a window in case the automatic restore mechanism (AutoRestoreProc) is used: Any output made directly with a QuickDraw routine has to be made a second time after having called procedure SelectRestoreCopy. *) TYPE QDVHSelect = (v,h); QDVHSelectR = [v..h]; QDPoint = RECORD CASE :INTEGER OF 0: v,h: INTEGER; | 1: vh: ARRAY QDVHSelectR OF INTEGER; END(*CASE*); END(*RECORD*); QDRect = RECORD CASE :INTEGER OF 0: top,left,bottom,right: INTEGER; | 1: topLeft,botRight: QDPoint; END(*CASE*); END(*RECORD*); PROCEDURE XYToQDPoint(x,y: INTEGER; VAR p: QDPoint); (*Convert position (x,y) into a QuickDraw point*) PROCEDURE RectAreaToQDRect(r: RectArea; VAR qdr: QDRect); (*Convert rectangular area r into a QuickDraw rectangle*) PROCEDURE SelectRestoreCopy(u: Window); (* Only to be used if Macintosh QuickDraw output routines are accessed directly and the current output goes to a window with automatic restoration (DMWindows.AutoRestoreProc). First call SelectForOutput and your QuickDraw routine. Second call this procedure and your QuickDraw routine a second time. *) PROCEDURE SetRestoreCopy(u: Window; rcp: ADDRESS); (* Use instead of CreateWindow or AssignRestoreProc with actual argument AutoRestoreProc. rcp must be of type GraphPort or CGraphPort and must have been allocated before this procedure is called. Subsequently the auto restore mechanism may be used in the usual way. This procedure is only provided to support the work with ColorQuickDraw on newer Macintosh machines like the Macintosh II, and should only be used by programmers with good Inside Macintosh knowledge!!!!!!!! *) (*-------------------------------*) (*===== Turtle graphics =====*) (*-------------------------------*) (* Angles are given in degrees (right angle = 90°) in positive direction. 0° points horizontally to the right. *) PROCEDURE Turn(angle: INTEGER); (*turn by angle*) PROCEDURE TurnTo(angle: INTEGER); (*turn to absolute angle position*) PROCEDURE MoveBy(distance: CARDINAL); (*move by distance pixels*) (*-------------------------------------------*) (*===== Drawing in user coordinates =====*) (*-------------------------------------------*) PROCEDURE ScaleUC(r: RectArea; xmin,xmax,ymin,ymax: REAL); (* Scale user coordinates (xmin,ymin) to lower left corner (r.x,r.y) of pixel coordinates. (xmax,ymax) corresponds to (r.x+r.w,r.y+r.h). It is recommended to avoid drawing in user coordinates (UC) outside of the defined rectangle. Note, that clipping can be accomplished by calling procedure SetClipping with the same argument as used when calling ScaleUC. There is a logical pen (UCPen) associated with the user coordinates, although output is actually made by using the pixel oriented pen. ERRORS: - If the two limits of each range are equal (xmin = xmax OR ymin = ymax) then an error message will be displayed and the user coordinate system won«t be changed. The default user corrdinate system is equal the pixel oriented coordinate system ( r.x = xmin = 0; r.y = ymin = 0; r.w = xmax - xmin = windowFrame.w; r.h = ymax - ymin = windowFrame.h) *) PROCEDURE GetUC(VAR r: RectArea; VAR xmin,xmax,ymin,ymax: REAL); (* Returns current rectangle and extrema mapped onto it of the user coordinate system *) (* Convert from user coordinates to cartesian coordinates in pixels and vice versa *) PROCEDURE ConvertPointToUC(x,y: INTEGER; VAR xUC,yUC: REAL); PROCEDURE ConvertUCToPoint(xUC,yUC: REAL; VAR x,y: INTEGER); (* Returns the pixel coordinates of a point, which is specified by the user coordinates xUC and yUC. ERRORS: - If the calculated pixel coordinates are outside the INTEGER range, an error message will be displayed; x and y remain unchanged. *) PROCEDURE UCFrame; (*Draw a frame around the user coordinate system*) PROCEDURE EraseUCFrame; PROCEDURE EraseUCFrameContent; PROCEDURE SetUCPen(xUC,yUC: REAL); (*set pen in user coordinates*) PROCEDURE GetUCPen(VAR xUC,yUC: REAL); (*get current pen position in user coordinates*) PROCEDURE UCDot(xUC,yUC: REAL); PROCEDURE UCLineTo(xUC,yUC: REAL); (*Draw a line from current to new pen position (xUC,yUC)*) PROCEDURE DrawSym(sym: CHAR); (* Draw character sym with its centre at current pen position (may also be used for drawing in pixel oriented coordinates) *) END DMWindIO.
|
||
|
|
|