Project 10.2: Dynamic UI Creation


Windows and interfaces in Maya are created with MEL commands. This allows for an incredible amount of flexibility to be built into UI creation scripts. In the following example, we will dynamically build a UI based on the number of lights in the scene. Not only is this simple, but there is no functionality to the script other than the UI. This shows how new functionality can easily be built simply by changing how the user interacts with a command.

Design

The goal of the tool is quite simple, to build a small user interface that allows for the quick selection of any of the lights in the scene. We first begin by roughing out the design on paper, as seen in Figure 10.34.

click to expand
Figure 10.34: Our proposed UI.

iWe then are able to break the design down into its component layout and control pieces. For our example, this step is particularly easy, but this will only aid us in dynamically building the UI. Our breakdown diagram is seen in Figure 10.35.

click to expand
Figure 10.35: Breaking down the UI elements.

Implementation

As with the mass renaming tool, we will begin by creating the basic MEL functionality first. For the Light Window, we simply need to find every light in the scene. All we need to do is use the ls command to build an array of all the light shapes that exist in the scene, and then parse the array to find their parent transform, as in Example 10.36.

Example 10.36: The code to find all the lights in the scene.

 global proc lightWindow ()     {  // build a list of all the light shapes in the scene  string $lights[] = `ls -type "light"`;     string $lightTransforms[];  // parse the array to find the transform   // associated with each light shape  for ($each in $lights)         {         string $parentList[] = `listRelatives                                     -parent $each`;         $lightTransforms[`size $lightTransforms`] =                                     $parentList[0];     }     } 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_10/project_UI02/v01/lightWindow.mel.

Our first goal in the creation of our UI is the creation of the window itself. After closing out the loop that builds the list of transforms, we can add the code seen in Example 10.37.

Example 10.37: Creating a window.

 if (`window -exists lightWindowUI` != 1)         {         window             -maximizeButton 0             -resizeToFitChildren on             -title "Light Window"             -iconName "Light Window"             -menuBar false             -menuBarVisible false             lightWindowUI             ;         showWindow lightWindowUI;         } 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_10/project_UI02/v02/lightWindow.mel.

Each of the flags and arguments were chosen to minimize the amount of screen real estate the UI would occupy. Right now, if the script is run, a small, barely there window would appear. In Example 10.38 we add the column layout, in preparation for the buttons to be added.

Example 10.38: Adding a columnLayout to hold further controls.

 if (`window -exists lightWindowUI` != 1)         {         window             -maximizeButton 0             -resizeToFitChildren on             -title "Light Window"             -iconName "Light Window"             -menuBar false             -menuBarVisible false             lightWindowUI             ;               columnLayout                 -columnAttach "both" 0                 -rowSpacing 1                 -columnWidth 250                 ;          showWindow lightWindowUI;         } 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_10/project_UI02/v03/lightWindow.mel.

For now, we can use an arbitrary width for the column layout, which we can revise later. Now that we have a layout, we start adding controls, seen in Example 10.39. We use a for in loop to add a button for each item held in the array $lightTransforms .

Example 10.39: Adding controls based on dynamic information.

 for ($each in $lightTransforms)                 button; 

If we create a scene with a bunch of lights and run the script, we get something similar to Figure 10.36.

click to expand
Figure 10.36: The results.

We can use the variable to label each button with the name of the light, and to build a command string that is executed when the button is pressed. We also can make the buttons slightly smaller, by changing their height to 20 pixels high; we see this in Example 10.40.

Example 10.40: Using the variable in the creation of the buttons.

 for ($each in $lightTransforms)                 button                     -label $each                     -height 20                     -command ("select -r " + $each); 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_10/project_UI02/v04/lightWindow.mel.

Executing the script at this stage gives us a result similar to Figure 10.37, providing that there are lights in the scene.

click to expand
Figure 10.37: The results with thinner buttons.

Since one of the main goals with this UI is to minimize the amount of screen real estate it occupies, it seems illogical to always have our width set to 250 pixels. At the same time, we will want to account for those artists who have lights called spotlight_which_shines_down_on_the_left_side_of_the_lead_characters_head. We will now tie the width of our window to the length of the longest name of any light.

The first step in this process is to find the longest name of any light, and count the number of characters in that name. We can integrate this into the loop that parses the light list, immediately after finding the name of the parent transform, as seen in Example 10.41.

Example 10.41: Finding the longest name of a light in the scene.

 global proc lightWindow ()     {     string $lights[] = `ls -type "light"`;     string $lightTransforms[];          int $longestName;     for ($each in $lights)         {         string $parentList[] = `listRelatives                                     -parent $each`;         $lightTransforms[`size $lightTransforms`]                                 = $parentList[0];         if (`size $parentList[0]` > $longestName)             $longestName = `size $parentList[0]`;     } 

The test is simple. If the transform name is longer than the number of characters stored in the variable $longestName , the length of that transform s name is assigned to $longestName . Once this value is determined, we can use it in a mathematical statement in the columnLayout to determine the appropriate width for the window, as in Example 10.42.

Example 10.42: Altering the columnLayout command to account for the new information.

 columnLayout         -columnAttach "both" 0         -rowSpacing 1         -columnWidth (($longestName * 6) + 2)         ; 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_10/project_UI02/v05/lightWindow.mel.

This gives us the result seen in Figure 10.38. Smaller and much more efficient, the window is given six pixels of width for each character, as well as two extra pixels to prevent errors if there are no lights in the scene.

click to expand
Figure 10.38: The window width is now based on the names of the lights in the scene.

While this solution works, for scenes with a large numbers of lights the UI becomes unwieldy or even impossible to use, with buttons falling off the screen itself. We will enclose the column layout in a scroll layout, allowing the window to be sized to a reasonable size, yet still have access to all the buttons. While we could use a text scroll field, our goal is a tool to quickly select lights, which the small selection area of the list does not allow. Simply adding a scroll layout will not produce the results we want, as the window does not resize automatically to fit. What we will do is twofold:

  • Only implement the scroll layout when needed. Arbitrarily, we will implement the scroll if there are more than 10 lights in the scene. We could have chosen 5, 15, or 21 ”but we chose 10.

  • Calculate the size of the window based on how many buttons are needed, and whether the scroll is included.

This is shown in Example 10.43.

Example 10.43: Addition of the scrollLayout depending on need.

 global proc lightWindow ()     {     string $lights[] = `ls -type "light"`;     string $lightTransforms[];          int $longestName;          for ($each in $lights)         {         string $parentList[] = `listRelatives                                     -parent $each`;         $lightTransforms[`size $lightTransforms`]                                     = $parentList[0];              if (`size $parentList[0]` > $longestName)             $longestName = `size $parentList[0]`;         }          if(`window -exists lightWindowUI` != 1)         {         int $height=((`size $lightTransforms` * 21) + 35);         int $width = (($longestName * 6) + 1);            if (`size $lightTransforms` > 10)             {             $height = 245;             $width = (($longestName * 6) + 35);             }              window             -maximizeButton 0             -resizeToFitChildren 0             -title "Light Window"             -iconName "Light Window"             -menuBar false             -menuBarVisible false             -widthHeight $width $height             lightWindowUI             ;         if (`size $lightTransforms` > 10)             scrollLayout -horizontalScrollBarThickness 0 ;         columnLayout             -columnAttach "both" 0             -rowSpacing 1             -columnWidth (($longestName * 6) + 2)             ;              for ($each in $lightTransforms)             {              button                 -label $each                 -height 20                 -command ("select -r "                             + $each                             + ";lightWindow;");             }         showWindow lightWindowUI;         }     } 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_10/project_UI02/final/lightWindow.mel.

Executing this code gives the result in Figure 10.39, assuming there are more than 10 lights in the scene.

click to expand
Figure 10.39: The addition of a scrollLayout.



The MEL Companion
The MEL Companion: Maya Scripting for 3D Artists (Charles River Media Graphics)
ISBN: 1584502754
EAN: 2147483647
Year: 2003
Pages: 101

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