123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- MODULE Properties;
- (* THIS IS TEXT COPY OF BlackBox 1.6-rc6 System/Mod/Properties.odc *)
- (* DO NOT EDIT *)
- IMPORT SYSTEM, Kernel, Math, Services, Fonts, Stores, Views, Controllers, Dialog;
- CONST
- (** StdProp.known/valid **)
- color* = 0; typeface* = 1; size* = 2; style* = 3; weight* = 4;
- (** SizeProp.known/valid **)
- width* = 0; height* = 1;
- (** PollVerbsMsg limitation **)
- maxVerbs* = 16;
- (** PollPickMsg.mark, PollPick mark **)
- noMark* = FALSE; mark* = TRUE;
- (** PollPickMsg.show, PollPick show **)
- hide* = FALSE; show* = TRUE;
- TYPE
- Property* = POINTER TO ABSTRACT RECORD
- next-: Property; (** property lists are sorted **) (* by TD address *)
- known*, readOnly*: SET; (** used for polling, ignored when setting properties **)
- valid*: SET
- END;
- StdProp* = POINTER TO RECORD (Property)
- color*: Dialog.Color;
- typeface*: Fonts.Typeface;
- size*: INTEGER;
- style*: RECORD val*, mask*: SET END;
- weight*: INTEGER
- END;
- SizeProp* = POINTER TO RECORD (Property)
- width*, height*: INTEGER
- END;
- (** property messages **)
- Message* = Views.PropMessage;
- PollMsg* = RECORD (Message)
- prop*: Property (** preset to NIL **)
- END;
- SetMsg* = RECORD (Message)
- old*, prop*: Property
- END;
- (** preferences **)
- Preference* = ABSTRACT RECORD (Message) END;
- ResizePref* = RECORD (Preference)
- fixed*: BOOLEAN; (** OUT, preset to FALSE **)
- horFitToPage*: BOOLEAN; (** OUT, preset to FALSE **)
- verFitToPage*: BOOLEAN; (** OUT, preset to FALSE **)
- horFitToWin*: BOOLEAN; (** OUT, preset to FALSE **)
- verFitToWin*: BOOLEAN; (** OUT, preset to FALSE **)
- END;
- SizePref* = RECORD (Preference)
- w*, h*: INTEGER; (** OUT, preset to caller's preference **)
- fixedW*, fixedH*: BOOLEAN (** IN **)
- END;
- BoundsPref* = RECORD (Preference)
- w*, h*: INTEGER (** OUT, preset to (Views.undefined, Views.undefined) **)
- END;
- FocusPref* = RECORD (Preference)
- atLocation*: BOOLEAN; (** IN **)
- x*, y*: INTEGER; (** IN, valid iff atLocation **)
- hotFocus*, setFocus*: BOOLEAN (** OUT, preset to (FALSE, FALSE) **)
- END;
- ControlPref* = RECORD (Preference)
- char*: CHAR; (** IN **)
- focus*: Views.View; (** IN **)
- getFocus*: BOOLEAN; (** OUT, valid if (v # focus), preset to ((char = [l]tab) & "FocusPref.setFocus") **)
- accepts*: BOOLEAN (** OUT, preset to ((v = focus) & (char # [l]tab)) **)
- END;
-
- TypePref* = RECORD (Preference)
- type*: Stores.TypeName; (** IN **)
- view*: Views.View (** OUT, preset to NIL **)
- END;
-
- (** verbs **)
- PollVerbMsg* = RECORD (Message)
- verb*: INTEGER; (** IN **)
- label*: ARRAY 64 OF CHAR; (** OUT, preset to "" **)
- disabled*, checked*: BOOLEAN (** OUT, preset to FALSE, FALSE **)
- END;
-
- DoVerbMsg* = RECORD (Message)
- verb*: INTEGER; (** IN **)
- frame*: Views.Frame (** IN **)
- END;
-
-
- (** controller messages **)
- CollectMsg* = RECORD (Controllers.Message)
- poll*: PollMsg (** OUT, preset to NIL **)
- END;
- EmitMsg* = RECORD (Controllers.RequestMessage)
- set*: SetMsg (** IN **)
- END;
- PollPickMsg* = RECORD (Controllers.TransferMessage)
- mark*: BOOLEAN; (** IN, request to mark pick target **)
- show*: BOOLEAN; (** IN, if mark then show/hide target mark **)
- dest*: Views.Frame (** OUT, preset to NIL, set if PickMsg is acceptable **)
- END;
- PickMsg* = RECORD (Controllers.TransferMessage)
- prop*: Property (** set to picked properties by destination **)
- END;
- VAR era-: INTEGER; (* estimator to cache standard properties of focus *)
- PROCEDURE ^ IntersectSelections* (a, aMask, b, bMask: SET; OUT c, cMask: SET; OUT equal: BOOLEAN);
- (** properties **)
- PROCEDURE (p: Property) IntersectWith* (q: Property; OUT equal: BOOLEAN), NEW, ABSTRACT;
- PROCEDURE (p: StdProp) IntersectWith* (q: Property; OUT equal: BOOLEAN);
- VAR valid: SET; c, m: SET; eq: BOOLEAN;
- BEGIN
- WITH q: StdProp DO
- valid := p.valid * q.valid; equal := TRUE;
- IF p.color.val # q.color.val THEN EXCL(valid, color) END;
- IF p.typeface # q.typeface THEN EXCL(valid, typeface) END;
- IF p.size # q.size THEN EXCL(valid, size) END;
- IntersectSelections(p.style.val, p.style.mask, q.style.val, q.style.mask, c, m, eq);
- IF m = {} THEN EXCL(valid, style)
- ELSIF (style IN valid) & ~eq THEN p.style.mask := m; equal := FALSE
- END;
- IF p.weight # q.weight THEN EXCL(valid, weight) END;
- IF p.valid # valid THEN p.valid := valid; equal := FALSE END
- END
- END IntersectWith;
- PROCEDURE (p: SizeProp) IntersectWith* (q: Property; OUT equal: BOOLEAN);
- VAR valid: SET;
- BEGIN
- WITH q: SizeProp DO
- valid := p.valid * q.valid; equal := TRUE;
- IF p.width # q.width THEN EXCL(valid, width) END;
- IF p.height # q.height THEN EXCL(valid, height) END;
- IF p.valid # valid THEN p.valid := valid; equal := FALSE END
- END
- END IntersectWith;
- (** property collection and emission **)
- PROCEDURE IncEra*;
- BEGIN
- INC(era)
- END IncEra;
- PROCEDURE CollectProp* (OUT prop: Property);
- VAR msg: CollectMsg;
- BEGIN
- msg.poll.prop := NIL;
- Controllers.Forward(msg);
- prop := msg.poll.prop
- END CollectProp;
- PROCEDURE CollectStdProp* (OUT prop: StdProp);
- (** post: prop # NIL, prop.style.val = prop.style.val * prop.style.mask **)
- VAR p: Property;
- BEGIN
- CollectProp(p);
- WHILE (p # NIL) & ~(p IS StdProp) DO p := p.next END;
- IF p # NIL THEN
- prop := p(StdProp); prop.next := NIL
- ELSE
- NEW(prop); prop.known := {}
- END;
- prop.valid := prop.valid * prop.known;
- prop.style.val := prop.style.val * prop.style.mask
- END CollectStdProp;
- PROCEDURE EmitProp* (old, prop: Property);
- VAR msg: EmitMsg;
- BEGIN
- IF prop # NIL THEN
- msg.set.old := old; msg.set.prop := prop;
- Controllers.Forward(msg)
- END
- END EmitProp;
- PROCEDURE PollPick* (x, y: INTEGER;
- source: Views.Frame; sourceX, sourceY: INTEGER;
- mark, show: BOOLEAN;
- OUT dest: Views.Frame; OUT destX, destY: INTEGER);
- VAR msg: PollPickMsg;
- BEGIN
- ASSERT(source # NIL, 20);
- msg.mark := mark; msg.show := show; msg.dest := NIL;
- Controllers.Transfer(x, y, source, sourceX, sourceY, msg);
- dest := msg.dest; destX := msg.x; destY := msg.y
- END PollPick;
- PROCEDURE Pick* (x, y: INTEGER; source: Views.Frame; sourceX, sourceY: INTEGER;
- OUT prop: Property);
- VAR msg: PickMsg;
- BEGIN
- ASSERT(source # NIL, 20);
- msg.prop := NIL;
- Controllers.Transfer(x, y, source, sourceX, sourceY, msg);
- prop := msg.prop
- END Pick;
- (** property list construction **)
- PROCEDURE Insert* (VAR list: Property; x: Property);
- VAR p, q: Property; ta: INTEGER;
- BEGIN
- ASSERT(x # NIL, 20); ASSERT(x.next = NIL, 21); ASSERT(x # list, 22);
- ASSERT(x.valid - x.known = {}, 23);
- IF list # NIL THEN
- ASSERT(list.valid - list.known = {}, 24);
- ASSERT(Services.TypeLevel(list) = 1, 25)
- END;
- ta := SYSTEM.TYP(x^);
- ASSERT(Services.TypeLevel(x) = 1, 26);
- p := list; q := NIL;
- WHILE (p # NIL) & (SYSTEM.TYP(p^) < ta) DO
- q := p; p := p.next
- END;
- IF (p # NIL) & (SYSTEM.TYP(p^) = ta) THEN x.next := p.next ELSE x.next := p END;
- IF q # NIL THEN q.next := x ELSE list := x END
- END Insert;
- PROCEDURE CopyOfList* (p: Property): Property;
- VAR q, r, s: Property; t: Kernel.Type;
- BEGIN
- q := NIL; s := NIL;
- WHILE p # NIL DO
- ASSERT(Services.TypeLevel(p) = 1, 20);
- t := Kernel.TypeOf(p); Kernel.NewObj(r, t); ASSERT(r # NIL, 23);
- SYSTEM.MOVE(p, r, t.size);
- r.next := NIL;
- IF q # NIL THEN q.next := r ELSE s := r END;
- q := r; p := p.next
- END;
- RETURN s
- END CopyOfList;
- PROCEDURE CopyOf* (p: Property): Property;
- VAR r: Property; t: Kernel.Type;
- BEGIN
- IF p # NIL THEN
- ASSERT(Services.TypeLevel(p) = 1, 20);
- t := Kernel.TypeOf(p); Kernel.NewObj(r, t); ASSERT(r # NIL, 23);
- SYSTEM.MOVE(p, r, t.size);
- r.next := NIL;
- END;
- RETURN r
- END CopyOf;
- PROCEDURE Merge* (VAR base, override: Property);
- VAR p, q, r, s: Property; tp, tr: INTEGER;
- BEGIN
- ASSERT((base # override) OR (base = NIL), 20);
- p := base; q := NIL; r := override; override := NIL;
- IF p # NIL THEN
- tp := SYSTEM.TYP(p^);
- ASSERT(Services.TypeLevel(p) = 1, 21)
- END;
- IF r # NIL THEN
- tr := SYSTEM.TYP(r^);
- ASSERT(Services.TypeLevel(r) = 1, 22)
- END;
- WHILE (p # NIL) & (r # NIL) DO
- ASSERT(p # r, 23);
- WHILE (p # NIL) & (tp < tr) DO
- q := p; p := p.next;
- IF p # NIL THEN tp := SYSTEM.TYP(p^) END
- END;
- IF p # NIL THEN
- IF tp = tr THEN
- s := p.next; p.next := NIL; p := s;
- IF p # NIL THEN tp := SYSTEM.TYP(p^) END
- ELSE
- END;
- s := r.next;
- IF q # NIL THEN q.next := r ELSE base := r END;
- q := r; r.next := p; r := s;
- IF r # NIL THEN tr := SYSTEM.TYP(r^) END
- END
- END;
- IF r # NIL THEN
- IF q # NIL THEN q.next := r ELSE base := r END
- END
- END Merge;
- PROCEDURE Intersect* (VAR list: Property; x: Property; OUT equal: BOOLEAN);
- VAR l, p, q, r, s: Property; plen, rlen, ta: INTEGER; filtered: BOOLEAN;
- BEGIN
- ASSERT((x # list) OR (list = NIL), 20);
- IF list # NIL THEN ASSERT(Services.TypeLevel(list) = 1, 21) END;
- IF x # NIL THEN ASSERT(Services.TypeLevel(x) = 1, 22) END;
- p := list; s := NIL; list := NIL; l := NIL; plen := 0;
- r := x; rlen := 0; filtered := FALSE;
- WHILE (p # NIL) & (r # NIL) DO
- q := p.next; p.next := NIL; INC(plen);
- ta := SYSTEM.TYP(p^);
- WHILE (r # NIL) & (SYSTEM.TYP(r^) < ta) DO
- r := r.next; INC(rlen)
- END;
- IF (r # NIL) & (SYSTEM.TYP(r^) = ta) THEN
- ASSERT(r # p, 23);
- IF l # NIL THEN s.next := p ELSE l := p END;
- s := p;
- p.known := p.known + r.known;
- p.IntersectWith(r, equal);
- filtered := filtered OR ~equal OR (p.valid # r.valid);
- r := r.next; INC(rlen)
- END;
- p := q
- END;
- list := l;
- equal := (p = NIL) & (r = NIL) & (plen = rlen) & ~filtered
- END Intersect;
- (** support for IntersectWith methods **)
- PROCEDURE IntersectSelections* (a, aMask, b, bMask: SET; OUT c, cMask: SET; OUT equal: BOOLEAN);
- BEGIN
- cMask := aMask * bMask - (a / b);
- c := a * cMask;
- equal := (aMask = bMask) & (bMask = cMask)
- END IntersectSelections;
- (** standard preferences protocols **)
- PROCEDURE PreferredSize* (v: Views.View; minW, maxW, minH, maxH, defW, defH: INTEGER;
- VAR w, h: INTEGER);
- VAR p: SizePref;
- BEGIN
- ASSERT(Views.undefined < minW, 20); ASSERT(minW < maxW, 21);
- ASSERT(Views.undefined < minH, 23); ASSERT(minH < maxH, 24);
- ASSERT(Views.undefined <= defW, 26);
- ASSERT(Views.undefined <= defH, 28);
- IF (w < Views.undefined) OR (w > maxW) THEN w := defW END;
- IF (h < Views.undefined) OR (h > maxH) THEN h := defH END;
- p.w := w; p.h := h; p.fixedW := FALSE; p.fixedH := FALSE;
- Views.HandlePropMsg(v, p); w := p.w; h := p.h;
- IF w = Views.undefined THEN w := defW END;
- IF h = Views.undefined THEN h := defH END;
- IF w < minW THEN w := minW ELSIF w > maxW THEN w := maxW END;
- IF h < minH THEN h := minH ELSIF h > maxH THEN h := maxH END
- END PreferredSize;
- (** common resizing constraints **)
- PROCEDURE ProportionalConstraint* (scaleW, scaleH: INTEGER; fixedW, fixedH: BOOLEAN; VAR w, h: INTEGER);
- (** pre: w > Views.undefined, h > Views.undefined **)
- (** post: (E s: s * scaleW = w, s * scaleH = h), |w * h - w' * h'| min! **)
- VAR area: REAL;
- BEGIN
- ASSERT(scaleW > Views.undefined, 22); ASSERT(scaleH > Views.undefined, 23);
- IF fixedH THEN
- ASSERT(~fixedW, 24);
- ASSERT(h > Views.undefined, 21);
- area := h; area := area * scaleW;
- w := SHORT(ENTIER(area / scaleH))
- ELSIF fixedW THEN
- ASSERT(w > Views.undefined, 20);
- area := w; area := area * scaleH;
- h := SHORT(ENTIER(area / scaleW))
- ELSE
- ASSERT(w > Views.undefined, 20); ASSERT(h > Views.undefined, 21);
- area := w; area := area * h;
- w := SHORT(ENTIER(Math.(*L*)Sqrt(area * scaleW / scaleH)));
- h := SHORT(ENTIER(Math.(*L*)Sqrt(area * scaleH / scaleW)))
- END
- END ProportionalConstraint;
- PROCEDURE GridConstraint* (gridX, gridY: INTEGER; VAR x, y: INTEGER);
- VAR dx, dy: INTEGER;
- BEGIN
- ASSERT(gridX > Views.undefined, 20);
- ASSERT(gridY > Views.undefined, 21);
- dx := x MOD gridX;
- IF dx < gridX DIV 2 THEN DEC(x, dx) ELSE INC(x, (-x) MOD gridX) END;
- dy := y MOD gridY;
- IF dy < gridY DIV 2 THEN DEC(y, dy) ELSE INC(y, (-y) MOD gridY) END
- END GridConstraint;
-
- PROCEDURE ThisType* (view: Views.View; type: Stores.TypeName): Views.View;
- VAR msg: TypePref;
- BEGIN
- msg.type := type; msg.view := NIL;
- Views.HandlePropMsg(view, msg);
- RETURN msg.view
- END ThisType;
-
- END Properties.
|