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

### Methods

BeginEdit | EndEdit | GetCell | GetCellBackgroundColor
GetCellReadOnlyFlags | GetColumnComboItems | GetColumnDef | GetColumnLabel
GetColumnType | GetColumnValues | GetRowBackgroundColor | GetRowLabel
GetRowValues | InsertColumn | InsertRow | RemoveColumn
RemoveRow | SetCell | SetCellBackgroundColor | SetCellReadOnlyFlags
SetColumnComboItems | SetColumnDef | SetColumnLabel | SetColumnType
SetColumnValues | SetColumnsVisibility | SetRowBackgroundColor | SetRowLabel
SetRowValues | SetRowsVisibility |  |

### Properties

ColumnCount | Data | GridWidget | MultiSelectionMode
ReadOnly | 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 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 ) ;

### See Also

XSIFactory.CreateGridData CustomProperty.AddGridParameter