ð¦Syntax10.Scn.FntSyntax10i.Scn.Fntõÿÿÿ€‹ðIStampElemsAlloc16 Oct 98Ó Syntax10b.Scn.Fnt  *1 üÿÿÿÀÔ°­MarkElemsAlloc½Fÿÿÿÿ€8ÀÔFoldElemsNewåÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­¾Fÿÿÿÿ€8ÀÔîÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­ïöAÊÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt draw current color Ëÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­¿FJÿÿÿÿ€8ÀÔÁÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­ÀFÿÿÿÿ€8ÀÔBÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­ÁFIÿÿÿÿ€8ÀÔcÌÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt inside the table Mÿÿÿÿ€8ÀÔaÇÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt mouse moved or wasout "ÿÿÿÿ€8ÀÔ<Ñÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt inside elem Mÿÿÿÿ€8ÀÔaÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­ÃF+ÿÿÿÿ€8ÀÔ¿ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt adjust table to fit in screen ±ÿÿÿÿ€8ÀÔqÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­“r!2ÿÿÿÿ€8ÀÔ8ÿÿÿÿ€8ÀÔò&'ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔäÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔ\ÿÿÿÿ€8ÀÔ%ÿÿÿÿ€8ÀÔgÿÿÿÿ€8ÀÔ3ÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­ÅF+ÿÿÿÿ€8ÀÔ*ƒ êÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­pd ÿÿÿÿ€8ÀÔwÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­ÆFÿÿÿÿ€8ÀÔ=ÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­ÇFÿÿÿÿ€8ÀÔ6ÿÿÿÿ€8ÀÔT}MODULE ColorElems; (* CE   *) IMPORT Elems, GU := GUtils, Math, Oberon, Input, Display, Viewers, Files, Texts, TextFrames, Bitmaps, TextPrinter; CONST DUnit = TextFrames.Unit; MR = 0; MM = 1; ML = 2; black = Display.white; border = 3; (** elem border *) tb = 4; (** table border *) TYPE Elem* = POINTER TO ElemDesc; ElemDesc* = RECORD(Elems.ElemDesc) value*, nrOfCols* : INTEGER; END ; VAR lines : INTEGER; (* nrOfColors in one column = sqrt(e.nrOfCols) *) table : INTEGER; (* table dimension *) PROCEDURE DrawColors (x, y : INTEGER); VAR i, j, w : INTEGER; BEGIN w := table DIV lines; FOR i := 0 TO lines -1 DO FOR j := 0 TO lines -1 DO GU.ReplConst (NIL, i * lines + j, x + j * w, y + (lines - i - 1) * w, w, w, Display.paint) END END END DrawColors; PROCEDURE DrawTable (x, y : INTEGER); BEGIN GU.ReplConst(NIL, 13, x - tb + 1, y - tb +1, table + 2 * (tb - 1), table + 2 * (tb - 1), Display.replace); GU.Frame(NIL, black, x - tb, y - tb, table + 2 * tb, table + 2 * tb, 1, Display.replace); DrawColors(x, y) END DrawTable; PROCEDURE DrawElemColor (e : Elem; col, x, y : INTEGER; f : Display.Frame); VAR w, h, b : INTEGER; BEGIN b := GU.Unit(border, FALSE); w := GU.Unit(e.W, TRUE); h := GU.Unit(e.H, TRUE); GU.ReplConst(f, col, x + b, y + b, w - 2 * b, h - 2 * b, Display.paint) END DrawElemColor; PROCEDURE DrawElem (e : Elem; x, y : INTEGER; f : Display.Frame; pressed : BOOLEAN); VAR w, h: INTEGER; BEGIN w := GU.Unit(e.W, TRUE); h := GU.Unit(e.H, TRUE); GU.Area(f, 13, 0, x, y, w, h, GU.Unit(1, FALSE), TRUE, pressed); DrawElemColor(e, e.value, x, y, f) END DrawElem; PROCEDURE Invert (x, y, w : INTEGER); BEGIN GU.Frame(NIL, 0, x, y, w, w, 2, Display.invert) END Invert; PROCEDURE TrackColors (e : Elem; VAR col : INTEGER; VAR msg : TextFrames.TrackMsg); VAR ew, eh, mx, my, w, cx, cy, ox, oy : INTEGER; wasout : BOOLEAN; keysum : SET; BEGIN ew := SHORT(e.W DIV DUnit); eh := SHORT(e.H DIV DUnit); w := table DIV lines; wasout := TRUE; keysum := {}; ox := -1; oy := -1; REPEAT Input.Mouse(msg.keys, mx, my); keysum := keysum + msg.keys; Oberon.DrawCursor(Oberon.Mouse,Oberon.Arrow, mx, my); IF  (mx >= msg.X) & (mx < msg.X + table) & (my >= msg.Y) & (my < msg.Y + table)  THEN cx := ((mx -msg.X) DIV w) * w + msg.X; cy := ((my - msg.Y) DIV w) * w + msg.Y; IF  (cx # ox) OR (cy # oy) OR wasout  THEN IF ~wasout THEN Invert(ox, oy, w) END; wasout := FALSE; ox := cx; oy := cy; Invert(ox, oy, w); DrawElemColor(e, (mx - msg.X) DIV w + (lines - (my - msg.Y) DIV w - 1) * lines, msg.X0, msg.Y0, msg.frame) END ELSIF ~wasout THEN DrawElemColor(e, e.value, msg.X0, msg.Y0, msg.frame); Invert(ox, oy, w); wasout := TRUE END; UNTIL msg.keys = {}; IF ~wasout THEN IF ~(MR IN keysum) THEN cx := (mx - msg.X) DIV w; cy := (my - msg.Y) DIV w; col := cx + (lines - cy - 1) * lines END; msg.keys := keysum ELSIF  (mx >= msg.X0) & (mx <= msg.X0 + ew) & (my >= msg.Y0) & (my <= msg.Y0 + eh)  THEN msg.keys := keysum; col := e.value ELSE msg.keys := {ML,MM,MR} END END TrackColors; PROCEDURE Track (e :Elem; msg : TextFrames.TrackMsg); VAR b : Bitmaps.Bitmap; w, h, color : INTEGER; exec : Elems.ExecMsg; BEGIN lines := SHORT(ENTIER(Math.sqrt(e.nrOfCols))); table := (10 + (lines MOD 16) * 2) * lines; w := SHORT(e.W DIV DUnit); h := SHORT(e.H DIV DUnit); msg.X := msg.X0 + tb; msg.Y := msg.Y0 + h + tb; IF (msg.X + table + 2*tb > Display.Width) THEN msg.X := msg.X0 - table - tb + w END; IF (msg.Y0 + h + table + 2*tb > Display.Height) THEN msg.Y := msg.Y - table - 2*tb - h END; b := Bitmaps.New(table+2*tb, table+2*tb); Bitmaps.CopyBlock(Bitmaps.Disp, b, msg.X-tb, msg.Y-tb, table+2*tb, table+2*tb, 0, 0, 0); DrawElem(e, msg.X0, msg.Y0, msg.frame, TRUE); DrawTable(msg.X, msg.Y); TrackColors(e, color, msg); Bitmaps.CopyBlock(b,Bitmaps.Disp, 0,0, table+2*tb, table+2*tb, msg.X-tb, msg.Y-tb, 0); IF ~(MR IN msg.keys) THEN e(Elem).value:= color; DrawElem(e, msg.X0, msg.Y0, msg.frame, FALSE); exec.e := e; exec.x := msg.X0; exec.y := msg.Y0; exec.unload := ML IN msg.keys; exec.f := msg.frame; e.handle(e, exec) ELSE DrawElem(e, msg.X0, msg.Y0, msg.frame, FALSE) END END Track; PROCEDURE HandleAttrMsg (e : Elem; VAR msg : Elems.AttrMsg); BEGIN Elems.Done := TRUE; IF msg.id = Elems.get THEN IF msg.name = "Value" THEN msg.class := Elems.Int; msg.i := e.value ELSIF msg.name = "NrOfColors" THEN msg.class := Elems.String; IF e.nrOfCols = 16 THEN msg.s := "16" ELSE msg.s := "256" END; msg.hasProps := TRUE; (*ELSIF msg.name = "NrOfColors" THEN*) (*msg.class := Elems.Int;*) (*msg.i := e.nrOfCols*) ELSE Elems.Handle(e, msg); END; ELSIF msg.id = Elems.set THEN IF msg.name = "Value" THEN IF msg.class = Elems.Int THEN e.value := SHORT(msg.i) END; IF (e.value < 0) OR (e.value > 256) THEN e.value := 15 END ELSIF msg.name = "NrOfColors" THEN IF msg.class = Elems.Int THEN e.nrOfCols := SHORT(msg.i) ELSIF msg.class = Elems.String THEN IF msg.s[0] = "1" THEN e.nrOfCols := 16 ELSE e.nrOfCols := 256 END END; IF (e.nrOfCols # 16) & (e.nrOfCols # 256) THEN e.nrOfCols := 16 END ELSE Elems.Handle(e, msg) END; ELSIF msg.id = Elems.enum THEN Elems.Handle(e, msg); msg.enum("Value", Elems.Int); msg.enum("NrOfColors", Elems.Int);  ELSIF msg.id = Elems.enumProps THEN IF msg.name = "NrOfColors" THEN msg.enum("16", Elems.String); msg.enum("256", Elems.String) END ELSE Elems.Handle(e, msg) END END HandleAttrMsg; PROCEDURE Handle* (e : Texts.Elem; VAR msg : Texts.ElemMsg); VAR ch : CHAR; copy : Elem; BEGIN WITH e : Elem DO WITH msg : TextFrames.DisplayMsg DO IF ~msg.prepare THEN GU.SetDevice(GU.display); DrawElem(e, msg.X0, msg.Y0, msg.frame, FALSE) END | msg : TextPrinter.PrintMsg DO IF ~msg.prepare THEN GU.SetDevice(GU.printer); DrawElem(e, msg.X0, msg.Y0, NIL, FALSE); GU.SetDevice(GU.display) END | msg : Elems.AttrMsg DO HandleAttrMsg(e, msg) | msg : Texts.CopyMsg DO IF msg.e = NIL THEN NEW(copy); msg.e := copy ELSE copy := msg.e(Elem) END; Elems.CopyElem(e, copy); copy.value := e.value; copy.nrOfCols := e.nrOfCols; msg.e := copy | msg : Texts.IdentifyMsg DO msg.mod:="ColorElems"; msg.proc:="New" | msg : Texts.FileMsg DO Elems.Handle(e, msg); IF msg.id=Texts.load THEN Files.Read(msg.r, ch); (* version -> not yet used *) Files.ReadInt (msg.r, e.value); Files.ReadInt(msg.r, e.nrOfCols) ELSIF msg.id=Texts.store THEN Files.Write(msg.r, 0X); (* version *) Files.WriteInt(msg.r, e.value); Files.WriteInt(msg.r, e.nrOfCols) END | msg : TextFrames.TrackMsg DO Elems.Handle(e, msg); IF msg.keys = {MM} THEN Track(e, msg) END ELSE Elems.Handle(e, msg) END END END Handle; PROCEDURE Init* (e : Elem); BEGIN Elems.Init(e); e.handle := Handle; e.value := 15; e.nrOfCols := 16; e.W := 20 * DUnit; e.H := e.W END Init; PROCEDURE New*; VAR e : Elem; BEGIN NEW(e); Init(e); Texts.new := e END New; PROCEDURE Insert*; VAR e : Elem; m : TextFrames.InsertElemMsg; s : Texts.Scanner; BEGIN NEW(e); Init(e); Elems.GetPar(e, s); IF ~s.eot & (s.class = Texts.Int) THEN e.value := SHORT(s.i); Texts.Scan(s); IF ~s.eot & (s.class = Texts.Int) THEN e.nrOfCols := SHORT(s.i) END END; m.e := e; Viewers.Broadcast(m) END Insert; END ColorElems. System.Free ColorElems ~ ColorElems.Insert "" "" "" 0 0 5 256 ~