Custom User Interface (Comparing - Part 4)

The prose in this section is not complete, but here are my rough notes that anybody can build upon.

Table of contents

Types of XSI Windows

The easiest way to get started with custom UI is to try the Custom Property Wizard which will generate basic layout code and call back stubs automatically.

The InspectObj command in XSI will pop up a Property Page. There is an argument that lets you control whether the PPG is modal or not. For example, promptDialog is equiv to InspectObj with modal enabled.

Property Pages (PPG)

These are similar to the Maya Channel Box because they show the Parameters of an Object. However they can also be used for Dialog Boxes.

Each Property Page has a custom layout, with the ability to organize the controls into groups, columns and tabs. Custom Shaders and Custom Operators can specify the exact visual appearance of their Parameters.

SDK users often use a temporary CustomProperty object to create a custom dialog.

Views

Toolbars are a type of XSI View. So are all the common user interface elements such as the Animation Editor, Render Tree and Mixer. These are specified inside XML files and SDK users can create their own custom "Relational Views", which are a way to combine multiple views together. SDK users can also create custom views, via the Custom Display Host feature.

Other UI

It is not necessary to build a custom user interface for asking simple questions to the User.

  • XSIUIToolkit.MsgBox provides similar functionality to confirmDialog
  • XSIInputBox, XSIDialog and PickFolder are useful for quick and easy user interface scripting.

Property Page UI

In Maya controls are not tightly bound to the attributes of an object. For example a control can be added that does not reflect any actual data inside the scene. And controls inside a single window can be bound to attributes from different objects.

XSI Controls are always tied to parameters of a specific object, so changing the state of a control on the screen is always changing the value of a parameter somewhere in the scene. Temporary CustomProperty objects are often used to host controls that do not need to be persisted as scene data. Multiple objects can be shown at the same time within a single window frame. You can group parameters from multiple objects together by creating proxy parameters on a custom property object.

Layout

The default is to show parameters in the order they were defined.

In XSI, nesting of controls into groups and tabs is supported like in Maya. However, you must always refer to the control by its parameter name, and you don’t need to traverse the structure to get to the name. For example, MEL refers to a control foo like “fooExportWnd|fooClmLayout|fooFormatGrp|foo” and XSI would just call it “foo”.

Logic

Maya lets you attach the command/code directly to buttons. XSI calls event code based on naming convention, for example changing ParamX results in function ParamX_OnChanged() being called.

In XSI, you can completely rebuild the layout (or even change the underlying data) from the Logic so that you can build dynamic UI (such as hiding controls depending on the context).

UI Example

This is a simplistic example of a user interface for a custom export tool. Many plug-ins follow this same pattern - a temporary window is used to ask the user some questions, then based on the settings of the UI an export process (not shown in this example) is launched.

User interface for a custom export tool



   if ( `window -exists fooExportWnd` )
           deleteUI fooExportWnd ;
   
   window -title "Export Foo Format" 
          -resizeToFitChildren true fooExportWnd ;
   
   columnLayout -columnAlign left -adjustableColumn true fooClmLayout ;
   
   radioButtonGrp -l "File Format:"
                 -numberOfRadioButtons 2 
                 -labelArray2 "Ascii" "Binary" -sl 1 fooFormatGrp;
   
   floatSliderGrp -label "Zeta Factor" -min 0 -max 100 fooZeta;
   
   rowLayout -numberOfColumns 3 -columnWidth3 50 300 50 myRow ;
   
   text -label "FileName" fooFilelabel;
   textField -width 300 fooFile;
   button -label "..." -command "PickFooFile();";
   
   setParent .. ;
   
   button -label "Export" -command "ExportFoo();";
   
   showWindow fooExportWnd ;
   
   global proc PickFooFile()
   {
          $valFile = `fileDialog` ;
   
          if ( size($valFile) > 0 )
          {
                  textField -edit -fileName $valFile 
                          fooExportWnd|fooClmLayout|myRow|fooFile ;
          }
   }
   
   global proc ExportFoo()
   {
          // Read the values from the UI
   
          $valFooZeta = `floatSliderGrp -query -value 
                     fooExportWnd|fooClmLayout|fooZeta`;	
          print ("Value of valFooZeta " + $valFooZeta );
   	
          //Get the 1-based index of the selected radio button
          $valFrmt = `radioButtonGrp -query -select 
                     fooExportWnd|fooClmLayout|fooFormatGrp`;	
          if ($valFrmt == 2 )
          {
                  print( "Doing a binary export of Foo" ) ;
          }
   
          $valFile = `textField -query -fileName 
                     fooExportWnd|fooClmLayout|myRow|fooFile` ;
   
          if ( size($valFile) == 0 )
          {
                  confirmDialog -title "Missing File" -message "Please enter a file to export to"
                         -button "OK" ;
                  return ;
          }
   
          // Here a real plug-in would actually
          // do the export job
   
          //.....
   
          // Self destruct
          deleteUI fooExportWnd ;
   }

XSI Version



   // Create a temporary custom property 
   // that will hold the user's choices
   var oPPG = XSIFactory.CreateObject("CustomProperty")
   oPPG.Name = "FooSettings" ;

   oPPG.AddParameter3( "Fmt", siString, "Ascii" );
   oPPG.AddParameter3( "Zeta", siFloat, 0, 0, 100,false ) ;
   oPPG.AddParameter3( "File", siString );
   
   oLayout = oPPG.PPGLayout
   
   oLayout.AddEnumControl( "Fmt", 
               Array( "Ascii","Ascii","Binary","Binary" ),
               "File Format:",	siControlRadio ) ;		
   oLayout.AddItem( "Zeta", "Zeta Factor" ) ;
   oLayout.AddItem( "File", "File Name", siControlFilePath ) ;
   oLayout.AddButton( "Export" ) ;
   
   oLayout.Logic = Export_OnClicked.toString() ;
   oLayout.Language = "JScript" ;
   
   InspectObj( oPPG,null,"Export Foo Format" );
   
   function Export_OnClicked()
   {
        zetaVal = PPG.Zeta.Value ;
        
        LogMessage( "Value of zeta " + zetaVal ) ;
        
        if ( PPG.Fmt.Value == "Binary" )
        {
           LogMessage( "Doing a binary export of Foo" ); 
        }
        
        var fileName = PPG.File.Value ;
        
        if ( fileName.length == 0 )
        {
           XSIUIToolkit.MsgBox( "Please select a file to export",
               siMsgOkOnly, "Missing File" ) ;
        }		
        else
        {
               // Here a real plug-in would actually
               // do the export job
               
               // Destroy the Custom Property (optional)
               DeleteObj( PPG.Inspected ) ;

               PPG.Close() ;
        }
   }

See also



This page was last modified 08:44, 5 Apr 2006.
This page has been accessed 22878 times.

© Copyright 2009 Autodesk Inc. All Rights Reserved. Privacy Policy | Legal Notices and Trademarks | Report Piracy