ðþ  Syntax10.Scn.Fnt     Syntax10i.Scn.Fnt  #    õÿÿÿ ¡ ÀÔ StampElems Alloc 15 May 95  7       ,    K   Syntax10b.Scn.Fnt              e            	    !                    	        B                        	                #    ú            d    -           $    u            #    h                    6    K       &    /    „    (    `    Z    “    L    ©
   	        &    G    
        $    >        2    2    ú    #    o           S    `           >               _    W   m    a           j    «   !        á3  MODULE DialogComboBoxes;	(** Markus Knasm…ller 30 Sep 94 -   *)	(* based on PopupElems MF 27.1.92 /MH/CM/MAH/HM *)	IMPORT		Bitmaps, DialogCheckBoxes, DialogFrames, DialogListBoxes, Dialogs, DialogSliders, DialogStaticTexts, DialogTexts, 		Display, Files, Fonts, GraphicUtils, In, Input, MenuViewers, Oberon, Printer, TextFrames, Texts, Viewers;	CONST		mhm = 5; mvm = 2;	(*menu: horizontal margin, vertical margin*)		CR = 0DX; lbH = 100;		MR = 0; MM = 1; ML = 2; cancel = {ML, MM, MR};		W* = 60; H* = 22; minH = 20; downW = 9;		white = 0; grey1 = 12; grey2 = 13; grey3 = 14; black = 15;		TYPE		Item* = POINTER TO ItemDesc;		ItemDesc* = RECORD(Dialogs.ObjectDesc)			menu*: Texts.Text;	(** text of the list box *)			readonly*: BOOLEAN;	(** allows changes of the entry field without using the listbox *) 			selline*: INTEGER;	(** last selected cmd *)			lbHeight*: INTEGER;	(** height of the listbox *)			n: INTEGER;		(** number of lines in the text *)			f: TextFrames.Frame;		END;			ChangeMsg = RECORD (Display.FrameMsg);			x, y: LONGINT;		END;	VAR w0: Texts.Writer;		PROCEDURE Max (x, y: INTEGER): INTEGER;	BEGIN		IF x > y THEN RETURN x ELSE RETURN y END	END Max;		PROCEDURE (b: Item) Copy* (VAR dup: Dialogs.Object);	(** allocates dup and makes a deep copy of o. Before calling this methode dup should be equal NIL *)		VAR x: Item; 	BEGIN		IF dup = NIL THEN NEW (x); dup := x ELSE x := dup(Item) END; 		b.Copy^ (dup); x.menu := TextFrames.Text (""); x.selline := b.selline; x.readonly := b.readonly;		x.lbHeight := b.lbHeight; x.f := TextFrames.NewText (TextFrames.Text (""), 0);	END Copy;	PROCEDURE (b: Item) Load* (VAR r: Files.Rider);	(** reads the object from rider r *)	BEGIN b.Load^ (r); Files.ReadBool (r, b.readonly); Files.ReadInt (r, b.lbHeight);	END Load;	PROCEDURE (b: Item) Store* (VAR r: Files.Rider);	(** writes the object to rider r *)	BEGIN b.Store^ (r); Files.WriteBool (r, b.readonly); Files.WriteInt (r, b.lbHeight);	END Store;	(* graphics *)		PROCEDURE (b: Item) Print* (x, y: INTEGER);	(** prints the object at printer coordinates (x, y) *)		VAR h, w, ox, oy, i, p: INTEGER;	BEGIN  		b.GetPDim (ox, oy, w, h);		IF w > h THEN p := h; DEC (w, h) ELSE p := 0 END;		GraphicUtils.PrintBox (x, y, w, h);		IF p > SHORT (downW DIV Dialogs.dUnit * Dialogs.pUnit) THEN			i := (p - SHORT (downW DIV Dialogs.dUnit * Dialogs.pUnit)) DIV 2;			GraphicUtils.PrintPatternBox (DialogSliders.downArrow, x + w + 1, y, p, p, i, i); 		END	END Print;		PROCEDURE DrawFrame (f1, f: Display.Frame; m: BOOLEAN);		VAR mode: INTEGER;	BEGIN		IF m THEN mode := Display.invert ELSE mode := Display.replace END;		Display.ReplConstC (f1, black, f.X - 1, f.Y, 1, f.H + 1, mode); Display.ReplConstC (f1, white, f.X + f.W, f.Y, 1, f.H + 1, mode);		Display.ReplConstC (f1, white, f.X, f.Y, f.W - 1, 1, mode); Display.ReplConstC (f1, black, f.X, f.Y + f.H, f.W - 1, 1, mode)	END DrawFrame;   	PROCEDURE Adjust (f: TextFrames.Frame; id, dY, y, h: INTEGER);		VAR m: MenuViewers.ModifyMsg;	BEGIN		m.id := id; m.dY := dY; m.Y := y; m.H := 0; f.handle (f, m);		m.id := id; m.dY := dY; m.Y := y; m.H := h; f.handle (f, m);	END Adjust; 		PROCEDURE (b: Item) Draw* (x, y: INTEGER; f: Display.Frame);	(** displays the object at (x, y) in frame f *)		VAR ox, oy, w, h, w1, h1, p, i: INTEGER; pat: Display.Pattern;	BEGIN		INC (x); b.GetDim (ox, oy, w, h); DEC (w, 2); DEC (h);		(* checks wether textframe is visible *)		IF (y + h <= f.Y) OR (y >= f.Y + f.H) OR (x + w <= f.X) OR (x >= f.X + f.W) THEN RETURN END;		(* corrects x and y such that the lower left coordinats of the textframes are visible *)		IF (x < f.X) & (x + w > f.X) THEN w := w - (f.X - x); x := f.X END;			IF (y < f.Y) & (y + h > f.Y) THEN  h := h- (f.Y - y); y := f.Y END;				(* corrects wide and height such that the full textframe can be displayed *)		w1 := f.W - (x - f.X); h1 := f.H - (y - f.Y);		IF w1 < b.f.left THEN RETURN END;			IF w > w1 THEN w := w1 END; IF h > h1 THEN h := h1 END;		IF w < 0 THEN w := 0 END; IF h < 0 THEN h := 0 END;		IF w > h THEN p := h; DEC (w, h) ELSE p := 0 END;				b.f.X := x; b.f.Y := y; b.f.W := w; b.f.H := h; 		Oberon.RemoveMarks (f.X, f.Y, f.W, f.H); DrawFrame (f, b.f, b.selected);		b.f.barW := 0; b.f.left := 3; b.f.right := 3; b.f.bot := 1; b.f.top := 2;  		Adjust (b.f, MenuViewers.extend, 0, b.f.Y + 1, b.f.H - 1);		IF p > downW THEN			i := (p - downW) DIV 2;			GraphicUtils.DrawPatternBox (f, FALSE, DialogSliders.downArrow, x + w + 1, y, p, p, i, i, Display.paint); 		END	END Draw;		PROCEDURE NilNotifier (T: Texts.Text; op: INTEGER; beg, end: LONGINT);	END NilNotifier;		PROCEDURE (b: Item) Popup (x, y, w, h: INTEGER; f: Display.Frame);			VAR 			menuX, menuY, menuW, menuH, p, i, lsp, dsc, sc, pos1, pos2: INTEGER; t1: Texts.Text;			r: Texts.Reader; keys: SET; ch: CHAR; bit: Bitmaps.Bitmap;	BEGIN		IF w > h THEN p := h ELSE p := 0 END;		IF p > downW THEN			i := (p - downW) DIV 2;			GraphicUtils.DrawPatternBox (f, TRUE, DialogSliders.downArrow, x + w - p + 1, y, p, p, i, i, Display.paint); 		END;				menuW := w + 2 * mhm; menuH := Max (b.lbHeight, 40);		IF y - menuH >= 0 THEN menuY := y - menuH		ELSIF y + h + menuH <= Display.Height THEN menuY := y + h		ELSE menuY := 0		END;		IF x + menuW <= Display.Width THEN 			menuX := x		ELSE 			menuX := Max (x + w - menuW, 0)		END;				Oberon.RemoveMarks (menuX, menuY, menuW, menuH);		Oberon.FadeCursor (Oberon.Mouse);		bit := Bitmaps.New (menuW, menuH);		Bitmaps.CopyBlock (Bitmaps.Disp, bit, menuX, menuY, menuW, menuH, 0, 0, 0); sc := b.selline;		GraphicUtils.DrawMenu (NIL, b.menu, sc, b.selline, menuX, menuY, menuW, menuH, Display.replace, b.n, lsp, dsc);		GraphicUtils.TrackMenu (NIL, b.menu, menuX, menuY, menuW, menuH, b.n, lsp, dsc, sc, b.selline);		Oberon.FadeCursor (Oberon.Mouse);		Bitmaps.CopyBlock (bit, Bitmaps.Disp, 0, 0, menuW, menuH, menuX, menuY, 0);				IF p > downW THEN			i := (p - downW) DIV 2;			GraphicUtils.DrawPatternBox (f, FALSE, DialogSliders.downArrow, x + w - p + 1, y, p, p, i, i, Display.paint); 		END;				IF (b.selline > -1) THEN			DialogTexts.GetParText (b.par, b.panel, t1); 			GraphicUtils.Set( r, b.menu, b.selline); pos1 := SHORT (Texts.Pos (r));			WHILE (~ r.eot) & (ch # CR) DO Texts.Read (r, ch) END;			pos2 := SHORT (Texts.Pos (r));			Texts.Save (b.menu, pos1, pos2, w0.buf);			b.f.text.notify := NilNotifier;			Texts.Delete (b.f.text, 0, b.f.text.len); 			b.f.text.notify := TextFrames.NotifyDisplay; Texts.Append (b.f.text, w0.buf);		END;	END Popup;	PROCEDURE (b: Item) SetTitle* (t: Texts.Text);	(** sets the title of the item to t *)	BEGIN b.f.text := t; b.Restore;	END SetTitle;		PROCEDURE (b: Item) GetTitle* (): Texts.Text;	(** returns the title of the item *)	BEGIN RETURN b.f.text	END GetTitle;		PROCEDURE (b: Item) Handle* (f: Display.Frame; VAR msg: Display.FrameMsg);	(** handles messages which were sent to frame f *)		VAR x, y, w, h, p, xh, yh, h1: INTEGER; v: Viewers.Viewer; msg1: Oberon.CopyMsg; 			f1: Display.Frame; cond: BOOLEAN; msg2: ChangeMsg; t1: Texts.Text;	BEGIN			b.Handle^ (f, msg); b.GetDim (x, y, w, h);		IF w > h THEN p := h ELSE p := 0 END;		(* checks textframe is visible *)		WITH f: DialogFrames.Frame DO			yh := f.Y + f.H + y; xh := f.X + x; 			WITH msg: Oberon.InputMsg DO				Oberon.DrawCursor (Oberon.Mouse, Oberon.Arrow, msg.X, msg.Y);				IF (msg.id = Oberon.track) & (p > 0) &							(msg.X >= xh + w - p) & (msg.X <= xh + w) & (msg.Y >= yh) & (msg.Y <= yh + h) & (msg.keys # {}) THEN					b.Popup (xh, yh, w, h, f);					RETURN				END;			ELSE			END;			IF yh < f.Y THEN h1 := h - f.Y + yh ELSE h1 := h END;			IF (yh + h <= f.Y) OR (yh >= f.Y + f.H) OR (xh + w <= f.X) OR (xh >= f.X + f.W) OR (h1 < minH) THEN RETURN END;			IF (b.readonly) & (msg IS Oberon.InputMsg) THEN RETURN END;			IF (f.X <= b.f.X) & (f.X + f.W >= b.f.X) & (f.Y <= b.f.Y) & (f.Y + f.H >= b.f.Y) THEN				IF msg IS TextFrames.UpdateMsg THEN 					IF msg(TextFrames.UpdateMsg).text = b.f.text THEN 						b.f.handle (b.f, msg); msg2.x := f.X; msg2.y := f.Y; Viewers.Broadcast (msg2);						IF (f.X > b.f.X) OR (f.X + f.W < b.f.X) OR (f.Y > b.f.Y) OR (f.Y + f.H < b.f.Y) THEN							b.Draw (f.X + x, f.Y + f.H + y, f); 						END;						IF b.cmd[0] # 0X THEN 							DialogTexts.GetParText (b.par, b.panel, t1);							b.CallCmd (f, Viewers.This (xh, yh), t1) 						END					END 				ELSIF msg IS MenuViewers.ModifyMsg THEN					IF msg(MenuViewers.ModifyMsg).id = MenuViewers.reduce THEN b.Restore END				ELSE 					b.f.handle (b.f, msg); 				END;			ELSE 				cond := FALSE; 				WITH msg: Oberon.InputMsg DO 					IF (msg.id = Oberon.track) & 						(msg.X >= xh) & (msg.X <= xh + w) & (msg.Y >= yh) & (msg.Y <= yh + h) & (msg. keys # {}) THEN cond := TRUE; 					END;					IF msg.id = Oberon.defocus THEN cond := TRUE END				| msg: ChangeMsg DO						b.Draw (f.X + x, f.Y + f.H + y, f);				ELSE  				END;				IF cond THEN 					TextFrames.RemoveCaret (b.f); b.Draw (f.X + x, f.Y + f.H + y, f); b.f.handle (b.f, msg); 				END;			END		ELSE		END; 	END Handle;	PROCEDURE (b: Item) Init*;	(** initialies the object, should be called after allocating the object with NEW *)	BEGIN 		b.Init^; b.menu := TextFrames.Text ("");  b.f := TextFrames.NewText (TextFrames.Text (""), 0);		b.lbHeight := lbH;	END Init; 		PROCEDURE WriteToObjectInt (o: DialogTexts.Item; n: INTEGER);		VAR t: Texts.Text; 	BEGIN		t := o.GetText (); Texts.WriteInt (w0, n, 0); Texts.Append (t, w0.buf);	END WriteToObjectInt;	PROCEDURE (b: Item) Edit*;	(** opens a dialog for editing the properties of the object *)		VAR on: Dialogs.Object; os, t: DialogTexts.Item; s: DialogStaticTexts.Item; c: DialogCheckBoxes.Item; t1: Texts.Text; fnt: Fonts.Font;	BEGIN		b.Edit^; 		NEW (s); s.Init; s.SetDim (2, - 176, 35, 20, FALSE); 		s.SetString ("lbHeight"); fnt := Fonts.This ("Syntax10.Scn.Fnt"); s.SetFont (fnt);		Dialogs.editPanel.Insert (s, FALSE); 		(* ---- *)  ASSERT (Dialogs.res = Dialogs.ok);		NEW (t); t.Init; t.SetDim (38, - 176, 40, 19, FALSE); t.SetName ("LBh");		Dialogs.editPanel.Insert (t, FALSE);		(* ---- *)  ASSERT (Dialogs.res = Dialogs.ok);		WriteToObjectInt (t, b.lbHeight);		NEW (c); c.Init; c.SetDim (195, - 30, 20, 19, FALSE); c.SetName ("RO");		Dialogs.editPanel.Insert (c, FALSE);		(* ---- *)  ASSERT (Dialogs.res = Dialogs.ok);		c.ChangeValue (b.readonly);		NEW (s); s.Init; s.SetDim (215, - 30, 60, 22, FALSE);		s.SetString ("readonly"); fnt := Fonts.This ("Syntax10.Scn.Fnt"); s.SetFont (fnt);		Dialogs.editPanel.Insert (s, FALSE); 		(* ---- *)  ASSERT (Dialogs.res = Dialogs.ok);	END Edit;		PROCEDURE (b: Item) Update* (p: Dialogs.Panel);	(** sets the properties of the object to the values defined in the dialog p opened with Edit *)		VAR o: Dialogs.Object; t1: Texts.Text; s: Texts.Scanner; ch: CHAR; str: ARRAY 64 OF CHAR; i: INTEGER; cond: BOOLEAN;	BEGIN		b.Update^ (p); 		o := p.NamedObject ("LBh"); t1 := o(DialogTexts.Item).GetText ();		Texts.OpenScanner (s, t1, 0); Texts.Scan (s);		i := b.lbHeight;		IF (s.class = Texts.Int) & (s.i # i) THEN b.lbHeight := SHORT (s.i); b.panel.MarkMenu END;		o := p.NamedObject ("RO"); cond := o(DialogCheckBoxes.Item).on;		IF cond # b.readonly THEN b.readonly := cond; b.panel.MarkMenu END	END Update;	PROCEDURE ParText (n: ARRAY OF CHAR; p: Dialogs.Panel; VAR t: Texts.Text);	(* returns the generated parameter t, defined by the text items of panel p, which names are contained in n *)		VAR t0, t1: Texts.Text; s: Texts.Scanner; o: Dialogs.Object;	BEGIN		t := TextFrames.Text (""); t0 := TextFrames.Text ("");		Texts.WriteString (w0, n); Texts.Append (t0, w0.buf);		Texts.OpenScanner (s, t0, 0); Texts.Scan (s);		WHILE (s.class # Texts.Char) OR (s.c # 0X) DO			IF s.class = Texts.Name THEN				o := p.NamedObject (s.s);				IF (o # NIL) & (o IS DialogTexts.Item) THEN					t1 := o(DialogTexts.Item).GetText ();					Texts.Save (t1, 0, t1.len, w0.buf); Texts.WriteString (w0, " ");					Texts.Append (t, w0.buf)				ELSIF (o # NIL) & (o IS Item) THEN					t1 := o(Item).GetTitle ();					Texts.Save (t1, 0, t1.len, w0.buf); Texts.WriteString (w0, " ");					Texts.Append (t, w0.buf)				END			ELSIF s.class = Texts.String THEN				Texts.WriteString (w0, s.s); Texts.Append (t, w0.buf)			END;			Texts.Scan (s)		END	END ParText;	PROCEDURE Insert*;	(** Insert ([name] [x y w h] | ^ ) inserts a combobox - item in the panel containing the caret position *)		VAR x, y, x1, y1, w, h: INTEGER; b: Item; p: Dialogs.Panel; name: ARRAY 64 OF CHAR; 	BEGIN 		NEW (b); 		DialogFrames.GetCaretPosition (p, x, y);		IF (p # NIL) THEN 			b.Init; In.Open; In.Name (name);			IF ~In.Done THEN COPY ("", name); In.Open END;			b.SetName (name); 			In.Int (x1); In.Int (y1); In.Int (w); In.Int (h);			IF ~In.Done THEN x1 := x; y1 := y; w := W; h := H 			ELSE				IF w < 0 THEN w := W END;				IF h < 0 THEN h := H END			END;			b.SetDim (x1, y1, w, h, FALSE); p.Insert (b, FALSE) 		ELSE			Dialogs.res := Dialogs.noPanelSelected		END;		IF Dialogs.res # 0 THEN Dialogs.Error ("DialogComboBoxes") END;	END Insert;BEGIN Texts.OpenWriter (w0); DialogTexts.GetParText := ParTextEND DialogComboBoxes.