Object Hierarchy | Related C++ Class: PPGLayout




The PPGLayout object represents the visual appearance of an object's state when it is inspected. (PPG is a common acronym for Property Page). The layout makes it possible to group objects together, use special controls, hide obsolete parameters, add Buttons and in general create a presentation of an object's state that is pleasing to the eye.

A Layout is modeled in Softimage as a linear list of PPGItem objects. Each PPGItem represents either a parameter in the inspected object, or a special UI item like a Tab or Button. In most cases the layout does not specify hard-coded pixel positions or dimensions for the PPGItems. Instead Softimage automatically draws the controls with a sensible layout. This allows the presentation to change in a pleasing manner when the user resizes the property page. However there is some support for providing hints, for example PPGItem.WidthPercentage, or even explicit sizes via PPGItem.SetAttribute.

Many different controls are available for use on a property page, see siPPGControlType. All controls can be added using PPGLayout.AddItem but convenience methods are provided for some of the most common controls, for example PPGLayout.AddColor.

Practically every built-in Softimage object has its own layout. However, if there is no specific layout, Softimage displays a default layout that lists all the parameters in a simple fashion.

Layouts are remembered in memory while Softimage is running. For internal objects they are reloaded from SPDL files when Softimage restarts. The layout for a CustomProperty object implemented as a PluginItem is defined by implementing the DefineLayout callback.

You cannot directly modify an existing layout structure, apart from adding new items at the end or changing the attributes of items already in the layout. However to modify a layout it is often reasonable to call PPGLayout.Clear and then rebuild the entire layout with the changes included. You can also use the Parameter.Enable method to hide parameters without removing them from the layout.

If the layout is changed from within Logic code (see PPGLayout.Logic) it is necessary to call PPG.Refresh to see the changes take effect.

Normally the layout is associated with an object that remains in the scene. However it is also possible to use this object to define the user interface of a temporary dialog box. For example a script can ask the user to specify some import or export options. This is done in conjunction with a temporary CustomProperty object and the InspectObj command. This approach is demonstrated in the following examples.


AddButton operator AddColor operator AddEnumControl operator AddFCurve operator
AddGroup operator AddItem operator AddRow operator AddSpacer operator
AddStaticText operator AddString operator AddTab operator Clear operator
Delete operator EndGroup operator EndRow operator GetAttribute operator
SetAttribute operator SetViewPosition operator SetViewSize operator  


Count operator Item operator Language operator Logic operator
ViewPosition operator ViewSize operator    


1. JScript Example

        This example demonstrates a typical use of a custom pset with custom layout as a way of 
        collecting some information from the user.
// Step 1: Create a custom pset and define the data on it
var oPSet=ActiveSceneRoot.AddProperty("CustomProperty",false,"Demo") ;
// Color is made up of 4 components
oPSet.AddParameter3( "MyR", siDouble ) ;
oPSet.AddParameter3( "MyG", siDouble ) ;
oPSet.AddParameter3( "MyB", siDouble ) ;
oPSet.AddParameter3( "MyA", siDouble ) ;
oPSet.AddParameter3( "EnumCtrl", siInt4, 4 ) ;
// Step 2: Put the items on the layout with a custom UI
var oPPGLayout = oPSet.PPGLayout ;
oPPGLayout.AddGroup( "Pick a Color" ) ;
var oItem = oPPGLayout.AddColor( "MyR", "",true ) ;
oItem.SetAttribute("NoLabel", true ) ;
oPPGLayout.EndGroup() ;
oPPGLayout.AddEnumControl( "EnumCtrl", new Array( "item 1", 4, "item 2", 6 ), "Choice",  siControlCombo ) ;
// Step 3: Show the user the dialog.  They can change the
// parameter values and then click OK or Cancel
try {
        InspectObj( oPSet, "", "Check out this layout created from scripting", siModal );
        // Step 4: Read the values and do something with them.  Normally this
        //      would be where you call a custom command which does the operation
        Application.LogMessage( "User picked the color (" + oPSet.Parameters("MyR").Value + ","  + oPSet.Parameters("MyG").Value + "," 
                + oPSet.Parameters("MyB").Value + ","  + oPSet.Parameters("MyA").Value + ")" ) ;                
        if ( oPSet.Parameters( "EnumCtrl" ).Value == 4 ) {
                Application.LogMessage( "User selected item 1" ) ;
        } else {
                Application.LogMessage( "User selected item 2" ) ;
} catch( e ) {
        // Tip: rather than using try/catch, you can specify false
        // as the 5th argument to InspectObj and it will not throw an exception
        Application.LogMessage( "User Cancelled" );
//Step 5: Remove the pset now that we are done with it
DeleteObj( oPSet ) ;

2. JScript Example

        A demonstration of the Number Control on a Custom Property Set. The number control 
        normally appears as a [Animation Divot] [Label] [Edit+Slider Control] but this 
        example demonstrates how this appearance can be controlled. It also shows how to 
        change the range of a parameter. All these changes can be made dynamically.
NewScene( null, false ) ;
var oCustomProperty = ActiveSceneRoot.AddProperty( "CustomProperty", false, "NumberControlTester" ) ;
// Add a parameter of type double.  
// It has the min/max values of -1000 to 1000,
// default value of -1.0, and ui range -100 to 100
var oGridParam = oCustomProperty.AddParameter2( "number", siDouble, -1.0, -1000.0, 1000.0, -100.0, 100.0, siClassifUnknown, siPersistable | siAnimatable ) ;
// Add the Edit boxes and other controls that will
// be used to get information from the user
oCustomProperty.AddParameter3( "setLabel", siString, "NewLabel" ) ;
oCustomProperty.AddParameter3( "setNoLabel", siBool, false,null,null,false) ;
oCustomProperty.AddParameter3( "setValueOnly", siBool, false,null,null,false) ;
oCustomProperty.AddParameter3( "setNoSlider", siBool, false,null,null,false) ;
oCustomProperty.AddParameter3( "setThumbWheel", siBool, false,null,null,false) ;
oCustomProperty.AddParameter3( "setTreadmill", siBool, false,null,null,false) ;
oCustomProperty.AddParameter3( "setDecimals", siInt4, 3,0,10,false) ;
oCustomProperty.AddParameter3( "setLabelMinPixels", siInt4, 10,0,300,false) ;
oCustomProperty.AddParameter3( "setLabelPercentage", siInt4, 30,0,100,false) ;
oCustomProperty.AddParameter3( "setCX", siInt4, 0,0,500,false) ;
oCustomProperty.AddParameter3( "setCY", siInt4, 0,0,100,false) ;
oCustomProperty.AddParameter3( "setUIMin", siDouble, -100,-10000,10000,false) ;
oCustomProperty.AddParameter3( "setUIMax", siDouble, 100,-10000,10000,false) ;
oCustomProperty.AddParameter3( "setMin", siDouble, -1000,-10000,10000,false) ;
oCustomProperty.AddParameter3( "setMax", siDouble, 1000,-10000,10000,false) ;
// Build the layout for the test property page
var oLayout = oCustomProperty.PPGLayout
oLayout.AddGroup( "Test Number Parameter" ) ;
        //The logic code will set all the detailed attributes
        oLayout.AddItem( "number" ) ;
oLayout.EndGroup() ;
oLayout.AddGroup( "Display Attributes" ) ;
        oLayout.AddItem( "setLabel","Label" ) ;
        oLayout.AddItem( "setNoLabel","NoLabel" ) ;
        oLayout.AddItem( "setNoSlider","NoSlider" ) ;
        oLayout.AddItem( "setThumbWheel","ThumbWheel" ) ;
        oLayout.AddItem( "setTreadmill","Treadmill" ) ;
        oLayout.AddItem( "setCX","Fixed Width" ) ;
        oLayout.AddItem( "setCY","Fixed Height" ) ;
        oLayout.AddItem( "setDecimals","Decimals" ) ;
        oLayout.AddItem( "setLabelMinPixels","Label Pixels (Min)" ) ;
        oLayout.AddItem( "setLabelPercentage","Label %" ) ;
        oLayout.AddButton( "Update" ) ;
oLayout.EndGroup() ;
// These values actually fundamentally affect the
// parameter itself.
// Note1:You could potentially change the script name
//      but that would break the logic code that depends
//      on the scripting name
// Note2:You can't change the type of a parameter.
//      Instead you could delete and recreate a new parameter
//      dynamically but that is not part of this example
oLayout.AddGroup( "Parameter Attributes" ) ;
        oLayout.AddItem( "setMin" ) ;
        oLayout.AddItem( "setMax" ) ;
        oLayout.AddItem( "setUIMin" ) ;
        oLayout.AddItem( "setUIMax" ) ;
        oLayout.AddButton( "PDefUpdate","Update" ) ;
oLayout.EndGroup() ;
oLayout.Language = "Jscript" ;
oLayout.Logic = NumberControlTester_Update_OnClicked.toString() + 
oLayout.SetAttribute( "LogicPrefix", "NumberControlTester_" ) ;
InspectObj( oCustomProperty ) ;
// This is the logic code
function NumberControlTester_Update_OnClicked()
        var oCustomProperty = PPG.Inspected(0) ;
        var oLayout = oCustomProperty.PPGLayout
        var oPPGItem = oLayout.Item( "number" ) ;
        // Based on the property page items, set the attributes
        // of the control
        oPPGItem.Label = oCustomProperty.setLabel.Value ;
        oPPGItem.SetAttribute( "NoLabel", oCustomProperty.setNoLabel.Value ) ;
        oPPGItem.SetAttribute( "ValueOnly", oCustomProperty.setValueOnly.Value ) ;
        oPPGItem.SetAttribute( "NoSlider", oCustomProperty.setNoSlider.Value ) ;
        oPPGItem.SetAttribute( "Decimals", oCustomProperty.setDecimals.Value ) ;        
        oPPGItem.SetAttribute( "ThumbWheel", oCustomProperty.setThumbWheel.Value ) ;    
        oPPGItem.SetAttribute( "Treadmill", oCustomProperty.setTreadmill.Value ) ;      
        oPPGItem.SetAttribute( "CX", oCustomProperty.setCX.Value ) ;    
        oPPGItem.SetAttribute( "CY", oCustomProperty.setCY.Value ) ;    
        oPPGItem.LabelMinPixels = oCustomProperty.setLabelMinPixels.Value ;
        oPPGItem.LabelPercentage = oCustomProperty.setLabelPercentage.Value ;
        // (There is also a logithmic attribute 
        // but it only works for integer parameters)
        // You need to rebuild the PPG contents to see the changes
        PPG.Refresh() ;
function NumberControlTester_PDefUpdate_OnClicked()
        var oCustomProperty = PPG.Inspected(0) ;
        var oLayout = oCustomProperty.PPGLayout
        var newUIMin = oCustomProperty.setUIMin.Value ;
        var newUIMax = oCustomProperty.setUIMax.Value ;
        var newMin = oCustomProperty.setMin.Value ;
        var newMax = oCustomProperty.setMax.Value ;
        if ( newUIMin > newUIMax ) {
                Logmessage( "UIMin must be less than UIMax!" ) ;
                return ;
        if ( newMax < newUIMax ) {
                Logmessage( "UIMax can't be bigger than Max!" ) ;
                return ;                
        if ( newMin > newUIMin ) {
                Logmessage( "UIMin can't be smaller than Min!" ) ;
                return ;                
        // Call the command with the new parameter ranges
        EditParameterDefinition( oCustomProperty.number.FullName, null, null, newMin, newMax, newUIMin, newUIMax ) ;
        // You need to rebuild the PPG contents to see the changes
        PPG.Refresh() ;

See Also

PPGItem ProjectItem.PPGLayout InspectObj