(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* *) (* Last modified on Wed Aug 12 23:29:10 PDT 1992 by meehan *) (* modified on Wed Aug 12 17:12:45 PDT 1992 by guarino *) (* modified on Tue Jun 16 13:08:47 PDT 1992 by muller *) (* modified on Mon Jun 15 21:49:39 1992 by mhb *) (* modified on Fri Mar 27 01:58:11 1992 by steveg *) (* modified on Fri Feb 2 14:03:04 PST 1990 by glassman *) (* modified on Sun Jun 5 23:37:29 PDT 1988 by gnelson *) <*PRAGMA LL*> (* A "JoinVBT.T" allows many parent "VBT"s to view the screen of a single child "VBT". One parent's view of the child's domain may overlap with another parent's view, and it might not cover the entire child domain. In this implementation, all of the parents must share an identical "VBT.ScreenType". Any portion of a parent screen that lies outside the "JoinVBT"'s screen will be not get painted, so this should be avoided. The screentype of the join is the common screentype of the parents. Event-time operations on the child are performed on the event-time parent (the parent that last received a mouse click, or an arbitrary parent if none of the current parents got the last mouse click). When the event-time parent changes, all selections held by the old event-time parent are released (if the parents are on different Trestles). These event-time operations are handled by making the parent an "ETAgent" and inserting a filter between the parent and the join. When a parent receives a "VBT.Deleted" code, it removes itself (and the filter). Other miscellaneous codes are handled as an "ETAgent". The value of "v.parent" is "NIL" if the "JoinVBT" "v" has no parents; otherwise it is an arbitrary parent (or rather the filter below the parent---these will not be explicitly mentioned hereafter). Those who are familiar with the rules for using concurrency while reformatting splits will note that two parents of a join may be reformatted concurrently. These reformat procedures may wish to call "MoveParent", "Reshape", or "Redisplay". Therefore, an internal lock is used by the join to serialize these operations; their locking level is "LL <= VBT.mu" instead of "LL = VBT.mu". *) INTERFACE JoinVBT; IMPORT ETAgent, Filter, Rect, VBT; TYPE T <: Public; Public = Filter.T OBJECT METHODS <* LL.sup <= VBT.mu *> init (ch: VBT.T): T END; (* The call "v.init(ch)" initializes "v" as a "JoinVBT" with child "ch", and returns "v". *) TYPE Points = REAL; ParentT <: ParentPublic; ParentPublic = ETAgent.T OBJECT METHODS <* LL.sup <= VBT.mu *> init (join: T; north, west: Points := 0.0): ParentT; <* LL.sup = VBT.mu *> translate (READONLY r: Rect.T): Rect.T; END; (* The call "v.init(join, north, west)" initializes "v" as a "JoinVBT.ParentT" with child "join", and returns "v". The northwest corner of the parent's domain is positioned at point "(north, west)" in "join"'s domain; this will be maintained as the parent is reshaped or rescreened. For a given parent "p", "p.translate(r)" returns the rectangle in "p"'s coordinate space corresponding to "r" in the coordinate space of the child. *) PROCEDURE New (ch: VBT.T): T; <* LL.sup <= VBT.mu *> (* "New(...)" is equivalent to "NEW(T).init(...)". *) PROCEDURE NewParent (v: T; north, west: Points := 0.0): ParentT; <* LL.sup <= VBT.mu *> (* "NewParent(...)" is equivalent to "NEW(ParentT).init(...)". *) PROCEDURE RemParent (v: T; prnt: ParentT); <* LL = VBT.mu *> (* Cause "v" to lose parent "prnt", which is reshaped to "Rect.Empty". Also, "v" is marked for redisplay since "RemParent" can change the screentype of the join. It is a checked runtime error if "prnt" is not a parent of "v". *) PROCEDURE Child (prnt: ParentT): T; <* LL = VBT.mu *> (* Return the "JoinVBT" for which "prnt" is a parent. *) PROCEDURE MoveParent (v: T; prnt: ParentT; north, west: Points); <* LL = share(VBT.mu) *> (* Change the position in "v"'s domain of the northwest corner of parent "prnt" to be "(north, west)" and mark "v" for redisplay. % Note: If you override the reformat method of the % parent of the join with a wrap-around of the procedure % supplied to it by "AddParent", you may be able to make use of % the fact that calling "MoveParent" is a way of notifying the % "JoinVBT" that the parent has changed shape, even if the % northwest corner is not changed from its old value. Note that this procedure has a locking level that allows it to be called from within a parent's "reshape" or "rescreen" method. *) PROCEDURE Succ (v: T; prnt: ParentT): ParentT; <* LL = VBT.mu *> (* Return the successor to parent "prnt" of "v", in front-to-back order. It is a checked runtime error if "prnt" is not a parent of "v". As with "Split.Succ", the successor of "NIL" is the first parent; the successor the last parent is "NIL"; and the successor of "NIL" is "NIL" if "v" has no parents. Note that "Succ(v, NIL), Succ(v, Succ(v, NIL)), ..." is an enumeration of the parents of "v" in front-to-back order. *) END JoinVBT.