home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 10
/
Fresh_Fish_10_2352.bin
/
new
/
dev
/
obero
/
oberon-a
/
examples
/
libraries
/
intuition
/
lines.mod
< prev
next >
Wrap
Text File
|
1995-07-02
|
11KB
|
388 lines
(*************************************************************************
$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
b