Page 1 of 1

DataGrid cell object

Posted: Sun Oct 26, 2014 1:05 pm
by Nikos
Greetings to all,

I know I'm not being original here, this being my first post and already asking about DataGrids, but there's that. I've been through the documentation and forums, and I've found similar issues to mine, but not exactly.

I want to access an arbitrary individual cell object of a populated DataGrid. Not the contents, the object. To change colors, font size, etc.
And I want to do this OUTSIDE the script of the cell. Arbitrarily, not when lines are highlighted, not when contents are updated. I just want to be able to say, from the script of a button on the card, "Set backgroundcolor of cell 5,3 to red".

My problem is that I can't find a way to get the object name of each cell. The closest I came was when I created a custom behavior script for the DataGrid cells to print out the name of each cell as it was filled-in, and I got names like "Col 1 0005". But if I don't do that, and just use the default column behavior, the same reference "Col 1 0005" does not work ("no such object").

Thanks

Nikos

Re: DataGrid cell object

Posted: Sun Oct 26, 2014 2:55 pm
by Nikos
Well that was silly,

It's obvious now but the reference "Col 1 0005" isn't absolute, the "Col 1" part actually takes into account the column name, so if you rename the 1st column to "First Name", the cell reference becomes "First Name 0005".

But now I've discovered an even worse obstacle to what I'm trying to do.

If you have a DataGrid of 20 lines of 5 columns (100 values), but the VISIBLE size is 10 lines of 5 columns (50 cells), in reality there seem to be only 50 individual DataGrid cells, not 100.

Here's what happens: if you try on the above scenario

set the textsize of field "Col 1 0001" of group "dg1" to 18

then the cell at [1,1] changes font size to 18 (correctly). However if you scroll down the DataGrid, the cell at [11,1] also changed font size to 18. Line 11 was the first non-visible line.
And here's the weirdest part: if you at that point (where lines 1 and 11 are at textsize 18) you go manually and resize the DataGrid to include one extra line, now line 11 is fine, and line 12 (!) becomes size 18 (automatically just by resizing, no setting anything this time).

Is this deliberate? It seems like a bug, unless we weren't meant to be playing around with the DataGrid cells like that. But then, how to do what I'm after?

Re: DataGrid cell object

Posted: Tue Oct 28, 2014 8:47 am
by William Jamieson
From my experience using the datagrid, sometimes it will have behaviors that are not desireable, there are a lot of mysteries in it. One is probably the one you found. I have been through many threads where the usual conclusion is to force the properties to be the way that you want them. This can usually be done through a few lines of code such as

Code: Select all

if the last word of the short name of {my Field} is not "0001" then
set the textsize to 12 --or what ever other size besides 18 you dont want it to be
end if
this code is not exact by no means, but you get the point.

If you really cant force it to behave as you want, then I suggest creating a bug report with Livecode.

Not too sure if they are going to have the datagrid much longer. I heard at the Livecode conference that they may be making a new system to replace the DG for Livecode 8.0 coming out early next year. Maybe it was just a thought they had, maybe it was serious, I don't know. But just wanted to give you a heads up.

-Will

Re: DataGrid cell object

Posted: Tue Oct 28, 2014 9:15 am
by Nikos
Thanks Will,

What you propose unfortunately does not work and this is why this seems to be a bug.

In the example I described above (table-type Datagrid with 20 rows of data, 10 visible, textsize 12 normally), I am setting one specific cell [1,1] to textsize 18 via external code (can be even from the message window). Field reference is: [Col 1 0001].

On its own, LC goes and changes also cell [11,1] (row 11 is the 1st non visible row) and sets its textsize also to 18. When I say cell [11,1] I mean the cell on row 11 column 1, in LC Field reference it would be [Col 1 0011].

If I manually then go and set textsize of cell [11,1] back to 12, it tells me that cell [11,1] does not exist ("no such object") ! Field reference: [Col 1 0011].

This is why it seemed to me that the underlying structure of cell objects of a DataGrid does not seem to correspond to the total values of the DataGrid, but only to the visible ones.

If you are also replicating this (I tried on LC6.7 and on LC7.0 and both have this issue) then it's either a bug or something that wasn't meant to be exposed but slipped through. I would really like to hear from one of the LC guys/gals if I should just drop it or wait for a fix.

Re: DataGrid cell object

Posted: Tue Oct 28, 2014 10:09 am
by Ledigimate
Hi Nikos,

The "bug" you've described is actually not a bug. The datagrid internally only creates the objects necessary to display the visible portion of the data, and the same controls are used again when you scroll up or down. These internal objects were not designed to remain associated with rows going out of the visible range.

You therefore need to keep tabs on which cells should be colorized and colorize them only when they come into visible range.

* Edit: To determine which lines are currently being displayed, use the dgVisibleLines property.

Re: DataGrid cell object

Posted: Tue Oct 28, 2014 10:55 am
by Nikos
Hi Ledigimate,
These internal objects were not designed to remain associated with rows going out of the visible range.
Try this:
Create a DataGrid as described above (table-type Datagrid with 20 rows of data, 10 visible, textsize 12 normally). Say the text is "Text1", "Text2" and so forth up to "Text20". Only rows 1-10 are visible. So the values I'm seeing in the DataGrid are "Text1" to "Text10".

Scroll down one line. Rows 2-11 are now visible. So now I'm seeing "Text2" to "Text11".

Execute: set the textsize of field "Col 1 0001" of group "dg1" to 18

According to what you mentioned, either of 2 things should happen:
1. Nothing should happen, row 1 is not in the visible range.
Or
2. The currently displayed value at Col 1 Row 1 should change to size 18, so I should get "Text2" blown to size 18

Instead, what happens is that it does actually go and change the size of "Text1". Even though it's not visible. When you scroll one up again you will see it. Of course it also changed "Text11" as we've been discussing.

So what I'm finding is that, you cannot individually access any of the DataGrid ROWS that were not initially visible before scrolling. With the visible ones you can do anything you want. But when you do, you will also change other "hidden" cells below.

Note I put ROWS in capitals because all this strange behaviour does not apply to COLUMNS! If you change something in a cell that is on a visible row but not a visible column, it changes beautifully, as far along as you would like, with no repeating property changes like with ROWS. Even if it's hidden. So if it's working for COLUMNS, why not for ROWS?

I still think we should leave the bug option open.

Re: DataGrid cell object

Posted: Tue Oct 28, 2014 2:28 pm
by Ledigimate
Nikos

Here's what I mean:

When a datagrid table is resized, it only creates enough fields to display the rows that are visible on-screen, and then when you scroll up/down, it "recycles" those same fields to display the new set of on-screen rows. For that reason, you cannot rely on field "Col 1 0001" to still point at "Text 1" after you scrolled down. In your behavior script, you should rather use the "dgColumnNumber" and "dgLine" properties to identify the current cell that is being filled in, and set the color of that cell to a value stored in an array of which the keys are coordinates of the cells you want colorized and the values are colors.

Here's an example of what the "FillInData" handler in your behavior script would look like:

Code: Select all

on FillInData pData
   -- This message is sent when the Data Grid needs to populate
   -- this template with the column data. pData is the value to be displayed.
   
   put the dgColumnNumber of me,the dgLine of me into tKey
   get the customProperties["cellColors"] of group dgridTest
   put it[tKey] into theColor
   if not (theColor is empty) then
      set the backgroundColor of the long id of me to theColor
      set the opaque of the long id of me to true
   else
      set the backgroundColor of the long id of me to empty
      set the opaque of the long id of me to false
   end if
   
   set the text of the long ID of me to pData ## temp workaround for
end FillInData
in which case you would set a specific cell's color as follows:

Code: Select all

on setCellColor pCellCoordinates, theColor
   put the customProperties["cellColors"] of group dgridTest into theCellColors
   put theColor into theCellColors[pCellCoordinates]
   set the customProperties["cellColors"] of group dgridTest to theCellColors
   send "RefreshLine item 2 of pCellCoordinates" to group dgridTest
end setCellColor
Then you can set the color of cell 5,3 to red as follows:

Code: Select all

setCellColor "5,3", "red"

Re: DataGrid cell object

Posted: Tue Oct 28, 2014 5:18 pm
by Nikos
Thank you Ledigimate,

I really liked your script. It works great. Although you DID violate 2 of the original rules I had set:
- this must be done OUTSIDE the script of the cell
- it must not be done when contents are updated

Not that I mind really :wink:

To summarize, setting DG cell properties directly without any extra scripting can be done only if all DataGrid rows are visible. In this case, for the target cell [X,Y], on a visible or not visible column initially - it doesn't matter, you just say set the textsize of field "Col Y 000X" of group "dg1" to 18. That works fine, once it is set you can scroll left/right to your heart's content and it stays correctly set.
However if there are non-visible rows, attempting the above on a visible row cell will create "mirror" effects further down, and attempting it on a non-visible row cell will not work at all. In this case you have to get to the cell script as Ledigimate showed above.

Thanks again for the help.