(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* *) (* Last modified on Mon Jan 4 14:52:38 PST 1993 by mhb *) (* modified on Wed Aug 5 21:48:47 PDT 1992 by meehan *) (* modified on Tue Jun 16 13:07:58 PDT 1992 by muller *) (* modified on Fri Mar 27 02:59:20 1992 by steveg *) MODULE ZGrowVBT; IMPORT Axis, BtnVBTClass, Cursor, Feedback, Point, Rect, Thread, VBT, VBTClass, ZMoveVBT, ZSplitUtils; <* FATAL Thread.Alerted *> REVEAL T = Public BRANDED OBJECT zChild : VBT.T; rect : Rect.T; stuck : BOOLEAN; shape : ARRAY Axis.T OF VBT.SizeRange; changeW: BOOLEAN; changeE: BOOLEAN; changeN: BOOLEAN; changeS: BOOLEAN; OVERRIDES init := Init; pre := Pre; during := During; END; PROCEDURE Init (v: T; f: Feedback.T): T = BEGIN GetResources(); EVAL ZMoveVBT.T.init (v, f); RETURN v END Init; PROCEDURE Pre (v: T) = BEGIN ZMoveVBT.T.pre (v); IF NOT v.ready THEN RETURN END; v.zChild := ZSplitUtils.FindZChild(v); v.rect := VBT.Domain(v.zChild); v.stuck := FALSE; v.changeE := FALSE; v.changeW := FALSE; v.changeN := FALSE; v.changeS := FALSE; v.shape := VBTClass.GetShapes(v.zChild, FALSE); VBT.SetCage (v, VBT.EmptyCage); (* force a call to During, so cursor gets oriented *) END Pre; PROCEDURE During (v: T; READONLY cd: VBT.PositionRec) = VAR dom := VBT.Domain(v.zChild); pt := cd.cp.pt; rect := v.rect; BEGIN IF Rect.Member(pt, VBT.Domain(VBT.Parent(v.zChild))) THEN (* only grow a child inside of ZSplit's domain *) IF pt.h < rect.west THEN v.changeW := TRUE; v.changeE := FALSE; ELSIF pt.h > rect.east THEN v.changeW := FALSE; v.changeE := TRUE; END; IF pt.v < rect.north THEN v.changeN := TRUE; v.changeS := FALSE; ELSIF pt.v > rect.south THEN v.changeN := FALSE; v.changeS := TRUE; END; v.stuck := (v.changeE OR v.changeW OR v.changeN OR v.changeS); IF v.stuck THEN WITH min = v.shape[Axis.T.Hor].lo, max = v.shape[Axis.T.Hor].hi - 1 DO IF v.changeW THEN rect.east := dom.east; rect.west := pt.h; IF Rect.HorSize(rect) > max THEN rect.west := rect.east - max; ELSIF Rect.HorSize(rect) < min THEN v.changeW := FALSE; rect.west := rect.east - min; END ELSIF v.changeE THEN rect.west := dom.west; rect.east := pt.h; IF Rect.HorSize(rect) > max THEN rect.east := rect.west + max; ELSIF Rect.HorSize(rect) < min THEN v.changeE := FALSE; rect.east := rect.west + min; END END END; WITH min = v.shape[Axis.T.Ver].lo, max = v.shape[Axis.T.Ver].hi - 1 DO IF v.changeN THEN rect.south := dom.south; rect.north := pt.v; IF Rect.VerSize(rect) > max THEN rect.north := rect.south - max; ELSIF Rect.VerSize(rect) < min THEN v.changeN := FALSE; rect.north := rect.south - min; END ELSIF v.changeS THEN rect.north := dom.north; rect.south := pt.v; IF Rect.VerSize(rect) > max THEN rect.south := rect.north + max; ELSIF Rect.VerSize(rect) < min THEN v.changeS := FALSE; rect.south := rect.north + min; END END END END; v.rect := rect; OrientCursor(v, pt); END; ZMoveVBT.MoveAndHighlight(v, v.rect); END During; PROCEDURE OrientCursor (v: T; READONLY pt: Point.T) = CONST Slac = 32; VAR cursor : Cursor.T; cW, cE, cN, cS: BOOLEAN; dW, dE, dN, dS: INTEGER; hSlac, vSlac : INTEGER; BEGIN IF v.stuck THEN cN := v.changeN; cS := v.changeS; cE := v.changeE; cW := v.changeW; ELSE dW := pt.h - v.rect.west; dE := v.rect.east - pt.h; dN := pt.v - v.rect.north; dS := v.rect.south - pt.v; hSlac := MIN(Slac, Rect.HorSize(v.rect) DIV 4); vSlac := MIN(Slac, Rect.VerSize(v.rect) DIV 4); cW := (dW <= dE) AND (dW < dN + hSlac) AND (dW < dS + hSlac); cE := (dE < dW) AND (dE < dN + hSlac) AND (dE < dS + hSlac); cN := (dN <= dS) AND (dN < dW + vSlac) AND (dN < dE + vSlac); cS := (dS < dN) AND (dS < dW + vSlac) AND (dS < dE + vSlac); END; IF cN AND cE THEN cursor := MagnetNE ELSIF cN AND cW THEN cursor := MagnetNW ELSIF cS AND cW THEN cursor := MagnetSW ELSIF cS AND cE THEN cursor := MagnetSE ELSIF cN THEN cursor := MagnetN ELSIF cW THEN cursor := MagnetW ELSIF cS THEN cursor := MagnetS ELSIF cE THEN cursor := MagnetE ELSE cursor := MagnetNE; END; VBT.SetCursor(v, cursor); END OrientCursor; VAR rsrcMu := NEW(MUTEX); rsrcInit := FALSE; MagnetW, MagnetE, MagnetN, MagnetS: Cursor.T; MagnetNW, MagnetNE, MagnetSW, MagnetSE: Cursor.T; PROCEDURE GetResources () = BEGIN LOCK rsrcMu DO IF rsrcInit THEN RETURN END; MagnetW := Cursor.FromName(ARRAY OF TEXT{"XC_left_side"}); MagnetE := Cursor.FromName(ARRAY OF TEXT{"XC_right_side"}); MagnetN := Cursor.FromName(ARRAY OF TEXT{"XC_top_side"}); MagnetS := Cursor.FromName(ARRAY OF TEXT{"XC_bottom_side"}); MagnetNW := Cursor.FromName(ARRAY OF TEXT{"XC_top_left_corner"}); MagnetNE := Cursor.FromName(ARRAY OF TEXT{"XC_top_right_corner"}); MagnetSW := Cursor.FromName(ARRAY OF TEXT{"XC_bottom_left_corner"}); MagnetSE := Cursor.FromName(ARRAY OF TEXT{"XC_bottom_right_corner"}); rsrcInit := TRUE; END END GetResources; BEGIN END ZGrowVBT.