Creating a Window-Based Menu System


When you have limited space, and you want to provide data-driven content, the window-based menu system depicted in Figure 15.5 is one way to go. The window-based menu system makes use of a significant amount of ActionScript, unlike the pop-up menu that you already examined. This provides a great deal of flexibility for the system. The menu system features a collapsible, data-driven menu, along with closeable data-driven content windows. Not only can you maximize and minimize the menu, but also you can move it around on the screen. The menu items are generated dynamically, every time the movie is loaded, so you just have to change a few variable values to add new items to the menu. The menu items cause windows to pop up, complete with dynamic data inside. These pop-up windows can be closed, thus providing even more available space when it might be needed.

Figure 15.5. The window-based menu system makes excellent use of limited space, while providing a data-driven solution for navigation through your content.

graphics/15fig05.gif

Again, as with the pop-up menus , the concept of draggable and collapsible windows is very familiar to most people. This type of menuing system is useful when you want to have more than one piece of information available to your user at one time, for example, when you have items that your user might want to compare and contrast.

You next will go through a series of exercises to create the menu, add some ActionScript to minimize and maximize the menu, add more ActionScript to access the content, and add even more ActionScript to organize the windows containing the content. When you're done with all four exercises, you will have a reusable window-based menu system to which you can add your own content.

Creating a Data-Driven Menu

The first part of the window-based menu system that you will create is the basic menu itself. This menu will be generated each time the movie is run, using ActionScript to assemble graphics and text. You will create an array, or list of variables , to contain the names of the menu items. You then will attach movie clips in the respective X and Y positions , and with the appropriate text, to create the menu.

Exercise 15.2 Making the Menu

In this first exercise, you create the menu using variable values to specify the items listed in the menu.

  1. Open menudrag.fla from the Chapter_15/Assets folder on the CD. (See Figure 15.6.) This movie has two layers , each of which has a single blank keyframe:

    • Actions. This layer has a blank keyframe in frame 1. You are going to add some ActionScript to this layer.

    • Menu. This layer also has a blank keyframe in frame 1. You will add your menu to this layer.

    Figure 15.6. The movie contains two layers.

    graphics/15fig06.gif

  2. Choose Insert > New Symbol. When the Symbol Properties dialog box opens, set Name to Menu and Behavior to Movie Clip. Click OK to enter Symbol-Editing mode for this new symbol.

  3. Name the existing layer in the Menu movie clip Top Bar. Open the Library for your movie and drag an instance of the Top Bar button symbol from the Menu Assets folder onto the Stage. Use the Info panel to position the top-left corner of this symbol at X: 0 and Y: 0.

  4. Make sure you have the instance of the Top Bar button symbol selected and use the Actions panel to add the following ActionScript:

     on (press) {     this.startDrag(false, leftSide, topSide, rightSide, bottomSide);  }  on (release, releaseOutside) {     this.stopDrag();  } 

    This ActionScript adds some drag-and-drop interactivity to the menu. When you press on the Top Bar button, the movie clip that it's inside starts dragging. When you let go of the button, the movie clip stops dragging.

  5. Add a new layer to the Menu movie clip. Name this layer Minimize Button and drag it to the top of the layer stacking order. Add an instance of the Minimize Button symbol from the Buttons folder in the Library to the new Minimize Button layer. Use the Info panel to position this instance of the Minimize Button symbol at X: 182 and Y: 8. (See Figure 15.7.)

    Figure 15.7. Position the Minimize Button symbol.

    graphics/15fig07.gif

  6. Add another layer to this movie clip and name it Actions. Drag the Actions layer to the top of the layer stacking order, select frame 1, and use the Actions panel to add the following ActionScript:

     //Initialize the variables  myHeight = this._height;  myWidth = this._width;  leftSide = 0;  topSide = 0;  rightside = 600-myWidth;  bottomSide = 400-myHeight; 

    You are going to use these variables to constrain the menu when it's dragged around the Stage. You want to do this so that you can't drag the menu right off the edge of the movie. If your menu disappears because it's dragged outside the visible area of the movie, it won't do your users much good!

  7. Choose Edit > Edit Movie to return to the main movie. Select frame 1 of the Menu layer, and add an instance of the Menu movie clip to the Stage. It doesn't matter where you put it.

  8. Choose Control > Test Movie. When you're done, close the Test Movie window and save your file.

    You should be able to drag the Menu movie clip around, but it will be constrained to a bounding box defined by the leftSide, topSide, rightSide, and bottomSide variables. Now that you have the draggable part done, you have to make the menu. This is where things get complicated.

  9. Choose Insert > New Symbol. When the Symbol Properties dialog box opens, set Name to Menu Item and Behavior to Movie Clip. Click OK to enter Symbol-Editing mode.

  10. Name the existing layer in this movie clip background. Add an instance of the Middle Section movie clip from the Menu Assets folder in the Library to this layer and use the Info panel to position its top-left corner at X: 0 and Y: 0. (See Figure 15.8.) Lock the Background layer.

    Figure 15.8. Add an instance of the Middle Section movie clip to the background layer, and then lock the layer.

    graphics/15fig08.gif

  11. Insert a new layer to this movie clip and position it at the top of the layer stacking order. Name your new layer Text. Choose the Text tool and create a text box that's a bit less than the width of the movie clip in the background layer. (See Figure 15.9.) Use the Info, Character, and Text Options panels to give the text box the following settings:

    X: 7

    Y: 3

    Font: _sans

    Font Height: 10

    Font Color: Black

    Bold and Italics: Deselected

    Text Type: Dynamic Text

    Line Type: Single Line

    Variable: Label

    HTML: Selected

    Border/BG and Selectable: Deselected

    Figure 15.9. Add a text box to the Text layer.

    graphics/15fig09.gif

  12. You are going to dynamically attach this Menu Item symbol to your menu, so you need to export it with the movie. You can do this by modifying the settings in the Symbol Linkage Properties dialog box. Right-click or Control-click the Menu Item symbol in the Library and choose Linkage. Set Linkage to Export This Symbol and Identifier to menuItem. Click OK to close the Symbol Linkage Properties dialog box.

  13. Open the Menu movie clip symbol in Symbol-Editing mode. You have to initialize another variable, so add the following ActionScript to frame 1 of the Actions layer, before the existing ActionScript attached to that frame (you should add it after the comment in the first line):

     maxItems = 4; 

    Your ActionScript should now look like this:

     //Initialize the variables  maxItems = 4;  myHeight = this._height;  myWidth = this._width;  leftSide = 0;  topSide = 0;  rightside = 600-myWidth;  bottomSide = 400-myHeight; 
  14. Now you need to add some ActionScript that defines the items in your menu. This consists of an array containing the labels for each item in the menu. You pass the values from this array into the label variable in your Menu Item movie clip. Add the following ActionScript to frame 1 of the Actions layer:

     //Create an array for the menu item labels.  //This array should have a length equal to maxItems.  myLabels = new Array();  myLabels[0] = "Chrissy";  myLabels[1] = "Jody";  myLabels[2] = "Tracy";  myLabels[3] = "Miles"; 

    Note

    You can get the values for your array from an external data source, using loadVariables, so that you don't have to hard-code them in your ActionScript. If your menu needs to be updated by someone who doesn't know Flash, or if you just don't want to have to open up the Flash source file again after the menu is made, you probably should put the data in an external data source and use loadVariables to get it into your menu.

  15. You have all your variables initialized , and you have some text for your menu items. Now you need to generate the menu. To do so, add the following ActionScript to frame 1 of the Actions layer, after the existing ActionScript:

     //Set up the functions to make and hide the menu  function makeMenu () {     for (i=0; i<maxItems; i++) {         this.attachMovie("menuItem", "item"+i, i);          this["item"+i]._x = 0;          this["item"+i]._y = myHeight+(this["item"+i]._height)*i;          this["item"+i].menuID = "menu" + i;          this["item"+i].label = myLabels[i];          menuHeight = this._height;      }  makeMenu(); 

    The makeMenu function contains a for loop, which attaches a movie clip to "this" (an instance of the Menu movie clip). It then sets the _x and _y properties of the attached movie clip. The _x property is 0, so the movie clip will be flush with the left side of the Menu movie clip. The _y property is based on the value of the myHeight variable plus the Menu Item's height multiplied by the current value of i (which is incremented each time the for loop is run). Next the function sets the menuID and label variables in the attached movie clip. Finally a variable called menuHeight is set to be equal to the height of the movie clip after the Menu Item movie clip has been attached.

    You're going to reuse the ActionScript in the makeMenu function; that's why you made it into a function.

  16. Choose Control > Test Movie to see what happens. Your menu should appear on the screen, complete with four labels. (See Figure 15.10.) Save the movie so that you can use it in the next exercise.

    Figure 15.10. The menu is dynamically generated by the ActionScript.

    graphics/15fig10.gif

Notice that when you drag the menu around the movie, you can drag most of it off the button. That's because the bottomSide variable sets the boundary up to be based on the height of the Menu movie clip that's on the Stage. You'll modify that in the next exercise. You also might notice that there's a small gap between each of the menu items. If you set your Magnification (View > Magnification) to 100%, the gaps should disappear.

Maximizing and Minimizing the Menu

In Exercise 15.1, you created a simple pop-up menu that jumped from one frame to another when you opened it. In this data-driven menu system, the menu is dynamically created every time the movie is loaded. You can use ActionScript to disassemble and reassemble the menu every time you want to open it (maximize) and close it (minimize).

Exercise 15.3 Maximizing and Minimizing the Menu

Now that you've made the menu, you have to add some more ActionScript to enable the user to maximize and minimize it.

  1. Make sure you still have menudrag.fla open or open menudrag1.fla from the CD-ROM. Modify the Symbol Linkage Properties for the Bottom Bar movie clip in the Menu Assets folder so that it is exported with the identifier bottomBar.

  2. Select frame 1 of the Actions layer in the Menu movie clip and add the following ActionScript after the for loop in the makeMenu function:

     this.attachMovie("bottomBar", "bottomBar", maxItems+1);  this.bottomBar._x = 0;  this.bottomBar._y = menuHeight;  bottomSide = 400-this._height; 

    This ActionScript attaches an instance of the Bottom Bar movie clip. It then sets the _x and _y properties of the attached movie clip and sets the value of the bottomSide variable to equal the new height of the menu. The new height takes into account all the attached movie clips.

    The makeMenu function should now look like this:

     function makeMenu () {     for (i=0; i<maxItems; i++) {         this.attachMovie("menuItem", "item"+i, i);          this["item"+i]._x = 0;          this["item"+i]._y = myHeight+(this["item"+i]._height)*i;          this["item"+i].menuID = "menu" + i;          this["item"+i].label = myLabels[i];          menuHeight = this._height;      }      this.attachMovie("bottomBar", "bottomBar", maxItems+1);      this.bottomBar._x = 0;      this.bottomBar._y = menuHeight;      bottomSide = 400-this._height;  } 
  3. Test the movie, and close the Test Movie window when you're done.

    The Bottom Bar movie clip is attached to the bottom of the menu, making it look a little nicer. (See Figure 15.11.) As you drag the movie clip around the Stage, you should no longer be able to drag it off the bottom. That's because the bottomSide variable has been modified to account for the new size of the menu.

    Figure 15.11. The addition of the Bottom Bar movie clip makes the menu look a bit nicer.

    graphics/15fig11.gif

  4. Now you need to add another function that will let you "minimize" the menu. This is useful because it frees up some screen space for the rest of your content. Select frame 1 of the Actions layer in the Menu movie clip and add the following ActionScript after the makeMenu function:

     function hideMenu () { for (i=0; i<maxItems; i++) { this["item"+i].removeMovieClip();      }      this.bottomBar._y = myHeight;      bottomSide = 400-this._height;      } 

    This ActionScript creates the hideMenu function, which removes all attached Menu Item movie clips and then modifies the _y property of the Bottom Bar movie clip so that it sits just beneath the Top Bar movie clip.

  5. When you press the Minimize Button in the Menu movie clip for the first time, you want to trigger the hideMenu function. You want to trigger the makeMenu function the next time. Thus, you need to make a toggle that enables you to switch back and forth. To do this, select the instance of the Minimize Button in the Menu movie clip and add the following ActionScript to it:

     on (press) {     if (menuHide) {         menuHide = false;          makeMenu();      } else if (!menuHide) {         menuHide = true;          hideMenu();      }  } 
  6. Select frame 1 of the Actions layer in the Menu movie clip and add one more variable to the top of the ActionScript:

     menuHide = false; 
  7. Test the movie.

You still should have the same functionality that you had before, but now when you click the Minimize button, the menu collapses. (See Figure 15.12.) When you click that button again, the menu reappears. The bottomSide variable changes depending on whether the menu is minimized or maximized, and it changes the bounding box for that draggable menu.

Figure 15.12. You now can minimize the menu.

graphics/15fig12.gif

Accessing the Content

Now that you have an almost-working menu, you have to provide some content for it to access. This content is going to be provided in the form of an array, much like the menu items.

Exercise 15.4 Accessing the Content

You have a menu, but what does it control? Nothing at this point! You need to provide some content and then have the menu open that content in pop-up windows.

  1. Make sure you still have menudrag.fla open, or load menudrag2.fla from the CD-ROM. Choose Insert > New Symbol. When the Symbol Properties dialog box opens, name the new symbol Contents and set its Behavior to Movie Clip. Click OK to enter Symbol-Editing mode.

  2. Name the only layer in the Contents movie clip Background. Locate the Contents Window button in the Contents Assets folder in the Library and drag an instance of it onto the Stage. Use the Info panel to position the top-left corner of this button at X: 0 and Y: 0.

  3. Add a new layer named Text above the Background layer. Use the Text tool to draw a text box in this layer. The text box should take up most of the space designated by the lighter gray area in the Contents Window button. (See Figure 15.13.) Use the Info, Character, and Text Options panels to set the following:

    X: 15

    Y: 30

    Font: _sans

    Font Height: 10

    Font Color: Black

    Bold and Italics: Deselected

    Text Type: Dynamic Text

    Line Type: Multiline

    Variable: text

    HTML and Word Wrap: Selected

    Border/BG and Selectable: Deselected

    Figure 15.13. Add a text box to the Text layer. This text box should take up most of the space designated by the lighter gray area in the Contents Window button.

    graphics/15fig13.gif

  4. Use the Text tool to create another text box in the Text layer. This text box should take up most of the space designated by the darker gray area in the Contents Window button. (See Figure 15.14.) Use the Info, Character, and Text Options panels to set the following:

    X: 7

    Y: 4

    Font: _sans

    Font Height: 10

    Font Color: White

    Bold and Italics: Deselected

    Text Type: Dynamic Text

    Line Type: Single Line

    Variable: label

    HTML, Border/BG and Selectable: Deselected

    Figure 15.14. Add another text box to the Text layer. This text box should take up most of the space designated by the darker gray area in the Contents Window button.

    graphics/15fig14.gif

  5. Add another layer, named Invisible Button, to the top of the layer stacking order. Drag an instance of the Invisible Button symbol from the Buttons folder in the Library onto the Stage in this new layer, and use the Info panel to set the following:

    W: 292

    H: 18

    X: 4

    Y: 4

  6. Select the instance of the Invisible Button and give it the following ActionScript:

     on (press) {     this.startDrag(false, leftSide, topSide, rightSide, bottomSide);  }  on (release, releaseOutside) {     this.stopDrag ();  } 

    This ActionScript should look familiar. You used it before to make your pop-up menu draggable (refer to Exercise 15.1). That's exactly what you're doing here.

  7. Now you have to provide some values for the leftSide, topSide, rightSide, and bottomSide variables that define the bounding box for the startDrag method that you added in the last step. Add a new layer, named Actions, to the Contents movie clip. Add the following ActionScript to frame 1 of this new layer:

     leftSide = 0;  topSide = 0;  rightSide = 600-this._width;  bottomSide = 400-this._height; 
  8. If your users want to close a content window, they should be able to do so. Again, you want to make sure that you make the most effective use of the space available. Providing an option to minimize, or even close, a window when it's no longer needed is one way to do that. Add a layer named Close Button between the Actions and Invisible Button layers. Drag an instance of the Close Button symbol from the Buttons folder in the Library onto the Stage in this layer. (See Figure 15.15.) Use the Info panel to position it at X: 282 and Y: 8 and give the button the following ActionScript:

     on (press) {     if (_root.offsetCount > 0) {         --_root.offsetCount;      }      this.removeMovieClip();  } 
    Figure 15.15. Add the Close Button to the movie clip.

    graphics/15fig15.gif

  9. You are going to use ActionScript to attach instances of the Contents movie clip. Right-click (Windows) or Control-click the Contents movie clip in the Library and select Linkage to open the Symbol Linkage Properties dialog box. Set Linkage to Export This Symbol and set Identifier to contentWindow. Click OK to close the dialog box.

  10. Now you need to initialize some variables in your main timeline, so every instance of the window movie clip that gets added can access them. Choose Edit > Edit Movie and select frame 1 of the Actions layer in the main timeline. To initialize the variables, add the following ActionScript to this frame:

     windowDepth = 100;  offset = 5;  offsetCount = 0; 
  11. Open the Menu movie clip in Symbol-Editing mode. Select frame 1 of the Actions layer, and add the following ActionScript after the ActionScript that builds the myLabels array:

     //Create an array for the contents.  //This array should have a length equal to maxItems.  myContents = new Array();  myContents[0] = "Chrissy is a developer and instructor at <a  href='http://www.figleaf.com'>Fig Leaf Software</a>. She manages  the Macromedia training department when she's not teaching  Generator and Advanced Flash Techniques classes.";  myContents[1] = "Jody is a Producer at <a  href='http://www.figleaf.com'>Fig Leaf Software</a>. She was  responsible for coordinating the production of Inside Flash 5.";  myContents[2] = "Tracy is an Instructor at <a  href='http://www.figleaf.com'>Fig Leaf Software</a>. She teaches  Flash and Dreamweaver.";  myContents[3] = "Miles is an instructor and developer at <a  href='http://www.figleaf.com'>Fig Leaf Software</a>. He teaches,  and uses, Flash, Generator, Dreamweaver, and UltraDev."; 

    Note

    Just as you could use external data for the array that lists the menu items, you can use loadVariables to provide an external data source for the array that lists the contents. This would be useful if someone who doesn't know Flash has to update the menu, or if you don't want to have to open the FLA to update the menu.

  12. You still have to add some ActionScript to pass the values from the array you just created into each of the instances of the Menu Item movie clip. Following the line in the makeMenu movie clip that contains this ActionScript:

     this["item"+i].label = myLabels[i]; 

    add this code:

     this["item"+i].text = myContents[i]; 
  13. Open the Menu Item movie clip in Symbol-Editing mode. Add a new layer, named Actions, to this movie clip and add the following ActionScript to frame 1 of the new layer:

     function loadWindow () {     ++_root.windowDepth;      if (!_root[menuID].isLoaded) {         _root.attachMovie("contentWindow", menuID, _-----         _root.windowDepth);          trace (_root[menuID].rightSide);          _root[menuID].isLoaded = true;          _root[menuID].label = label;          _root[menuID].text = text;          if (_parent._x < _parent.rightSide - _root[menuID]._width)          {             _root[menuID]._x = _parent._x + _parent.myWidth +              (_root.offset*_root.offsetCount);              } else {             _root[menuID]._x = _parent.leftSide +              (_root.offset*_root.offsetCount);          }          if (_parent._y < _parent.bottomSide -         _root[menuID]._height) {             _root[menuID]._y = _parent._y +              (_parent.myHeight*_root.offsetCount);          } else {             _root[menuID]._y = _parent.topSide +              (_parent.myHeight*_root.offsetCount);          }          ++_root.offsetCount;      } else {         _root[menuID].swapDepths(_root.windowDepth);      }  }  label = "<a href='asfunction:loadWindow'>" + this.label + "<//a>";  _root[menuID].isLoaded = false; 

    In this ActionScript, you first create a new function called loadWindow. This function increments the value of windowDepth on the main timeline and then checks whether the isLoaded variable associated with this menuID on the main timeline is false. If it is false, an instance of the Contents movie clip is added, the isLoaded variable associated with this menuID is set to true, and the _x and _y properties of the attached movie clip are set (based on the location of the menu). The value of the offsetCount variable on the main timeline is then incremented. If isLoaded is not false, meaning that an instance of the Contents movie clip with this menuID already has been loaded, that instance of the Contents movie clip is brought to the top of the stacking order using the swapDepths method.

    Next the ActionScript puts the original value of the label inside an anchor tag and uses asfunction to call the loadWindow function. The next line initializes the isLoaded variable on the main timeline (_root).

    Note

    The ActionScript for the loadWindow function is rather extensive . Remember to add the two lines following this function, or your menu system won't work correctly.

  14. Test the movie.

When you click one of the menu items, an instance of the Contents movie clip should appear with the appropriate text inside it. (See Figure 15.16.) You can drag this instance around. You also can close this instance by clicking the Close Window button. When you click a menu item that is already open, that window should jump to the top of the stacking order.

Figure 15.16. Click a menu item to make a Content window appear.

graphics/15fig16.gif

Organizing the Windows

Now that you have a bunch of windows, you need to add some extra functionality so that your users can better control them. You just have to add a little bit of ActionScript that will make any window that you click jump to the top of the stacking order.

Exercise 15.5 Organizing the Windows

This exercise shows you how to make each window jump to the top of the stacking order as it's clicked.

  1. You still should have menudrag.fla open from the last exercise, or you can load menudrag3.fla from the CD-ROM. Open the Contents movie clip in Symbol-Editing mode. Select the instance of the Contents Window button in the Background layer and give it the following ActionScript:

     on (press) {     ++_root.windowDepth;      this.swapDepths(_root.windowDepth);  } 

    This ActionScript increments the value of the windowDepth variable on the main timeline and then sets the depth of the current movie clip to that new value.

  2. Select the instance of the Invisible Button symbol in the Invisible Button layer of the Contents movie clip, and add the following ActionScript after the line containing the startDrag method:

     ++_root.windowDepth;  this.swapDepths(_root.windowDepth); 

    This ActionScript first increments the value of the windowDepth variable that's on the main timeline (_root). Then the swapDepths method sets the depth of the selected instance of the Contents movie clip (this) to the value of the windowDepth variable on the main timeline, which makes the movie clip jump to the top of the stacking order. This occurs whenever you click the Invisible Button in the Contents movie clip.

    The ActionScript for the Invisible Button should now look like this:

     on (press) {     this.startDrag(false, leftSide, topSide, rightSide, bottomSide);      ++_root.windowDepth;      this.swapDepths(_root.windowDepth);  }  on (release, releaseOutside) {     this.stopDrag();  } 
  3. Open the Menu movie clip in Symbol-Editing mode. Select the instance of the Top Bar button in the Top Bar layer and add the following ActionScript to the on (press) event for this button:

     ++_root.windowDepth;  this.swapDepths(_root.windowDepth); 

    This ActionScript does the same as the ActionScript that you added in the last step. You just need to add it to the Top Bar button in the Menu movie clip so that the menu can jump to the top of the stacking order when it's clicked.

    The ActionScript for the Top Bar button should now look like this:

     on (press) {     this.startDrag(false, leftSide, topSide, rightSide, bottomSide);      ++_root.windowDepth;      this.swapDepths(_root.windowDepth);  }  on (release, releaseOutside) {     this.stopDrag();  } 
  4. Test your movie, and save it when you're done.

    When you click any part of a content window, it should bring that window to the top of the stacking order. The same should happen when you click the top bar of the menu window. You can add an Invisible Button under the Text layer of the Menu Item symbol if you want to set up the menu so that it jumps to the top of the stacking order when you click each Menu Item movie clip. (See Figure 15.17.)

    Figure 15.17. When you click a Content window, it jumps to the top of the stacking order.

    graphics/15fig17.gif



Inside Flash
Inside Flash MX (2nd Edition) (Inside (New Riders))
ISBN: 0735712549
EAN: 2147483647
Year: 2005
Pages: 257
Authors: Jody Keating

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net