Using Other Graphic Formats in Your cCJGrids
by
, 3-Sep-2011 at 02:57 AM (9843 Views)
About a year ago (November 2010) I posted a blog about how to use other graphic formats in the headers of a cCJGrid. A couple of days ago there was a request about how to use other graphic formats in the grid itself. While all the information is in the one-year-old blog I feel you all want to see an example on how to do this. So that is what this blog is about.
In the previous blog I started with describing a column named oYellowCards. The blog was written shortly after the 2010 World Championships Football (ok Soccer for some of you). Since the year 2000 - the year in which Holland and Belgium were the host of the European Football Championships - Data Access Europe hosts, every 2 years, a website to predict scores for the Data Access customers worldwide. You can also win a nice prize. We will do the same again in 2012 and of course hope the Dutch will win again as in 1988 (it is time again)... I tell you this because the grid was built on top of data coming from this website. The website keeps track of the numbers in total and by player and expose this via a webservice to the rest of the world. The graphics in this website are GIF and JPEG pictures.
In this screenshot you see a grid with the football player names and the number of yellow and red cards they scored. In the first column the grid uses the country flag for a player instead of the name of the country.
The data shown in the grid is retrieved via a webservice function call and the flag pictures are downloaded automatically from the website based on the country flag URL returned by the webservice function call.
How can you make this grid yourself? Of course you start with a cCJGrid object. In there you need to add the five columns as shown in the picture. The first column is a current row indicator column (cCJGridColumnRowIndicator class). The second column - the one we are after - is a simple cCJGridColumn. One of the enhancement is that pictures are shown centered. This is done by setting the property peIconAlignment to xtpAlignmentIconCenter.
A more important enhancement is that I use the OnSetDisplayMetrics event to show the picture. The implemented code for this is:Code:Object oCountryFlag is a cCJGridColumn Set piWidth to 30 Set psCaption to "Country" Set peIconAlignment to xtpAlignmentIconCenter
Now of course you need to know how to get the picture in the sValue parameter of this grid cell. For this we have to look at the webservice and the returned information. Via the http://footballpool.dataaccess.eu/data/info.wso?wsdl URL you can create a cClientWebService class and base an object on this. For the grid data we use the function named wsAllPlayersWithYellowOrRedCards. The function returns an array of tWStPlayersWithCards data blocks. This struct is defined - by the WSDL parser in the Visual DataFlex Studio as:Code:Procedure OnSetDisplayMetrics Handle hoGridItemMetrics Integer iRow String ByRef sValue If (sValue <> "") Begin Set ComItemIcon of hoGridItemMetrics to sValue End End_Procedure
Each element of the array contains the name of the player, the number of yellow and red cards received, the name of team (country) he is playing for and an URL to the flag of the country. An example of the data is:Code:Struct tWStPlayersWithCards string sName integer iYellowCards integer iRedCards string sTeamName string sTeamFlag End_Struct // tWStPlayersWithCards
The code to call the webservice for the data is added to the method LoadData - a name that is quite often used in our examples about the CodeJock grids.
The next step in the process is to download the country flag which I do with a self written method named DownloadFile and this method is called as follows:Code:Procedure LoadData tWStPlayersWithCards[] Cards tDataSourceRow[] Data String sImageFileName Integer eTransferStatus iElements iElement iImage Boolean bFileExist Get wsAllPlayersWithYellowOrRedCards of oWSFootballPoolService False False False to Cards Get peTransferStatus of oWSFootballPoolService to eTransferStatus If (eTransferStatus = wssOk) Begin Move (SizeOfArray (Cards)) to iElements Decrement iElements For iElement from 0 to iElements
The DownLoadFile method creates and uses an object of the cHTTPTransfer class. To avoid that a picture is downloaded multiple times the code checks if the picture is present locally already or not. The full DownloadFile method is:Code:Get DownloadFile Cards[iElement].sTeamFlag (&bFileExist) to sImageFileName
The downloaded file is added to the set of images for the cCJGrid object with the AddImage function which we augmented in the previous blog. The code for this is:Code:Function DownloadFile String sFilePath Boolean ByRef bFileExist Returns String Handle hoHTTP hoWorkspace String sDownloadedFileName sRemoteHost sBitmapPaths sFileLocation sFileName Integer iPos iResult Get phoWorkspace of ghoApplication to hoWorkspace Get psBitmapPath of hoWorkspace to sBitmapPaths Get PathAtIndex of hoWorkspace sBitmapPaths 1 to sFileLocation Move (Pos ('\\', sFilePath) or Pos ('//', sFilePath)) to iPos If (iPos > 0) Begin Move (Right (sFilePath, Length (sFilePath) - iPos - 1)) to sFilePath End Move (Pos ('\', sFilePath) or Pos ('/', sFilePath)) to iPos If (iPos > 0) Begin Move (Left (sFilePath, iPos - 1)) to sRemoteHost Move (Right (sFilePath, Length (sFilePath) - iPos)) to sFilePath End If (sRemoteHost <> "" and sFilePath <> "" and sFileLocation <> "") Begin If (Right (sFileLocation, 1) <> '\') Begin Move (sFileLocation - '\') to sFileLocation End Move (RightPos ('\', sFilePath) or RightPos ('/', sFilePath)) to iPos If (iPos > 0) Begin Move (Right (sFilePath, Length (sFilePath) - iPos)) to sFileName End Move (sFileLocation - sFileName) to sDownloadedFileName Move (DoesFileExist (sDownloadedFileName)) to bFileExist If (not (bFileExist)) Begin Get Create (RefClass (cHTTPTransfer)) to hoHTTP Set psRemoteHost of hoHTTP to sRemoteHost Set psAcceptTypes of hoHTTP to "image/*" Set psSaveAsFile of hoHTTP to sDownloadedFileName Get HTTPGetRequest of hoHTTP sFilePath to iResult If (iResult = 0) Begin Move '' to sDownloadedFileName End Send Destroy of hoHTTP End End Function_Return sDownloadedFileName End_Function
The AddImage returns the handle to the image which is stored in the data used for the grid. The full LoadData is coded as:Code:Get AddImage sImageFileName 0 to Data[iElement].sValue[1] EraseFile sImageFileName
If your images are present in a local environment you can of course skip the whole download part and go for loading the image directly.Code:Procedure LoadData tWStPlayersWithCards[] Cards tDataSourceRow[] Data String sImageFileName Integer eTransferStatus iElements iElement iImage Boolean bFileExist Get wsAllPlayersWithYellowOrRedCards of oWSFootballPoolService False False False to Cards Get peTransferStatus of oWSFootballPoolService to eTransferStatus If (eTransferStatus = wssOk) Begin Move (SizeOfArray (Cards)) to iElements Decrement iElements For iElement from 0 to iElements Get DownloadFile Cards[iElement].sTeamFlag (&bFileExist) to sImageFileName Get AddImage sImageFileName 0 to Data[iElement].sValue[1] EraseFile sImageFileName Move Cards[iElement].sTeamName to Data[iElement].vTag Move Cards[iElement].sName to Data[iElement].sValue[2] If (Cards[iElement].iYellowCards > 0) Begin Move Cards[iElement].iYellowCards to Data[iElement].sValue[3] End Else Begin Move '-' to Data[iElement].sValue[3] End If (Cards[iElement].iRedCards > 0) Begin Move Cards[iElement].iRedCards to Data[iElement].sValue[4] End Else Begin Move '-' to Data[iElement].sValue[4] End Loop Send InitializeData Data End End_Procedure
Have fun with the above code.