home *** CD-ROM | disk | FTP | other *** search
- (*************************************************************************
-
- $RCSfile: Lines.mod $
- Description: A port of lines.c from the RKM:Libraries.
-
- Implements a superbitmap with scroll gadgets.
-
- Created by: fjc (Frank Copeland)
- $Revision: 1.6 $
- $Author: fjc $
- $Date: 1995/01/25 23:52:19 $
-
- Copyright © 1994-1995, Frank Copeland.
- This example program is part of Oberon-A.
- See Oberon-A.doc for conditions of use and distribution.
-
- *************************************************************************)
-
- <* STANDARD- *>
-
- MODULE Lines;
-
- IMPORT
- SYS := SYSTEM,
- e := Exec,
- gfx := Graphics,
- l := Layers,
- i := Intuition,
- rn := RandomNumbers;
-
- CONST VersionTag = "$VER: Lines 1.3 (24.1.95)\r\n";
-
- (*------------------------------------*)
- CONST
-
- widthSuper = 800;
- heightSuper = 600;
-
- upDownGadget = 0;
- leftRightGadget = 1;
- noGadget = 2;
-
- maxPropVal = 0FFFFH;
-
- VAR
-
- win : i.WindowPtr;
- botGadInfo : i.PropInfo;
- botGadImage : i.Image;
- botGad : i.Gadget;
- sideGadInfo : i.PropInfo;
- sideGadImage : i.Image;
- sideGad : i.Gadget;
-
- (*------------------------------------*)
- PROCEDURE UWORD2LONGINT (x : e.UWORD) : LONGINT;
-
- BEGIN (* UWORD2LONGINT *)
- IF x < 0 THEN RETURN x + 10000H
- ELSE RETURN x
- END;
- END UWORD2LONGINT;
-
- (*------------------------------------
- ** Replacement for amiga.lib function
- *)
- PROCEDURE RangeRand (maxValue : LONGINT) : LONGINT;
-
- BEGIN (* RangeRand *)
- RETURN ENTIER (rn.Uniform () * (maxValue + 1))
- END RangeRand;
-
- (*------------------------------------
- ** Set-up the prop gadgets--initialize them to values that fit
- ** into the window border. The height of the prop gadget on the side
- ** of the window takes the height fo the title bar into account in its
- ** set-up. Note the initialization assumes a fixed size "sizing" gadget.
- **
- ** Note also, that the size of the sizing gadget is dependent on the
- ** screen resolution. The numbers given here are only valid if the
- ** screen is NOT lo-res. These values must be re-worked slightly
- ** for lo-res screens.
- *)
- PROCEDURE InitBorderProps (myScreen : i.ScreenPtr);
-
- BEGIN (* InitBorderProps *)
- (* Initializes the two prop gadgets.
- **
- ** Note where the propNewLook flag goes. Adding this flag requires
- ** no extra storage, but tells the system that our program is
- ** expecting the new-look prop gadgets under 2.0.
- *)
- botGadInfo.flags := { i.autoKnob, i.freeHoriz, i.propNewlook };
- botGadInfo.horizPot := 0;
- botGadInfo.vertPot := 0;
- botGadInfo.horizBody := -1;
- botGadInfo.vertBody := -1;
-
- botGad.leftEdge := 3;
- botGad.topEdge := -7;
- botGad.width := -23;
- botGad.height := 6;
- botGad.flags := { i.gRelBottom, i.gRelWidth };
- botGad.activation := { i.relVerify, i.gadgImmediate, i.bottomBorder };
- botGad.gadgetType := i.propGadget + i.gzzGadget;
- botGad.gadgetRender := SYS.ADR (botGadImage);
- botGad.specialInfo := SYS.ADR (botGadInfo);
- botGad.gadgetID := leftRightGadget;
-
- sideGadInfo.flags := { i.autoKnob, i.freeVert, i.propNewlook };
- sideGadInfo.horizPot := 0;
- sideGadInfo.vertPot := 0;
- sideGadInfo.horizBody := -1;
- sideGadInfo.vertBody := -1;
-
- sideGad.leftEdge := -14;
- sideGad.topEdge := myScreen.wBorTop + myScreen.font.ySize + 2;
- sideGad.width := 12;
- sideGad.height := -sideGad.topEdge - 11;
- sideGad.flags := { i.gRelRight, i.gRelHeight };
- sideGad.activation := { i.relVerify, i.gadgImmediate, i.rightBorder };
- sideGad.gadgetType := i.propGadget + i.gzzGadget;
- sideGad.gadgetRender := SYS.ADR (sideGadImage);
- sideGad.specialInfo := SYS.ADR (sideGadInfo);
- sideGad.gadgetID := upDownGadget;
- sideGad.nextGadget := SYS.ADR (botGad);
- END InitBorderProps;
-
- (*------------------------------------*)
- PROCEDURE DoDrawStuff ();
-
- VAR
- x1, y1, x2, y2 : INTEGER;
- pen, ncolors, deltx, delty : INTEGER;
-
- BEGIN (* DoDrawStuff *)
- ncolors := SHORT (ASH (1, win.wScreen.bitMap.depth));
- deltx := SHORT (RangeRand (6)) + 2;
- delty := SHORT (RangeRand (6)) + 2;
-
- pen := SHORT (RangeRand (ncolors - 1)) + 1;
- gfx.SetAPen (win.rPort, SHORT (pen));
- x1 := 0; y1 := 0; x2 := widthSuper - 1; y2 := heightSuper - 1;
- WHILE x1 < widthSuper DO
- gfx.Move (win.rPort, x1, y1);
- gfx.Draw (win.rPort, x2, y2);
- INC (x1, deltx); DEC (x2, deltx)
- END;
-
- pen := SHORT (RangeRand (ncolors - 1)) + 1;
- gfx.SetAPen (win.rPort, SHORT (pen));
- x1 := 0; y1 := 0; x2 := widthSuper - 1; y2 := heightSuper - 1;
- WHILE y1 < heightSuper DO
- gfx.Move (win.rPort, x1, y1);
- gfx.Draw (win.rPort, x2, y2);
- INC (y1, delty); DEC (y2, delty)
- END;
- END DoDrawStuff;
-
- (*------------------------------------
- ** This function provides a simple interface to ScrollLayer()
- *)
- PROCEDURE SlideBitMap (Dx, Dy : INTEGER);
-
- BEGIN (* SlideBitMap *)
- l.ScrollLayer (win.rPort.layer, Dx, Dy)
- END SlideBitMap;
-
- (*------------------------------------
- ** Update the prop gadgets and bitmap positioning when the size changes.
- *)
- PROCEDURE DoNewSize ();
-
- VAR
- tmp : e.ULONG;
- scrollX, scrollY : INTEGER;
-
- BEGIN (* DoNewSize *)
- scrollX := win.rPort.layer.scrollX;
- scrollY := win.rPort.layer.scrollY;
-
- tmp := scrollX + win.gzzWidth;
- IF tmp >= widthSuper THEN
- SlideBitMap (widthSuper - SHORT (tmp), 0)
- END;
-
- i.NewModifyProp
- ( botGad, win, NIL, {i.autoKnob, i.freeHoriz},
- ( (scrollX * maxPropVal) DIV
- (widthSuper - win.gzzWidth) ),
- 0,
- ((win.gzzWidth * maxPropVal) DIV widthSuper),
- maxPropVal, 1 );
-
- tmp := scrollY + win.gzzHeight;
- IF tmp >= heightSuper THEN
- SlideBitMap (0, heightSuper - SHORT (tmp))
- END;
-
- i.NewModifyProp
- ( sideGad, win, NIL, {i.autoKnob, i.freeVert},
- 0,
- ( (scrollY * maxPropVal) DIV
- (heightSuper - win.gzzHeight) ),
- maxPropVal,
- ((win.gzzHeight * maxPropVal) DIV heightSuper),
- 1 );
- END DoNewSize;
-
- (*------------------------------------
- ** Process the currently selected gadget.
- ** This is called from i.idcmpIntuiTicks and when the gadget is released
- ** i.idcmpGadgetUp.
- *)
- PROCEDURE CheckGadget (gadgetID : e.UWORD);
-
- VAR
- tmp : e.ULONG;
- dX : INTEGER;
- dY : INTEGER;
-
- BEGIN (* CheckGadget *)
- dX := 0; dY := 0;
-
- CASE gadgetID OF
- upDownGadget :
- tmp := heightSuper - win.gzzHeight;
- tmp := tmp * UWORD2LONGINT (sideGadInfo.vertPot);
- tmp := tmp DIV maxPropVal;
- dY := SHORT (tmp) - win.rPort.layer.scrollY
- |
- leftRightGadget :
- tmp := widthSuper - win.gzzWidth;
- tmp := tmp * UWORD2LONGINT (botGadInfo.horizPot);
- tmp := tmp DIV maxPropVal;
- dX := SHORT (tmp) - win.rPort.layer.scrollX
- |
- ELSE (* gadgetID = noGadget *)
- END; (* CASE gadgetID *)
-
- IF (dX # 0) OR (dY # 0) THEN
- SlideBitMap (dX, dY)
- END;
- END CheckGadget;
-
- (*------------------------------------
- ** Main message loop for the window.
- *)
- PROCEDURE DoMsgLoop ();
-
- VAR
- msg : i.IntuiMessagePtr;
- flag : BOOLEAN;
- currentGadget : e.UWORD;
- gadget : i.GadgetPtr;
-
- BEGIN (* DoMsgLoop *)
- flag := TRUE; currentGadget := noGadget;
- WHILE flag DO
- (*
- ** Whenever you want to wait on just one message port
- ** you can use WaitPort(). WaitPort() doesn't require
- ** the setting of a signal bit. The only argument it
- ** requires is the pointer to the window's userPort.
- *)
- e.WaitPort (win.userPort);
- LOOP
- msg := SYS.VAL (i.IntuiMessagePtr, e.GetMsg (win.userPort));
- IF msg = NIL THEN EXIT END;
- gadget := msg.iAddress;
- IF msg.class = {i.closeWindow} THEN
- flag := FALSE
- ELSIF msg.class = {i.newSize} THEN
- DoNewSize();
- DoDrawStuff()
- ELSIF msg.class = {i.gadgetDown} THEN
- currentGadget := gadget.gadgetID
- ELSIF msg.class = {i.gadgetUp} THEN
- CheckGadget (currentGadget);
- currentGadget := noGadget
- ELSIF msg.class = {i.intuiTicks} THEN
- CheckGadget (currentGadget)
- END;
- e.ReplyMsg (msg)
- END;
- END;
- END DoMsgLoop;
-
- (*------------------------------------*)
- PROCEDURE SuperWindow (myScreen : i.ScreenPtr);
-
- VAR
- bigBitMap : gfx.BitMapPtr;
- planeNum : INTEGER;
- allocatedBitMaps : BOOLEAN;
-
- BEGIN (* SuperWindow *)
- (* set-up the border prop gadgets for the OpenWindow() call. *)
- InitBorderProps (myScreen);
-
- (* The code relies on the allocation of the BitMap structure with
- ** the memClear flag. This allows the assumption that all of the
- ** bitmap pointers are NIL, except those successfully allocated
- ** by the program.
- *)
- bigBitMap := e.AllocMem (SIZE (gfx.BitMap), {e.public, e.memClear});
- IF bigBitMap # NIL THEN
- gfx.InitBitMap
- ( bigBitMap^, myScreen.bitMap.depth, widthSuper, heightSuper );
-
- allocatedBitMaps := TRUE;
- planeNum := 0;
- WHILE (planeNum < myScreen.bitMap.depth) & allocatedBitMaps DO
- bigBitMap.planes [planeNum] :=
- gfx.AllocRaster (widthSuper, heightSuper);
- allocatedBitMaps := (bigBitMap.planes [planeNum] # NIL);
- INC (planeNum)
- END;
-
- (* Only open the window if the bitplanes were successfully
- ** allocated. Fail silently if they were not.
- *)
- IF allocatedBitMaps THEN
- (* OpenWindowTags() and OpenWindowTagList() are only available
- ** when the lebrary version is at least V36. Under earlier
- ** versions of Intuition, use OpenWindow() with a NewWindow
- ** structure.
- *)
- win := i.OpenWindowTagsA
- ( NIL,
- i.waWidth, 150,
- i.waHeight, 4 * (myScreen.wBorTop + myScreen.font.ySize + 1),
- i.waMaxWidth, widthSuper,
- i.waMaxHeight, heightSuper,
- i.waIDCMP, { i.gadgetUp, i.gadgetDown,
- i.newSize, i.intuiTicks,
- i.closeWindow },
- i.waFlags, { i.windowSizing, i.sizeBRight,
- i.sizeBBottom, i.windowDrag,
- i.windowDepth, i.windowClose,
- i.superBitmap, i.gimmeZeroZero,
- i.noCareRefresh },
- i.waGadgets, SYS.ADR (sideGad),
- i.waTitle, SYS.VAL (LONGINT, SYS.ADR (VersionTag)) + 6,
- i.waPubScreen, myScreen,
- i.waSuperBitMap, bigBitMap,
- 0 );
- IF win # NIL THEN
- (* set-up the window display *)
- gfx.SetRast (win.rPort, 0);
- gfx.SetDrMd (win.rPort, gfx.jam1);
- DoNewSize (); (* adjust props to represent portion visible *)
- DoDrawStuff ();
-
- (* process the window, return on idcmpCloseWindow *)
- DoMsgLoop ();
- i.CloseWindow (win)
- END;
- END;
- FOR planeNum := 0 TO myScreen.bitMap.depth - 1 DO
- gfx.FreeRaster
- ( bigBitMap.planes [planeNum], widthSuper, heightSuper )
- END;
- e.FreeMem (bigBitMap, SIZE (gfx.BitMap))
- END;
- END SuperWindow;
-
- (*------------------------------------*)
- PROCEDURE Main ();
-
- VAR
- myScreen : i.ScreenPtr;
-
- BEGIN (* Main *)
- IF i.base.libNode.version >= 37 THEN
- myScreen := i.LockPubScreen ("");
- IF myScreen # NIL THEN
- SuperWindow (myScreen);
- i.UnlockPubScreen ("", myScreen);
- END
- END
- END Main;
-
- BEGIN (* Lines *)
- rn.TimeSeed ();
- Main ();
- END Lines.
-