| By Guy Watson | Article Rating: |
|
| May 19, 2004 12:00 AM EDT | Reads: |
17,353 |
Part 1 of this article (Vol. 1, issue 3) covered a general introduction to the Extensibility Layer and discussed the fundamental DOM and the relationship between different parts of a Flash document and their associated objects. It introduced the History panel and showed you how to build your own Flash panels. In this installment we take an in-depth look at XML2UI and Flash dialog boxes.
Dialog Boxes - XUL
Some of the Timeline Effects that come pre-installed with Flash MX 2004 allow the user to modify numerous settings to change the outcome of the effect. This is achieved using a dialog box that appears when the Timeline Effect is selected. The dialog box contains a Flash movie control that allows the user to modify the settings of the effect.
The fine engineers at Macromedia have included the ability to provide cross-platform dialog boxes in your Flash extensions. This comes in the form of an XML2UI Engine, which parses and displays dialog boxes, defined using an XML-formatted language called XML2UI. XML2UI is a subset of XUL (www.mozilla.org/projects/xul/xul.html). This article assumes prior knowledge or experience with XML.
Displaying a Dialog Box
Depending on what type of Flash extension you're creating, the XML2UI document is defined in different ways. I discuss the use of XML2UI making the assumption that you are implementing dialog boxes into your commands.
When creating a Flash command that requires some kind of user interaction to configure settings, you define your GUI in a separate XML document with an .xml file extension. This file contains the dialog box definition. XML2UI documents are parsed and displayed by Flash MX 2004, so we have to be able to tell the interpreter to display a dialog box as needed.
In JSFL scripts a method is available that will read the source of a dialog box and then display it; this is called "xmlPanel" and is a method of the document object. As document objects represent Flash documents open in the authoring environment, it's possible to open an XML2UI dialog box only when one or more documents are open in the Flash Authoring Environment. Below is an example of the "xmlPanel" method:
flash.getDocumentDOM().xmlPanel("file:///C:/myGUI.xml");
When this code is executed, the interpreter reads the dialog box definition from the document specified and renders the controls defined in our XML2UI document. The standard operating system interface controls are used, which means that when your XML2UI document is rendered on a Macintosh, the interface controls will look different from when it's rendered on a Windows machine.
Notice the "getDocumentDOM" method of the "flash" object. This method returns the document object for the currently active Flash document.
When the "xmlPanel" method is called, your JSFL script will pause execution until the dialog box is closed.
Dialog Box Definition
You define the interface of your dialog box by writing a structured XML document that includes special XML nodes that Flash will interpret and display. Each XML node represents a particular part of your interface and has attributes that allow you to customize various settings related to that particular element. You can include various nodes in your XML2UI document that represent common interface controls such as textboxes, radio buttons, and checkboxes. When Flash parses your XML2UI document, all the nodes that it understands are interpreted into a visual interface. If you include nodes that Flash doesn't understand or support in your XML2UI document, Flash will just ignore them, as long as these nodes haven't been misspelled. All node names and attribute names must be lowercase. All XML2UI documents begin and end with a "dialog" node:
<dialog>...</dialog>
Inside the "dialog" node you define the layout of your dialog box and the various interface controls you want to display within it.
The "dialog" node has various attributes that you can specify. The "buttons" attribute allows you to specify a combination of system buttons to display in your dialog box. You can include three system buttons: accept, cancel, and help. Define the system buttons you want using a comma-separated list; each item in the list is the name of a system button.
<dialog buttons="accept,help">...</dialog>
This markup will display an empty dialog box with no title that contains two system buttons, "OK" and "Help". Flash lays out system buttons automatically. On both Windows and Macintosh, the buttons are laid out on the bottom row of the dialog box in the standard order for that platform.
If you exclude the three system buttons from your dialog box by not specifying a "buttons" attribute, then it may be troublesome for the user to exit your dialog box; the Escape key will close the dialog box just as if the user had pressed the Cancel button.
To specify a title for your dialog box, add a title attribute to your "dialog" node, the value of which will be the text that Flash uses as the title for your dialog box.
Here is the markup for a dialog box with no title attribute specified (see Image I):
<dialog buttons="accept"> <label value="Enter your name" /> <textbox /> </dialog>
Here is the markup for a dialog box with a title attribute (see Image II):
<dialog title="Enter your name" buttons="accept"> <textbox /> </dialog>
If your title is long make sure your dialog box is wide enough to display it, otherwise the end of your title will be replaced with "...".
Interface Controls
You can include various nodes in your XML2UI document that represent common interface controls. The interface controls that Flash will recognize and display are:
- Listbox
- Radio button
- Checkbox
- Textbox
- Color picker
- Dropdown list
- Slider bar
- Label
- Flash movie
Textbox
The "textbox" node represents an interface control that displays a textbox into which a user can type. Various attributes allow you to define the settings of this particular element. For example, you can specify the maximum number of characters that the user can enter into a textbox. You can also specify whether the textbox can contain more than one line of text, and you can define the default text that is displayed in the textbox:
<textbox maxlength="50" multiline="true" value="Your Address" />
This markup will display a multiline textbox into which the user cannot type more than 50 characters; the default text displayed in it will be "Your Address".
Label
The "label" node should be used regularly in your dialog boxes to clarify the purpose of a particular control. The "label" node has two important attributes; the first is the "value" attribute, which defines the text that will be shown for the label:
<label value="The label text" />
The "control" attribute allows you to associate a label with a particular interface control:
<label value="Enter your name" control="firstName" />
<textbox id="firstName" />
In the above markup, I have associated a label with a textbox by giving the "textbox" node an "id" attribute, and by setting this "id" as the value of the "control" attribute for my label.
Color Picker
It's possible to show a chip of color in your interface that when clicked will expand to display a grid of colors from which the user can select a desired color. Upon selecting the desired color, the color of the chip is updated.
To use a color picker in your dialog box, specify a "colorchip" node. This node has one important attribute, which you can use to define the default hexadecimal color displayed in the chip. The attribute is named "color" and is used as follows:
<dialog title="Color Picker" buttons="accept"> <colorchip color="#FF0000" /> </dialog>
The above markup will display a color picker, set to red (#FF0000) until the user changes it (see Image III).
Button
In addition to the ability to include the three system buttons in your dialog boxes (accept, cancel, help), it's also possible to define your own buttons. To define a button in your dialog box definition use the "button" node. The label that is displayed on your button is defined using the "label" attribute of the "button" node:
<dialog title="Click the button"> <button label="Click me" /> </dialog>
Checkbox
Checkboxes are interface controls that have two possible states, selected and unselected (on/off, 0/1, true/false, yes/no). Checkboxes are generally used to allow the user to choose one or more options from a list of available options. Individual checkboxes can have labels; to specify a label for a checkbox you define the "label" attribute; the label is displayed on the right of the checkbox.
Code I is a sample usage of checkboxes; this markup is rendered as shown in Image IV.
Slider Bar
Slider bars are used to present an option that requires the user to choose an integer value from a specified range, such as a percentage from 0-100. To implement a slider bar into your dialog box, use the "popupslider" node. This node has two required attributes: "minvalue", which is the minimum possible value in the range, and "maxvalue", which is the maximum possible value in the range:
<dialog title="Slider bar example" buttons="accept">
<popupslider minvalue="0" maxvalue="100" />
</dialog>
Radio Buttons
Radio buttons are similar to checkboxes when used individually, as they have two states, selected and unselected (on/off, 1/0, true/false, yes/no). However, in Flash, radio buttons cannot function individually; they have to be a part of a radio button group. The difference between a group of checkboxes and a group of radio buttons is that only one radio button in a group can be selected; selecting another radio button in the group deselects the currently selected option in the group. In a group of checkboxes it is possible to select all of the checkboxes.
To implement a radio button in your interface, you must first define a "radio- group" node, which will contain the individual radio button nodes that are a part of the group.
<radiogroup>...</radiogroup>
Then you can define one or more individual radio buttons group members by adding a "radio" node as a child of the "radiogroup" node.
<radigroup> <radio /> <radio /> </radiogroup>
Radio buttons generally have a label associated with them to display the option they are choosing. To define a label for a radio button you must specify the "label" attribute (see Code II); this markup is rendered as shown in Image V.
Listbox
Listboxes present a selection of options to a user, allowing only one option to be selected. To implement a listbox control into your dialog box you need to define a "listbox node". The "listbox" node contains individual "listitem" nodes, which represent each individual item in the listbox. Each listitem can be assigned a label and a value. The value of the "label" attribute is displayed as the label for the option in the listbox, and the "value" attribute is used to define the value of the listbox as a group when the item is selected (see Code III); this markup is rendered as shown in Image VI.
We have four options, and rather than the user having to scroll to see the options that aren't in view, we can define how many items to display in the viewable area at any one time using the "rows" attribute of the "listbox" node. To view all the items in the listbox without having to scroll, set the value of the "rows" attribute to be the total number of list items in our listbox plus one (see Code IV). Now the dialog box looks like Image VII.
Dropdown List
Dropdown lists show multiple options from which a user can choose one. Dropdown lists and listboxes are similar in function, but a listbox generally takes up more space and a listbox's options are generally not displayed all at once - thus the user has to scroll through the options using a scrollbar in the control. To implement a dropdown list into your dialog box use the "menulist" node, which is a container for individual "menuitem" nodes (see Code V).
To stick to the XUL guidelines you are supposed to place another container inside the "menulist" node. I assume that the next version of Flash will have more support for XUL elements and thus recommend that you adhere to these standards if you want your extensions to work in the future.
The standard states that you should place all "menuitem" nodes inside a "menupop" node; our markup now looks like Code VI. Whether you include it or not, the outcome is the same (see Image VIII).
By default, the dropdown list is empty until an option is selected, but it's possible to specify which menuitem is selected by including a "selected" attribute for the "menuitem" node that you want to be selected. The value can be "true" or "false", where true is selected and false is not selected. Not including the selected attribute is the same as specifying a "false" value (see Code VII).
It is good practice to include the "selected" attribute for each "menuitem" node in your dropdown list (see Code VIII).
Flash Movie
In a Web browser, it's also possible to build dialog boxes using the numerous form tags and input element tags. In the early days it wasn't possible for the state of a form, or the various input elements, to change based upon user input. Dynamic forms became possible with the introduction of DHTML into Web browsers. With XML2UI, it's also not possible to change a form once it has been rendered. Macromedia decided to allow developers to include Flash movies inside a dialog box, thus creating a host of new possibilities (e.g., loading dynamic data into your dialog box from a remote location).
Use a Flash movie control to create dynamic dialog boxes that can change state after they have been rendered. All of the input controls in XML2UI and many more are available in Flash MX 2004 as Flash components. The Flash movie for your dialog box can contain anything; you may just want to have a pretty animation piece in your dialog box, or you may want a little control over the look and feel of your dialog box. You can also have a Flash movie and any of XML2UI's other input controls in the same dialog box.
If you're having trouble writing an XML2UI document, all you need to know is the basic XML to display a Flash movie; then you can build all your dialog boxes in Flash. It's possible for Flash movies displayed in a dialog box to execute JSFL code using the MMExecute function.
I made my own Flash command that opens a dialog box containing a Flash movie. The Flash movie allows the user to browse for files and add them to a list. When the dialog box is closed, a JSFL script is executed for each file that was added to the list, thus enabling batch-scripting by Flash developers.
Image IX shows what my dialog box looks like; I built it using Flash MX 2004 and Flash components. When the "Add File" push button is pressed I execute some JSFL using the MMExecute ActionScript function, which opens a "Select File" dialog box. When the user selects a file, the fileURI is returned to ActionScript via the MMExecute function, and then I add it to the list.
To implement a Flash movie in your dialog box, use the "flash" node, which is not a standard element of XUL:
<dialog title="Batch Run Settings" buttons="accept,cancel" > <flash width="475" src="Batch Run.swf" height="150" id="settings" /> </dialog>
You must include an "src" attribute for all "flash" nodes so that when your dialog box is rendered the interpreter knows where to look for the Flash movie. You must also specify the width and height you want the Flash movie to be displayed at; otherwise it will be displayed at 10 pixels wide by 10 pixels high. The width and height attributes should match those that you would use if you were to display the Flash movie in an HTML page.
Dialog Box Layout
A dialog box will not function correctly if it isn't laid out properly. In XML2UI there are two ways of laying out your dialog boxes: (1) a grid system with rows and columns, or (2) hboxes and vboxes, which automatically lay out their contents horizontally and vertically, respectively (the better option in my opinion).
Grid Layout
To specify a grid to lay out your content, use the "grid" node, which is used to group together a collection of columns and rows. The columns and rows are simply containers and cannot be seen. The columns and/or the rows you specify in your grid are used either as white space or to position interface controls. The "grid" node should contain a "columns" node, a "rows" node, or both:
<grid> <columns>...</columns> <rows>...</rows> </grid>
Inside the "columns" node you define one or more empty "column nodes", and each one adds a new column to your virtual layout grid. Remember that columns run from left to right. It's recommended that you don't place any nodes within your "column" nodes; if you do, then each node contained within a "column" node is placed inside each successive row in the grid. The column with the most child nodes determines the number of rows in each column.
Inside the "rows" node, you define one or more "row" nodes; each one adds a new row to your virtual layout grid. Remember that rows run from top to bottom. Each node contained within a "row" node is placed according to its sequential position; for example, the first child node of a "row" node will be placed in the first column of the grid, and the second child node in the second column of the grid.
To align the contents of a row, you must specify an "align" attribute; its value can be "start", "center", "end", or "baseline".
Code IX is a sample grid that contains two columns, and each column has two rows. This markup is rendered as shown in Image X.
Note: It is good practice to always define your columns first (with a list of empty columns as its children) and then to define your rows, each row containing the interface controls. Also make sure that you define enough empty columns for the amount of interface controls in each row.
Box Layout
Boxes allow you to divide a dialog box into a series of boxes. Interface controls inside a box arrange themselves horizontally or vertically. By combining a series of boxes you can lay out your dialog box in no time, leaving the hard work to the renderer as it decides where the interface controls will be placed. There are two types of boxes: (1) vertical boxes, which lay out their contents one on top of the other, and (2) horizontal boxes, which lay out their contents one next to the other. To lay out your content vertically, use the "vbox" node, which is simply a container node into which you place the nodes of interface controls you want to be arranged vertically (see Code X). This markup produces the dialog box shown in Image XI.
As you can see, the interface controls are stacked on top of each other, from top to bottom, which looks neat, but isn't perfect. However, arranging the interface controls horizontally looks even worse.
To lay out your content horizontally, use the "hbox" node, which is simply a container node into which you place the nodes of interface controls you want to be arranged horizontally (see Code XI). This markup produces the dialog box shown in Image XII.
You can place multiple "vbox" nodes inside an "hbox" node and vice versa, allowing you to vertically arrange multiple groups of horizontally arranged elements (see Code XII). This produces the dialog box shown in Image XIII, which is perfectly arranged.
Which Settings Did the User Choose?
The purpose of displaying a dialog box is to allow the user to change various settings, which will determine how your Flash command will work. Excellent! But how do we determine what choices the user made in the dialog box? The "xmlPanel" method returns an object containing one ore more properties, depending upon how many were defined in the XML2UI document.
You define a property by specifying an "id" attribute for any interface control node; when the dialog box is closed, Flash MX 2004 populates that particular property name with the value that the user chose. All properties of your dialog box and their associated values are grouped together in the object returned from the "xmlPanel" method call. For example, if I specify an "id" attribute as "username" for a textbox node, the object returned from the "xmlPanel" method will contain a property named "username" whose value will be what the user entered into the textbox:
<dialog buttons="accept,cancel"> <textbox id="username"/> </dialog>
There is one property that will always be defined in the object returned by an "xmlPanel" method call; the property is named "dismiss", and it can have one of two possible string values. If the dialog box was closed using the OK button, then the value will be "accept"; however, if the dialog box was closed using the Cancel button, then the value will be "cancel". In addition, if a dialog box is closed using the Cancel button, then only the property "dismiss" will be returned (see Code XIII).
It's easy to get a return value from an XML2UI dialog box that contains any of the basic controls - the color picker, the textbox, or the checkbox - as there is only one option. However, for controls such as the radio button group, list box, and dropdown list, it's a different story. There are numerous options.
In a group of radio buttons only one radio button can be selected, and thus there is only one value to be returned. However, each radio button in the group can have a separate value. To specify a value for a radio button, use the "value" attribute of the radio node; you must also specify an "id" attribute for the "radio-group" that contains the radio buttons, such that when the user makes a choice, the value can be returned to JSFL (see Code XIV). When the dialog box is displayed, the user is presented with a list of options (see Image XIV).
When the dialog box is closed using the OK button, the value that was assigned to the selected radio button is returned as the value for the radio group. If I were to select "Yellow" and then close the dialog box, an object would be returned to JSFL containing two properties, (1) the default "dismiss" property, which will have a value of "accept", and (2) another property called "color" whose value will be "y", as that is the value we assigned to the "Yellow" radio button in the XML2UI document for the dialog box.
The listbox and dropdown list work in exactly the same way; you need to specify an "id" attribute for the "container" node that contains the individual items. Then you assign a "value" attribute to each individual item (see Code XV).
In Code XV, the "listbox" node is the container node; thus, we've given it an "id" attribute. Its children, the "listitem" nodes, are the individual items, and each one has its own "value" attribute.
As always, there's an exception to the rule. It's possible for Flash to pass multiple values back to JSFL in the return object, but it doesn't work in the same way as the other interface controls, as each of the other interface controls will only return one value. To solve this problem Macromedia has created a new ActionScript object, which is available to Flash movies running inside of dialog boxes. This ActionScript object is conveniently named "XMLUI" and it has four methods:
- XMLUI.accept()
- XMLUI.cancel()
- XMLUI.get()
- XMLUI.set()
If you want to customize the look and feel of the OK and Cancel buttons by implementing them into your Flash movie, use these methods as opposed to using the default system buttons.
The "XMLUI.get" method will return the value of a "property" node defined in the XML2UI document that contains the Flash Movie:
XMLUI.get("propertyName");
The return value will always be a string.
The "XMLUI.set" method will change the value of a property node defined in the XML2UI document that contains the Flash movie:
XMLUI.set("propertyName","value")
This method will only accept a string as the value for the "propertyName" argument, and it will only accept a string as the value for the second argument (the "value" argument), thus any ActionScript arrays should be joined using the array.join() method prior to using this method.
I mentioned that the XMLUI.set method could only change the value of a property, which means that the actual property has to be defined in the XML2UI document as well, which makes it impossible to pass any old property back to JSFL from a Flash movie control.
To define a property that you want to be returned back to JSFL from a dialog box, use the XML2UI "property" node.
<dialog title="Batch Run Settings" buttons="accept,cancel" > <flash width="475" src="Batch Run.swf" height="150" id="settings" /> <property id="files" /> </dialog>
The "property" node has two possible attributes. The first, the "id" attribute, is required and defines the name of the property whose value will be included in the return object. The second, the "value" attribute, allows you to define a default value for the property in case that particular one is not set by the Flash movie control.
Using ActionScript in a Flash movie that is in that same dialog box, I can set the value of the files property using:
theFiles=["tester.jpg","tester2.jpg"];
XMLUI.set("file",theFile.join(","));
Then the JSFL script that opened the dialog box will return an object containing two properties when this dialog box is closed. The first is the default "dismiss" property and the second is the "file" property, which will contain a string, concatenated with a comma (,) so I can then split it back into an array using JSFL.
Resources
Published May 19, 2004 Reads 17,353
Copyright © 2004 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Guy Watson
Guy Watson (aka FlashGuru) has been a well-recognized figure in the Flash community for around four years, supporting the community with tutorials and source files, moderating the large Flash community forums, and running his own Flash resource Web site - FlashGuru's MX 101. Guy was one of the two developers that created the award-winning zoom interface for Relevare and now works for Endemol UK, the creative force behind reality television, producing programs such as Big Brother and The Salon. Guy now spends most of his time developing Flash games and applications for high-profile clients such as Channel 5 Television, Ladbrookes, and UK Style.
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe Unveils LiveCycle Enterprise Suite 2 for Deployment in the Cloud
- Adobe Flex Developer Earns $100K in New York City
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Ph.D. in Twitter Anyone?
- Eolas Sues the Internet
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Betas Target RIAs and Cloud Computing
- Special Report on the Emerging Cloud Computing Trend
- Adobe Cans Another 9% of its Workforce
- My Thoughts on Ulitzer
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Ulitzer Live! New Media Conference & Expo
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Cloud Executives Feature on Cloud Computing Expo Power Panel
- Software Flexibility in the Cloud - Part 4 of 5
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Is Microsoft as Free as Open Source?
- Adobe Reader Sued
- Adobe Unveils LiveCycle Enterprise Suite 2 for Deployment in the Cloud
- Where Are RIA Technologies Headed in 2008?
- Cover Story: How to Increase the Frame Rates of Your Flash Movies
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Your First Adobe Flex Application with a ColdFusion Backend
- Adobe Flex 2: Advanced DataGrid
- i-Technology Blog: Death-Knell For "Rich Media? Hardly!
- Adobe/Macromedia - Microsoft, Look Out!
- How To Create a Photo Slide Show ...
- Adobe Flex Interface Customization - Themes, Styles, Skins
- Personal Branding Checklist
- Has the Technology Bounceback Begun?
- "Real-World Flex" by Adobe's Christophe Coenraets



































