Object Hierarchy | Related C++ Class: GridData
v4.0
This object represents a 2-Dimensional array of data. The word
"Grid" refers to the visual presentation of 2-Dimensional data on a
grid control (sometimes called a table or spreadsheet control). The
word "Cell" refers to a single element of the array.
The dimensions of the array can be dynamically resized and many
types of data can be stored as Cell data. The Columns and Rows can
be labelled and it is possible to refer to the data by these label
strings rather than by indices.
There are three main uses for the GridData object. The first is as
the data for a siGridControl on a custom object, see CustomProperty.AddGridParameter.
In this case the user can view and edit the data and the data is
saved inside the scene along with the CustomProperty. This can be
an effective way to store lists, vectors or even arrays of vectors
related to a plug-in. Some aspects of the visual representation of
the GridData object are set directly on the GridData object, for
example GridData.SetColumnType, but most
attributes are set inside the PPGLayout using PPGItem.SetAttribute. siPPGItemAttributes that apply to the
siGridControl include siUIGridColumnWidths and
siUIGridHideRowHeader.
A second possible use of the GridData object is to store hidden
data that is intended for internal use by a plug-in. In this case
it is still part of a CustomProperty but it is not exposed to
the user, which is easily done by not including the GridData
Parameter in the PPGLayout.
The third possible use of this object is as a temporary convenience
object for dealing with 2-Dimensional Arrays. In particular some
scripting languages like JScript do not support 2-Dimensional
arrays in their built-in Array
objects, so the GridData object provides a workaround. You can get
a temporary GridData object by calling XSIFactory.CreateGridData.
GridTester(); function GridTester() { // // A demonstration of the Grid Control on a Custom Property Set. // Controls on the Property Page demonstrate the OM API that // can be used to change the values and even size of the Grid Control // based on Property Page Logic code. // var oPSet = ActiveSceneRoot.AddProperty( "CustomProperty", false, "GridTester" ) ; var oGridParam = oPSet.AddGridParameter( "TestGrid" ) ; // Set up some initial size oGridParam.Value.RowCount = 3 ; oGridParam.Value.ColumnCount = 2 ; // Add the Edit boxes and other controls that will // be used to get information from the user oPSet.AddParameter3( "DimRows", siInt2, 3,null,null,false ) ; oPSet.AddParameter3( "DimCols", siInt2, 2,null,null,false ) ; oPSet.AddParameter3( "CellRow", siInt2, 0,null,null,false ) ; oPSet.AddParameter3( "CellCol", siInt2, 0,null,null,false ) ; oPSet.AddParameter3( "CellValue", siString, "New Value" ) ; oPSet.AddParameter3( "RowToChange", siInt2, 0,null,null,false ) ; oPSet.AddParameter3( "RowValue", siString, "New Value" ) ; oPSet.AddParameter3( "ColToChange", siInt2, 0,null,null,false ) ; oPSet.AddParameter3( "ColValue", siString, "New Value" ) ; oPSet.AddParameter3( "RowLabelToChange", siInt2, 0,null,null,false ) ; oPSet.AddParameter3( "RowLabel", siString, "New Row Label" ) ; oPSet.AddParameter3( "ColLabelToChange", siInt2, 0,null,null,false ) ; oPSet.AddParameter3( "ColLabel", siString, "New Column Label" ) ; oPSet.AddParameter3( "Batch", siBool,false,null,null,false ) ; oPSet.AddParameter3( "ColHeaderMode", siInt2, 0,null,null,false) ; oPSet.AddParameter3( "RowHeaderMode", siInt2, 0,null,null,false) ; oPSet.AddParameter3( "Width", siInt4, 0,null,null,false ) ; oPSet.AddParameter3( "Height", siInt4, 0,null,null,false ) ; oPSet.AddParameter3( "ColWidths", siString, "45;30;50" ) ; oPSet.AddParameter3( "ROCols", siString, "0;1" ) ; // second column read-only be default // Organize the controls on the PPG var oLayout = oPSet.PPGLayout var oPPGItem = oLayout.AddItem( "TestGrid", "",siControlGrid ) ; oPPGItem.SetAttribute( "NoLabel", true ) ; oLayout.AddGroup( "Change Contents Via OM" ) ; oLayout.AddGroup( "Dimensions" ) ; oLayout.AddRow() ; AddNonSliderItem( oLayout, "DimRows", "Rows", 50) ; AddNonSliderItem( oLayout, "DimCols", "Columns", 50) ; oLayout.AddButton( "DimUpdate", "Update" ) ; oLayout.EndRow() ; oLayout.EndGroup(); oLayout.AddGroup( "Cell value" ) ; oLayout.AddRow() ; AddNonSliderItem( oLayout, "CellRow", "Row", 75 ) ; AddNonSliderItem( oLayout, "CellCol", "Column", 75 ) ; oLayout.EndRow() ; oLayout.AddRow() ; oLayout.AddItem( "CellValue", "Value" ) ; oLayout.AddButton( "CellValueUpdate", "Update" ) ; oLayout.EndRow() ; oLayout.EndGroup(); oLayout.AddGroup( "Row Values" ) ; oLayout.AddRow() ; AddNonSliderItem( oLayout, "RowToChange", "Row", 50 ) ; oLayout.AddItem( "RowValue", "Value" ) ; oLayout.AddButton( "RowUpdate", "Update" ) ; oLayout.EndRow() ; oLayout.EndGroup(); oLayout.AddGroup( "Column Values" ) ; oLayout.AddRow() ; AddNonSliderItem( oLayout, "ColToChange", "Column", 50 ) ; oLayout.AddItem( "ColValue", "Value" ) ; oLayout.AddButton( "ColUpdate", "Update" ) ; oLayout.EndRow() ; oLayout.EndGroup(); oLayout.AddGroup( "Row Label" ) ; oLayout.AddRow() ; AddNonSliderItem( oLayout, "RowLabelToChange", "Row", 50 ) ; oLayout.AddItem( "RowLabel", "Label" ) ; oLayout.AddButton( "RowLabelUpdate", "Update" ) ; oLayout.EndRow() ; oLayout.EndGroup(); oLayout.AddGroup( "Column Label" ) ; oLayout.AddRow() ; AddNonSliderItem( oLayout, "ColLabelToChange", "Column", 50 ) ; oLayout.AddItem( "ColLabel", "Label" ) ; oLayout.AddButton( "ColLabelUpdate", "Update" ) ; oLayout.EndRow() ; oLayout.EndGroup(); AddPushButton( oLayout, "Batch", "Batch Edit" ) ; oLayout.EndGroup(); oLayout.AddGroup( "Change Layout" ) ; oLayout.AddRow() ; var headerModes = new Array( "Normal", 0, "None", 1, "Locked", 2) ; var oItem = oLayout.AddEnumControl( "ColHeaderMode", headerModes ) ; oItem.SetAttribute( siUICX, 75 ) ; oItem = oLayout.AddEnumControl( "RowHeaderMode", headerModes ) ; oItem.SetAttribute( siUICX, 75 ) ; oLayout.EndRow(); oLayout.AddRow() ; AddNonSliderItem( oLayout, "Height", "Height",75 ) ; AddNonSliderItem( oLayout, "Width", "Width",75 ) ; oLayout.EndRow() ; oLayout.AddItem( "ColWidths" ) ; oLayout.AddItem( "ROCols", "Read Only Columns" ) ; oLayout.AddButton( "Refresh", "Full Refresh" ) ; oLayout.EndGroup(); // Inject the event code oLayout.Language = "JScript" ; oLayout.SetAttribute( "HelpFile", "www.yahoo.com" ) ; oLayout.SetAttribute( "LogicPrefix", "GridTester_" ) oLayout.Logic = GridTester_OnInit.toString() + GridTester_TestGrid_OnChanged.toString() + GridTester_DimUpdate_OnClicked.toString() + GridTester_CellValueUpdate_OnClicked.toString() + GridTester_RowUpdate_OnClicked.toString() + GridTester_ColUpdate_OnClicked.toString() + GridTester_RowLabelUpdate_OnClicked.toString() + GridTester_ColLabelUpdate_OnClicked.toString() + GridTester_Height_OnChanged.toString() + GridTester_Width_OnChanged.toString() + GridTester_Batch_OnChanged.toString() + GridTester_ColHeaderMode_OnChanged.toString() + GridTester_RowHeaderMode_OnChanged.toString() + GridTester_Refresh_OnClicked.toString() + GridTester_ColWidths_OnChanged.toString() + GridTester_ROCols_OnChanged.toString() ; InspectObj( oPSet ) ; } //Helper function to create a button rather than a check box //for showing a boolean parameter function AddPushButton( in_oLayout, in_ParamName, in_Label ) { var oPPGItem = in_oLayout.AddItem( in_ParamName, "", "dscontrol" ) ; oPPGItem.SetAttribute( "Caption", in_ParamName ); oPPGItem.SetAttribute( "Class", "Button" ); oPPGItem.SetAttribute( "CX", 200 ); oPPGItem.SetAttribute( "Style", 0x00001003 );//(BS_AUTOCHECKBOX|BS_PUSHLIKE) oPPGItem.SetAttribute( "NoLabel", true ) ; } // By default numeric params have a slider, but // if we hide the slider the control takes up less horizontal space function AddNonSliderItem( in_oLayout, in_strParamName, in_strLabel, in_width ) { var oPPGItem = in_oLayout.AddItem( in_strParamName, in_strLabel ) ; oPPGItem.SetAttribute( siUINoSlider, true ) ; // Set a small width oPPGItem.SetAttribute( siUICX, in_width ) ; oPPGItem.WidthPercentage = 20 ; oPPGItem.LabelPercentage = 20 ; oPPGItem.LabelMinPixels = 20 ; } //Logic Code for GridTester function GridTester_OnInit() { //Force the logic code to run for setting the Column Widths to the //default values GridTester_ColWidths_OnChanged() GridTester_ROCols_OnChanged() } function GridTester_TestGrid_OnChanged() { // This is never called if the change to the grid // if provoked by changes to the grid caused // by the logic code itself. It is only called // if the cell contents are changed manually or by // an external script that uses the Object Model. logmessage( "Callback called for contents of TestGrid changing" ) ; var oGridData = PPG.TestGrid.value ; //Update the dimensions items based on the current size PPG.DimRows.Value = oGridData.RowCount ; PPG.DimCols.Value = oGridData.ColumnCount ; } function GridTester_DimUpdate_OnClicked() { var oGridData = PPG.TestGrid.value ; //Bracket with BeginEdit/EndEdit //so we only do a single update oGridData.BeginEdit() ; oGridData.RowCount = DimRows ; oGridData.ColumnCount = DimCols ; oGridData.EndEdit() ; Logmessage( "Calling GridData.RowCount = " + DimRows ) ; Logmessage( "Calling GridData.ColumnCount = " + DimCols ) ; // Notice that no call to PPG.Refresh is necessary } function GridTester_CellValueUpdate_OnClicked() { var oGridData = PPG.TestGrid.value ; oGridData.SetCell( PPG.CellCol.Value, PPG.CellRow.Value, PPG.CellValue.Value ) ; Logmessage( "Calling GridData.SetCell" ) ; } function GridTester_RowUpdate_OnClicked() { var oGridData = PPG.TestGrid.value ; //All items in the row will have the same value var newValue = PPG.RowValue.Value ; var aRowValues = new Array( oGridData.ColumnCount ) ; for ( var i = 0 ; i < aRowValues.length ; i++ ) { aRowValues[i] = newValue ; } oGridData.SetRowValues( PPG.RowToChange.Value, aRowValues ) ; Logmessage( "Calling GridData.SetRowValues" ) ; } function GridTester_ColUpdate_OnClicked() { var oGridData = PPG.TestGrid.value var newValue = PPG.ColValue.Value ; var aColValues = new Array( oGridData.RowCount ) ; for ( var i = 0 ; i < aColValues.length ; i++ ) { aColValues[i] = newValue ; } oGridData.SetColumnValues( PPG.ColToChange.Value, aColValues ) ; Logmessage( "Calling GridData.SetColumnValues" ) ; } function GridTester_RowLabelUpdate_OnClicked() { var oGridData = PPG.TestGrid.value ; oGridData.SetRowLabel( PPG.RowLabelToChange.Value, PPG.RowLabel ) ; Logmessage( "Calling GridData.SetRowLabel" ) ; } function GridTester_ColLabelUpdate_OnClicked() { var oGridData = PPG.TestGrid.value ; oGridData.SetColumnLabel( PPG.ColLabelToChange.Value, PPG.ColLabel ) ; Logmessage( "Calling GridData.SetColumnLabel" ) ; } function GridTester_Batch_OnChanged() { var oGridData = PPG.TestGrid.value ; // Demonstrate the ability to do multiple // updates without forcing a refresh if ( PPG.Batch.Value == 0 ) { logmessage( "Calling GridData.EndEdit" ) ; oGridData.EndEdit() ; } else { // Button pushed in logmessage( "Calling GridData.BeginEdit" ) ; oGridData.BeginEdit() ; } } function GridTester_Refresh_OnClicked() { // Does a complete refresh of the Property Page // Normal updates to the Grid should not require this PPG.Refresh() ; Logmessage( "Calling PPG.Refresh" ) ; } function GridTester_Height_OnChanged() { var oLayout = PPG.PPGLayout var oPPGItem = oLayout.Item( "TestGrid" ) if ( PPG.Height.Value != 0 ) { oPPGItem.SetAttribute( "CY", PPG.Height.Value ) ; } else { // When no attribute is set control will resize to fit the data oPPGItem.SetAttribute( "CY", null ) ; } // Attribute changes don't appear until there is a complete refresh PPG.Refresh() ; } function GridTester_Width_OnChanged() { var oLayout = PPG.PPGLayout var oPPGItem = oLayout.Item( "TestGrid" ) if ( PPG.Width.Value != 0 ) { oPPGItem.SetAttribute( "CX", PPG.Width.Value ) ; } else { oPPGItem.SetAttribute( "CX", null ) ; } PPG.Refresh() ; } function GridTester_ColWidths_OnChanged() { var oLayout = PPG.PPGLayout var oPPGItem = oLayout.Item( "TestGrid" ) if ( PPG.ColWidths.Value != "" ) { oPPGItem.SetAttribute( "ColumnWidths", PPG.ColWidths.Value ) ; } else { oPPGItem.SetAttribute( "ColumnWidths", null ) ; } PPG.Refresh() ; } function GridTester_ROCols_OnChanged() { var oLayout = PPG.PPGLayout var oPPGItem = oLayout.Item( "TestGrid" ) if ( PPG.ColWidths.Value != "" ) { oPPGItem.SetAttribute( "ReadOnlyColumns", PPG.ROCols.Value ) ; } else { oPPGItem.SetAttribute( "ReadOnlyColumns", null ) ; } PPG.Refresh() ; } function GridTester_ColHeaderMode_OnChanged() { var oLayout = PPG.PPGLayout var oPPGItem = oLayout.Item( "TestGrid" ) //Locked only makes sense if you set an explicit Height to the control oPPGItem.SetAttribute( "LockColumnHeader", PPG.ColHeaderMode.Value == 2 ) ; oPPGItem.SetAttribute( "HideColumnHeader", PPG.ColHeaderMode.Value == 1 ) ; PPG.Refresh() if ( PPG.ColHeaderMode.Value == 2 ) { Logmessage( "Setting LockColumnHeader attribute on Layout" ) ; } else if ( PPG.ColHeaderMode.Value == 1 ) { Logmessage( "Setting HideColumnHeader attribute on Layout" ) ; } } function GridTester_RowHeaderMode_OnChanged() { var oLayout = PPG.PPGLayout var oPPGItem = oLayout.Item( "TestGrid" ) oPPGItem.SetAttribute( "LockRowHeader", PPG.RowHeaderMode.Value == 2 ) ; oPPGItem.SetAttribute( "HideRowHeader", PPG.RowHeaderMode.Value == 1 ) ; PPG.Refresh() if ( PPG.RowHeaderMode.Value == 2 ) { Logmessage( "Setting LockRowHeader attribute on Layout" ) ; } else if ( PPG.RowHeaderMode.Value == 1 ) { Logmessage( "Setting HideRowHeader attribute on Layout" ) ; } } |
// Example of using GridData as a convenient way // to deal with 2D arrays from JScript // // ClusterProperties are widely used in scripting // and their data is represented as a 2D array. E.g. // there is a row for each component and each component // has multiple values (e.g. RGBA or UVW) which // are the column values. Even a Weight map is represented // this way, even though there is only 1 value per component // // JScript has no 2D support. Normally it is necessary to // convert to a 1D array using the VBArray.toArray method. // However if the data is transferred into a DataGrid object // it is then possible to access the data via a more convenient // API, for example Row by Row or setting values at a precise // Row/Column coordinate. This is demonstrated here: var oGrid = ActiveSceneRoot.AddGeometry( "Grid", "MeshSurface" ) ; oGrid.subdivu = 1 ; oGrid.subdivv = 1 ; SelectObj( oGrid ) ; CreateVertexColorSupport(null, "Vertex_Color", null, null); var oClusterProp = oGrid.ActivePrimitive.Geometry.Clusters(0).Properties( "Vertex_Color" ) ; var oGridData = XSIFactory.CreateGridData() // Example 1: Read the vertex color values // By transferring into GridData. // There are 4 Columns - R,G,B, and A // and there is 1 Row for each vertex. oGridData.Data = oClusterProp.Elements.Array LogMessage( "Blue Component on Vertex 0: " + oGridData.GetCell( 2, 0 ) ) ; LogMessage( "Red Component on Vertex 2: " + oGridData.GetCell( 0, 2 ) ) ; // Example 2: Change the vertex color values for ( var i = 0 ; i < oGridData.RowCount ; i++ ) { // Set RGBA value on each vertex oGridData.SetRowValues( i, Array( i * 0.10, 0.50, 0.75, 0.1 ) ) ; } // We MUST put the changed data back into the cluster property if we // want our changes to take effect oClusterProp.Elements.Array = oGridData.Data // Example 3: Display the values in custom pset var oPSet = ActiveSceneRoot.AddProperty( "CustomProperty", false, "ClusterPropContents" ) ; var oParam1 = oPSet.AddGridParameter( "mygrid" ) ; var oLayout = oPSet.PPGLayout var oPPGItem = oLayout.AddItem( "mygrid", "",siControlGrid ) ; oPPGItem.SetAttribute( "NoLabel", true ) ; //Copy data from our free floating //GridData object to the one on the Custom Property var oGridDataOnPSet = oParam1.Value ; oGridDataOnPSet.Data = oGridData.Data ; // Set up labels so the user knows what the data is oGridDataOnPSet.SetColumnLabel(0, "R" ) ; oGridDataOnPSet.SetColumnLabel(1, "G" ) ; oGridDataOnPSet.SetColumnLabel(2, "B" ) ; oGridDataOnPSet.SetColumnLabel(3, "A" ) ; for ( i = 0 ; i < oGridData.RowCount ; i++ ) { oGridDataOnPSet.SetRowLAbel( i, "Vertex " + i.toString() ) ; } // Now you can change the data by using the labels // (this doesn't change the copy of the data inside oGridData) oGridDataOnPSet.SetCell( "G", "Vertex 2", 0.99 ) ; InspectObj( oPSet ) ; |