ETHZ_Logo RAMSES_Logo_Right   RAMSES   RAMSES_Logo_Left Systems Ecology  
Start    search button      Modules:   A-Z   Function   Layer        QuickRefs:   DM   AuxLib   AuxLibE   SciLib   EasyMW   MW   ISIS   RMSLib

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.

  Contact RAMSES@env.ethz.ch Last updated: 25-Jul-2011 [Top of page]