Difference between revisions of "DataGrid Objects"

From LinuxMCE
Jump to: navigation, search
Line 144: Line 144:
 
   return false; // Keep processing it
 
   return false; // Keep processing it
 
   }
 
   }
 +
[[Category: Programmer's Guide]]

Revision as of 02:19, 6 September 2007

Data grids are objects shown on the Orbiters which have dynamically changing data in the rows and columns, which data is specified in code. To create a DataGrid you must add a new DataGrid to the DataGrid table in pluto_main, and create a function, usually in a plugin, which builds the rows and columns of data. Upon startup call the function RegisterDatagridGenerator in the DataGrid plugin to specify the function that provides the data for the data grid. In Designer create a data grid object on a screen and specify the data grid id and the parameters to be passed to the data grid generator in the DesignObjParameter 'options'.

In the Data Grid Generator create cells in rows and columns, and attach to each cell a 'value' and optionally 'text'. When the screen with a DataGrid first appears Orbiter will fire the command "Populate DataGrid" which will result in the DataGrid Generator getting called to populate the entire contents of the grid, and then every time it needs to render a block of rows/columns it sends the command "Request DataGrid Contents".

When a cell in the DataGrid is selected orbiter will store the 'value' for the cell into the variable specified in the parameter for the DataGrid, and Orbiter will fire all the commands in the "On Activate" list. You can also use ScreenHandler's RegisterCallBack method to create a function that is called whenever a cell is selected (use the type cbDataGridSelected).

Additionally in the Data Grid generator you can attach attributes to each cell, which are a pair of strings, such as color=blue, size=l, etc. In Designer you can specify as parameters for the datagrid PK_DesignObj_Row1, PK_DesignObj_Coll1 and PK_DesignObj_Cell. In this case those objects will be used in place of the normally rendered cells; the objects are positioned in Designer in a grid for the rows and columns, and are automatically hidden when there is no corresponding cell.

Example for Add Software grid:

We have a grid that lists software modules the user can install. Each row needs to list the title of the module, show an icon for the software, and display a check box if it's virus free.

We create an object in Designer for the cells in the grid, and on it place a text object with "<%=CA:Title%>". This means the text will contain the cell's attribute "Title". Create a blank bitmap object with no graphic to represent the icon, and another which contains a check box for 'virus free'.

Create a new DataGrid in Designer and place on it all 3 of those objects, marking the 'virus free' one as 'can hide', meaning it won't always be visible.

Create a data grid generator (in this case in general info plugin) and register it as follows:

 bool General_Info_Plugin::Register() {
 ...
 	m_pDatagrid_Plugin->RegisterDatagridGenerator(
 		new DataGridGeneratorCallBack(this, (DCEDataGridGeneratorFn) (&General_Info_Plugin::AddSoftware)),
 		DATAGRID_Installable_Apps_CONST, PK_DeviceTemplate_get());

in the generator code we retrieve the software modules from the database and create a cell for each with the correct attributes:

 class DataGridTable *General_Info_Plugin::AddSoftware( string GridID, string Parms, void *ExtraData, int *iPK_Variable, string
*sValue_To_Assign, class Message *pMessage ) {
 	DataGridTable *pDataGrid = new DataGridTable();
 	DataGridCell *pCell;
 
 	string sql="SELECT PK_Software, Iconstr, Title, Category, Rating, Virus_Free, Installation_status, Description, Homeurl 
 FROM Software WHERE FK_Device="+sPK_Device_PC+" ORDER BY Title";
 
 	int iRow=0;
 	if( (result.r = m_pDatabase_pluto_main->mysql_query_result(sql)) )
 	{
 		unsigned long *lengths;
 		while((row=mysql_fetch_row(result.r))){
 			lengths=mysql_fetch_lengths(result.r);
 			int size = 0;
 			char *data = NULL;
 
 			pCell = new DataGridCell("", row[0]);
 			if(lengths[1]){
 				char *Data=new char[lengths[1]];
 				memcpy(Data,row[1],lengths[1]);
 				pCell->SetImage(Data, lengths[1], GR_PNG);
 			}
 			pCell->m_mapAttributes["Title"] = row[2] ? row[2] : "";
 			pCell->m_mapAttributes["Category"] = row[3] ? row[3] : "";
 			pCell->m_mapAttributes["Rating"] = row[4] ? row[4] : "";
 			pCell->m_mapAttributes["Rating"] = row[4] ? row[4] : "";
 			pCell->m_mapAttributes["Virus_Free"] = row[5] ? row[5] : "";
 			pCell->m_mapAttributes["Installation_status"] = row[6] ? row[6] : "";
 			pCell->m_mapAttributes["Description"] = row[7] ? row[7] : "";
 			pDataGrid->SetData(0,iRow++,pCell);
 		}
 	}
 
 	return pDataGrid;
 }

Then in orbiter we create a screen handler for this screen and register interceptors:

 /*virtual*/ void ScreenHandler::SCREEN_Add_Software(long PK_Screen)
 {
 	ScreenHandlerBase::SCREEN_Add_Software(PK_Screen);
 	RegisterCallBack(cbDataGridSelected, (ScreenHandlerCallBack) &ScreenHandler::AddSoftware_GridSelected, 
 	new DatagridCellBackData());
 	RegisterCallBack(cbDataGridRendering, (ScreenHandlerCallBack) &ScreenHandler::AddSoftware_GridRendering,
 	new DatagridAcquiredBackData());
 }
 //-----------------------------------------------------------------------------------------------------
 bool ScreenHandler::AddSoftware_GridRendering(CallBackData *pData)
 {
 	// This is called every time a new section of the grid is to be rendered.  We want to find the child 
 	// object for the 'virus free' check and hide it if it's virus free,
 	// and also find the child object for the icon and assign it the picture associated with the cell.
 	DatagridAcquiredBackData *pDatagridAcquiredBackData = (DatagridAcquiredBackData *) pData;  
 	// Call back data containing relevant values for the grid/table being rendered
 
 	// Iterate through all the cells
 	for(MemoryDataTable::iterator it=pDatagridAcquiredBackData->m_pDataGridTable->m_MemoryDataTable.begin();
 	it!=pDatagridAcquiredBackData->m_pDataGridTable->m_MemoryDataTable.end();++it)
 	{
  		DataGridCell *pCell = it->second;
 		pair<int,int> colRow = DataGridTable::CovertColRowType(it->first);  // Get the column/row for the cell
 
 		// See if there is an object assigned for this column/row
 		map< pair<int,int>, DesignObj_Orbiter *>::iterator itobj = pDatagridAcquiredBackData->m_pObj->m_mapChildDgObjects.find( colRow );
 		if( itobj!=pDatagridAcquiredBackData->m_pObj->m_mapChildDgObjects.end() )
 		{
 			DesignObj_Orbiter *pObj = itobj->second;  // This is the cell's object.
 			DesignObj_DataList::iterator iHao;
 
 			// Iterate through all the object's children
 			for( iHao=pObj->m_ChildObjects.begin(  ); iHao != pObj->m_ChildObjects.end(  ); ++iHao )
 			{
 				DesignObj_Orbiter *pDesignObj_Orbiter = (DesignObj_Orbiter *)( *iHao );
 				if( pDesignObj_Orbiter->m_iBaseObjectID==DESIGNOBJ_Installed_Apps_Not_Virus_Free_CONST )
 					pDesignObj_Orbiter->m_bHidden = pCell->m_mapAttributes_Find("Virus_Free")=="Yes";  // Hide this if it's virus fee
 				if( pDesignObj_Orbiter->m_iBaseObjectID==DESIGNOBJ_Installed_Apps_Icon_CONST )
 					m_pOrbiter->m_pOrbiterRenderer->UpdateObjectImage(pDesignObj_Orbiter->m_ObjectID, "PNG",
 						pCell->m_pGraphicData, pCell->m_GraphicLength, "0");  // Store the icon, which is cell's picture
 			}
 		}
 	}
 	return false;
 }
 //-----------------------------------------------------------------------------------------------------
 bool ScreenHandler::AddSoftware_GridSelected(CallBackData *pData)
 {
 	DatagridCellBackData *pCellInfoData = (DatagridCellBackData *)pData;
 	if( pCellInfoData->m_pDataGridCell )
 	{
 		int PK_Software = atoi(pCellInfoData->m_pDataGridCell->GetValue());
 		string sText,sCommand;
 		if( PK_Software>0 )
 		{
 			sText = m_pOrbiter->m_mapTextString[TEXT_Confirm_Add_Software_CONST];
 			sCommand = StringUtils::itos(m_pOrbiter->m_dwPK_Device) + " " + StringUtils::itos(m_pOrbiter->m_dwPK_Device_GeneralInfoPlugIn)
 				+ " 1 " + TOSTRING(COMMAND_Add_Software_CONST) + " " + TOSTRING(COMMANDPARAMETER_PK_Software_CONST)
 				+ " " + pCellInfoData->m_pDataGridCell->GetValue() + " " TOSTRING(COMMANDPARAMETER_PK_Device_CONST) " "
 				+ StringUtils::itos(m_pOrbiter->m_pLocationInfo->m_dwPK_Device_MediaDirector) + " " TOSTRING(COMMANDPARAMETER_TrueFalse_CONST) " 1";
 		}
 		else if( PK_Software<0 )
 		{
 			sText = m_pOrbiter->m_mapTextString[TEXT_Confirm_Add_Software_CONST];
 			sCommand = StringUtils::itos(m_pOrbiter->m_dwPK_Device) + " " + StringUtils::itos(m_pOrbiter->m_dwPK_Device_GeneralInfoPlugIn)
 				+ " 1 " + TOSTRING(COMMAND_Add_Software_CONST) + " " + TOSTRING(COMMANDPARAMETER_PK_Software_CONST)
 				+ " " + StringUtils::itos(PK_Software*-1) + " " TOSTRING(COMMANDPARAMETER_PK_Device_CONST) " "
 				+ StringUtils::itos(m_pOrbiter->m_pLocationInfo->m_dwPK_Device_MediaDirector) + " " TOSTRING(COMMANDPARAMETER_TrueFalse_CONST) " 0";
 		}
 		else
 			return false; // No software was selected
 
 		DataGridCell *pCell = pCellInfoData->m_pDesignObj_DataGrid->DataGridTable_Get() ? pCellInfoData->m_pDesignObj_DataGrid->DataGridTable_Get()->GetData( 0, pCellInfoData->m_Row ) : NULL;
 		if( pCell )
 			sText+="\n" + pCell->m_mapAttributes["Title"];
 		DisplayMessageOnOrbiter(0,sText,false,"30",false,m_pOrbiter->m_mapTextString[TEXT_YES_CONST],sCommand,m_pOrbiter->m_mapTextString[TEXT_NO_CONST]);
 	}
 
 	return false; // Keep processing it
 }