## GridData

Object Hierarchy | Related C++ Class: GridData

### Introduced

v4.0

### Description

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 labeled 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.

### Methods

BeginEdit | EndEdit | GetCell | GetColumnComboItems
GetColumnLabel | GetColumnType | GetColumnValues | GetRowBackgroundColor
GetRowLabel | GetRowValues | SetCell | SetColumnComboItems
SetColumnLabel | SetColumnType | SetColumnValues | SetRowBackgroundColor
SetRowLabel | SetRowValues |  |

### Properties

ColumnCount | Data | GridWidget | RowCount

### Examples

#### 1. JScript Example

    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" ) ;
            }
    }

#### 2. JScript Example

    // 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 transfered 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 transfering 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 ) ;

### See Also

XSIFactory.CreateGridData CustomProperty.AddGridParameter