|  "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") ortheReturnValue=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()   |