"3: Window Manager" Public Handlers (for Programmers)
This section is for programmers who want to do things beyond what the
WFS drag and drop behaviors permit you to do. The "3: Window Manager"
behavior contains the below public handlers that are useful for opening,
closing and changing the locZ of windows. The public handlers also permit
developers to move windows and also families of windows around and to
align them.
The public handlers also provide handlers for setting parent-child
relationships between Managers. These last handlers are the most powerful
of the public handlers. Why? Because they go beyond the notion of windows
and menus. WFS is actually not so much about windows and menus as multi-sprite
objects. Being able to set parent-child relationships amongst multi-sprite
objects allows you to combine multi-sprite objects to make larger objects.
To see working code involving these handlers, open up the source DIR
of the demo
and the script window in Director, and do a search on the name of the
handler.
OPENING, CLOSING, AND LOCZ OF WINDOWS
wfsOpenWindow ()
This opens the window whose Manager's spriteNum is the integer managerSpriteNum
and brings it to front. This handler is called by any WFS behaviors
that open windows.
You can call wfsOpenWindow via either of the ways shown below. The
advantage of the second way is that if the manager is not actually
instantiated, no script error will result. That is the only (but notable)
difference between using sprite(x).whatever() and sendSprite(x, #whatever).
sprite(managerSpriteNum).wfsOpenWindow()
or
sendSprite(managerSpriteNum,
#wfsOpenWindow)
wfsBringWindowToFront (doNotBringChildrenToFront)
This brings the window to the front. It is called when the window is
opened. It's also called when you click on a Window Element and you
have the window configured to come to front when clicked. Even if you
don't have it so configured, this handler is called when you click an
Element that has the "6: Handle" behavior attached to it. This handler,
by default, also brings the children to front--in front of the current
window. That is when doNotBringChildrenToFront is not specified or is
VOID. The idea is that children stay in front of their parents. If you
call this handler with a positive integer parameter for doNotBringChildrenToFront,
however, the children will not be brought to front.
sprite(managerSpriteNum).wfsBringWindowToFront()
or
sendSprite(managerSpriteNum,
#wfsBringWindowToFront)
sprite(managerSpriteNum).wfsBringWindowToFront(0)
or
sendSprite(managerSpriteNum,
#wfsBringWindowToFront,
0)
The above also brings the children
to front,but the below does not.
sprite(managerSpriteNum).wfsBringWindowToFront(1)
or
sendSprite(managerSpriteNum,
#wfsBringWindowToFront,
1)
The above brings the window to front
but does not bring the children to front.
The reason the parameter works this way is for backward compatibility.
Version 3 did not have a parameter. The reason the parameter was introduced
was to make it possible to drag a parent window over its children. But
usually you don't want this to happen, ie, usually you want it to behave
as in version 3, which it does if you do not pass a positive integer
parameter.
Version 4.5 makes use of this parameter in this new
feature.
wfsCloseWindow ()
This handler closes the referenced window and all its open descendents
(not just children). It restores the original locZ values and makes
the window invisible. You do not need to call this handler if you use
either the 'Close My Window' behavior or the 'Close
A Window' behavior.
They call this handler.
sprite(managerSpriteNum).wfsCloseWindow()
or
sendSprite(managerSpriteNum,
#wfsCloseWindow)
wfsRestoreWindowLocZ ()
This restores the LocZ of each sprite in the window. It is called in
the wfsCloseWindow handler.
sprite(managerSpriteNum).wfsRestoreWindowLocZ()
or
sendSprite(managerSpriteNum,
#wfsRestoreWindowLocZ)
MOVING WINDOWS, FAMILIES OF WINDOWS, AND ALIGNMENT
To see these handlers used in working code, open up the feature tour
source code in Director and search for the handler name.
wfsCenterMultiSprite ()
This handler moves the referenced window to the center of the stage,
and moves descendant windows (that are configured to be moved with their
parents) accordingly, not necessarily centering them, but moving them
so that their position relative to the centered window is preserved.
This handler first calculates the current position of the window. But
what is that, since the window is really just an aggragate of sprites
with possibly different locations? So it is a bit arbitrary: it defines
the position of the window as the left (horizontal) and top (vertical)
values of the first window element (not the window manager). Hence it
is a good idea to make that window element be the top leftmost element
in the window since, by convention, that is generally what we mean when
we move something to a point. Note that the Window Manager sprite is
not moved.
sprite(managerSpriteNum).wfsCenterMultiSprite()
or
sendSprite(managerSpriteNum,
#wfsCenterMultiSprite)
wfsMoveFamilyBy (deltaPoint)
deltaPoint is a parameter of type Point. This handler moves the referenced
window and its descendent windows (that are configured to be moved with
their parents) by deltaPoint.locH pixels horizontally and deltaPoint.locV
pixels vertically. These can be negative or positive integers or 0.
This handler is recursive; it moves descendants, not just children.
sprite(managerSpriteNum).wfsMoveFamilyBy(deltaPoint)
or
sendSprite(managerSpriteNum,
#wfsMoveFamilyBy,
deltaPoint)
wfsMoveFamilyTo (absolutePoint)
absolutePoint is a parameter of type Point. This handler moves the
top left point of this window to absolutePoint and moves all its descendent
windows (that are configured to be moved with their parents) accordingly
so that they are in the same position relative to the referenced window.
The top left point of this window is considered to be the top left point
of the second window element of the window. This handler is recursive;
it moves descendants, not just children.
sprite(managerSpriteNum).wfsMoveFamilyTo(absolutePoint)
or
sendSprite(managerSpriteNum,
#wfsMoveFamilyTo,
absolutePoint)
wfsMoveMultiSpriteTo (absolutePoint)
absolutePoint is a parameter of type Point. This handler moves this
window to the point specified by absolutePoint. This handler first calculates
the current position of the window. But what is that, since the window
is really just an aggragate of sprites with possibly different locations?
So it is a bit arbitrary: it defines the position of the window as the
left (horizontal) and top (vertical) values of the first window element
(not the window manager). Hence it is a good idea to make that window
element be the top leftmost element in the window since, by convention,
that is generally what we mean when we move something to a point. Note
that the Window Manager sprite is not moved.
sprite(managerSpriteNum).wfsMoveMultiSpriteTo(absolutePoint)
or
sendSprite(managerSpriteNum,
#wfsMoveMultiSpriteTo,
absolutePoint)
wfsMoveMultiSpriteBy (deltaPoint)
deltaPoint is a parameter of type Point. This handler moves the referenced
window and all its window elements by deltaPoint.locH pixels horizontally
and deltaPoint.locV pixels vertically. These can be negative integers
as well as positive or 0. It doesn't move the Window Manager sprite.
sprite(managerSpriteNum).wfsMoveMultiSpriteby(deltaPoint)
or
sendSprite(managerSpriteNum,
#wfsMoveMultiSpriteby,
deltaPoint)
wfsCenterElementLocH (elementSpriteNum)
elementSpriteNum is an integer parameter indicating the spritenum
of the window element to center horizontally. This handler checks where
the regpoint is in elementSpritenum and centers the element horizontally
relative to the window's background, which is assumed to be the first
window element in the window (after the Window Manager, which isn't
considered to be an element of the window).
sprite(managerSpriteNum).wfsCenterElementLocH(elementSpriteNum)
or
sendSprite(managerSpriteNum,
#wfsCenterElementLocH,
elementSpriteNum)
wfsCenterElementLocV (elementSpriteNum)
elementSpriteNum is an integer parameter indicating the spritenum
of the window element to center vertically. This handler checks where
the regpoint is in elementSpritenum and centers the element vertically
relative to the window's background, which is assumed to be the first
window element in the window (after the Window Manager, which isn't
considered to be an element of the window).
sprite(managerSpriteNum).wfsCenterElementLocV(elementSpriteNum)
or
sendSprite(managerSpriteNum,
#wfsCenterElementLocV,
elementSpriteNum)
wfsPositionElementLocVRelative (elementSpritenum, theLocV)
This handler positions the locv of WindowElementSpritenum theLocv
pixels below the window's background, which is assumed to be the first
window element (after the Window Manager).
sprite(managerSpriteNum).wfsPositionElementLocVRelative(elementSpritenum,
theLocV)
or
sendSprite(managerSpriteNum,
#wfsPositionElementLocVRelative,
elementSpritenum,
theLocV)
wfsPositionElementLocVAbsolute (elementSpritenum, theLocV)
This handler positions the locV of windowElementSpritenum at theLocV.
sprite(managerSpriteNum).wfsPositionElementLocVAbsolute(elementSpritenum,
theLocV)
or
sendSprite(managerSpriteNum,
#wfsPositionElementLocVAbsolute,
elementSpritenum,
theLocV)
PARENT-CHILD OPERATIONS
wfsGetParentName ()
This handler returns the name of the parent or "" if it has
no parent.
theName=sprite(managerSpriteNum).wfsGetParentName()
or
theName=sendSprite(managerSpriteNum,
#wfsGetParentName)
wfsGetParentSpriteNum ()
This handler returns the spritenum of the parent or 0 if it has no
parent.
theName=sprite(managerSpriteNum).wfsGetParentSpriteNum()
or
theName=sendSprite(managerSpriteNum,
#wfsGetParentSpriteNum)
wfsSetChild (theChild, moveChildWhenIMove)
See scene 9 in the demo for an example of this handler.
Calling
theResult= sprite(parentSpriteNum).wfsSetChild(theChild,
moveChildWhenIMove)
results in theChild becoming a child multi-sprite of the multi-sprite
with manager spritenum = parentSpriteNum. In other words, theChild becomes
a child of the parent.
Almost like people, a multi-sprite can have many children
but, at most, one parent.
theChild parameter is an integer or string. If it is a string, it denotes
the name of a multi-sprite. If it is an integer, it denotes the spriteNum
of a manager of a multi-sprite.
moveChildWhenIMove is a boolean. If it is TRUE, then
the child will move when the parent is moved. If it is FALSE, then
the
child will not be moved when the parent is moved.
wfsSetChild returns 1 (TRUE) if the operation was successful, and 0
(FALSE) if the operation was not successful and was cancelled. If wfsSetChild
returns 0, that means that the child was identical to the parent (a
child cannot be its own parent) or the child or the parent were not
instantiated or theChild spriteNum <=0 or parentManagerSpritenum
< 0.
We see in the below diagram that a call to wfsSetChild is equivalent
to a call to wfsSetParent, only with the parameters reversed. The moveChildWhenIMove
parameter has been omitted to clarify the main point. The "I"
in 'moveChildWhenIMove' refers to the parent.

A Manager is not allowed to be among its own ancestors. In other words,
a Manager cannot be its own parent or grandparent etc. It would cause
infinite loops when you move or close families of multi-sprites. The
diagram below illustrates how wfsSetChild handles such a situation.

What we see in the above diagram is how the call sprite(G).wfsSetChild(B)
is handled. It does indeed result in B becoming a child of G. But the
parent of B is changed to be G (as you would expect) and, also, D is
no longer a child of B. The relation between B and D has had to be severed,
or B would become its own granddaddy. The above operation returns 1.
The moveChildWhenIMove parameter is omitted from the above diagram to
make the main points clearer.
This handler sets the child's data and also the parent's data, so that
if you want to set a child, this is the only call you need to make.
Note that if the child already has a parent, this handler changes the
parent. A child can have, at most, one parent though a parent can have
multiple children.
See the included .DIR for example usage of wfsSetChild and wfsSetParent.
theResult=sprite(parentManagerSpriteNum).wfsSetChild(theChild,
moveTheChildWhenIMove) or
theResult=sendSprite(parentManagerSpriteNum,
#wfsSetChild,
theChild, moveTheChildWhenIMove)
wfsDeleteChild (theChild )
This handler deletes theChild from the Manager whose spriteNum is parentManagerSpriteNum
(see below), ie, it makes the child no longer a child of the parent
and sets the child so that it has no parent.
This handler returns 1 if the operation was successful, 0 if the operation
was not successful and the operation was cancelled. It will return 0
if theChild is not instantiated or is not a child of the parent.
theChild can be a string or an integer. If it is an integer, it refers
to the spriteNum of the Manager of the child. If it is a string, it
refers to the name of the child.
This handler adjusts data in the child and in the parent Manager, so
if you want to delete a child, this is the only call you need to make.
theResult=sprite(parentManagerSpriteNum).wfsDeleteChild(theChild)
or
theResult=sendSprite(parentManagerSpriteNum,
#wfsDeleteChild,
theChild)
wfsSetParent (theParent, moveWhenParentMoves)
See scene 9
in the demo for an example of this handler.
Calling
theResult= sprite(childSpriteNum).wfsSetParent(theParent,
moveWhenParentMoves)
results in theParent becoming the parent of the multi-sprite managed
by sprite childSpriteNum.
theParent is a string or integer. If it is a string, it is the name
of the proposed parent window or menu. If it is an integer, it is the
spriteNum of the proposed parent window or menu's Manager.
If you want to set the current window or menu to have no parent, then
use theParent="" or theParent=0. Or call wfsDeleteChild.
MoveWhenParentMoves is a boolean indicating whether the current window
should be dragged when its proposed new parent is moved.
A call to wfsSetParent is equivalent to a call to wfsSetChild, only
the parameters are different. In other words, if you make window A
the
parent of window B, that's the same as making window B the child of
window A. Use whichever one you like. See the documentation (above)
on wfsSetChild.
It is more detailed than the documentation on wfsSetParent. In particular,
look at the diagrams.
wfsSetParent returns 1 if the operation was successful, 0 if the operation
was not successful and was cancelled. A Manager is not allowed to be
one of its own ancestors.
A Manager can have, at most, one parent. If the Manager with spritenum=managerSpritenum
already has a parent, then wfsSetParent makes theParent the sole parent.
This handler sets data in both the managerSpritenum and theParent.
You don't need to call any other handlers to set the parent.
theResult=sprite(managerSpriteNum).wfsSetParent(theParent,
moveWhenParentMoves) or
theResult=sendSprite(managerSpriteNum,
#wfsSetParent,
theParent, moveWhenParentMoves)
wfsGetNumberOfChildren ()
This returns an integer indicating the number of children of the multi-sprite
managed by sprite managerSpriteNum.
theReturnValue=sprite(managerSpriteNum).wfsGetNumberOfChildren()
wfsGetChildList ()
This returns a linear list containing the spritenums of the managers
of child multi-sprites. This list is a duplicate of pWFSChildList, a
property of each manager. Since the list is a duplicate of pWFSChildList,
changing it does not change the status of the multi-sprite's children.
theList=sprite(managerSpriteNum).wfsGetChildList()
wfsSetMoveWithParent (theBoolean)
If theBoolean is TRUE (or 1) then wfsSetMoveWithParent sets the manager
to move when its parent moves. If theBoolean is FALSE (or 0) then wfsSetMoveWithParent
sets the manager to not move when its parent moves.
Returns 0 if there is no parent or it is not instantiated. Even so,
should the manager acquire a parent at a later time, wfsSetMoveWithParent(1)
sets it so that it will indeed move with its new parent, should it acquire
one.
Returns 1 otherwise.
theReturnValue=sprite(managerSpriteNum).wfsSetMoveWithParent(theBoolean)
MISCELLANEOUS PUBLIC HANDLERS
wfsGetElementList ()
Returns a duplicate of the element list, a linear list that contains
the spritenums of the elements of the multi-sprite. The first entry
in the list is always the spritenum of the manager of the multi-sprite,
which you shouldn't move.
theList=sprite(managerSpriteNum).wfsGetElementList()
wfsGetElementNamed
(theName, returnList)
FUNCTION
Finds
an element or all elements named theName (within a particular multi-sprite).
If returnList=VOID (or is not specified), then the handler will search
for the first occurrence
amid the elements of the
multi-sprite for an element named theName.
If returnList<>VOID, then the
handler will search for all occurrences of elements named theName (within
a particular multi-sprite). This handler does not look at the names
of managers. It looks at the
names of elements, which in this context
are never managers.
DMX 2004 lets you name
sprites and channels. I looked into those features to see if I could
use them in WFS. But the Director features have problems: they have
to be set during a score recording session (which screws up dynamic
sprites), and dynamic sprites cannot have sprite names. So I thought
I'd implement a WFS
version that I think is far more flexible and useful. It's important
to note that the WFS element naming system is completely independent
of the built in Director channel and sprite naming system. For instance,
if you have named a channel "bobo", that doesn't mean that
the WFS element in that channel is named "bobo".
Also, the names of elements are not the same as the names of Managers.
When you drop the "3: Window Manager" behavior on a sprite,
you must name the Manager. When you drop the "4: Window/Menu
Element" behavior on an element, you don't need to name the element
if you don't want to. Also, Manager names have to be
unique
among
instantiated
Managers.
There
is no such constraint concerning the names of elements. You can have
as many repeats in the names of instantiated elements as you like.
RETURN VALUE
If returnList=VOID (or is unspecified), then
returns an integer indicating the spritenum of the first element in
the multi-sprite named theName. If there is no element named theName,
then the handler returns 0. If returnList <> VOID, then returns
a linear list indicating the spritenums of all elements in the multi-sprite
named theName. Returns the empyty list [ ] if there are no elements
named theName.
PARAMETERS
theName: A string denoting the name of the element
returnList: is an optional parameter.
If returnList=VOID or is unspecified, then the
handler will look for only the first occurrence
of an element
in the multi-sprite named
theName and the handler will return an integer.
If returnList <> VOID, then the handler
will return a linear list indicating the spritenums of elements in
the multi-sprite named theName.
EXAMPLES
Suppose that sprite 5 is a Manager of a multi-sprite, and that two
of its elements, sprites 9 and 11, are named "bobo".
theReturnValue=sprite(5).wfsGetElementNamed("bobo") or
theReturnValue=sendSprite(5,
#wfsGetElementNamed, "bobo")
will return 9
theReturnValue=sprite(5).wfsGetElementNamed("bobo",
1) or
theReturnValue=sendSprite(5,
#wfsGetElementNamed, "bobo",
1)
will return [9, 11]
Suppose that, below, you want to
find the spritenum of an element named "bobo" which you know is part
of
an instantiated
multi-sprite
named "Alice".
AliceSpritenum=wfsGetManagerSpritenum("Alice")
--wfsGetManagerSpritenum is a handler in the "1: prepareMovie" script
boboSpritenum=sendSprite(AliceSpriteNum, #wfsGetElementNamed, "bobo")
SEE ALSO
You set the name of elements when you drop the "4: Window/Menu Element"
behavior on a sprite and you can change the name at run time. That
behavior contains two handlers relevant to element names: wfsGetElementName and wfsSetElementName.
The "1: prepareMovie" script contains a handler also named wfsGetElementNamed.
It will search multiple
multi-sprites for elements with a specified name (in various ways).
This is a bit different from the current handler, because the current
handler searches one particular multi-sprite.
wfsGetIAmVisible ()
This returns a boolean that indicates whether the referenced menu is
currently open. Open is TRUE.
theReturnValue=sprite(managerSpriteNum).wfsGetIAmVisible()
wfsGetWindowRect ()
This returns the rect of the window. What is that? It is the rect of
the background element, which is the first element below the manager.
If the pWFSElementList contains only one entry, 0 is returned.
theReturnValue=sprite(managerSpriteNum).wfsGetWindowRect()
wfsGetBackgroundSpriteNum ()
The background of a multi-sprite is, by WFS convention, defined as
pWFSElementList[2]. In other words, it's the element right after the
manager. If pWFSElementList contains only one entry, 0 is returned.
theReturnValue=sprite(managerSpriteNum).wfsGetBackroundSpriteNum()
|