Set a specific cell in a field to a different color

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
Paul D
Posts: 116
Joined: Mon May 21, 2007 6:58 pm

Set a specific cell in a field to a different color

Post by Paul D » Fri Oct 15, 2010 7:30 pm

Is this possible? I messed around with htmltext but it doesn't fill the entire cell.

Janschenkel
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 977
Joined: Sat Apr 08, 2006 7:47 am
Contact:

Re: Set a specific cell in a field to a different color

Post by Janschenkel » Sun Oct 17, 2010 9:21 am

Not with the built-in field, I'm afraid. You may be interested in RunRevPlanet's Flexible Grid for LiveCode as an alternative to using a table text field.

Jan Schenkel.
Quartam Reports & PDF Library for LiveCode
www.quartam.com

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Re: Set a specific cell in a field to a different color

Post by bn » Sun Oct 17, 2010 11:04 am

Paul,

Code: Select all

on mouseUp
   set the itemdelimiter to tab
   set the backgroundcolor of item 2 of line 1 of field "myTableField" to red
end mouseUp
this works only for cells that have text in them. I don't know if something like this is what you are looking after.

regards
Bernd

Paul D
Posts: 116
Joined: Mon May 21, 2007 6:58 pm

Re: Set a specific cell in a field to a different color

Post by Paul D » Mon Oct 18, 2010 1:51 pm

I was looking for more to fill the entire cell rather than just a small box around the text. Setting the background color of the item works just like setting <bgcolor> with htmltext. I suppose it will have to do! Thanks again for the help :)

Regulae
Posts: 136
Joined: Tue Oct 20, 2009 6:05 am

Re: Set a specific cell in a field to a different color

Post by Regulae » Mon Oct 18, 2010 3:03 pm

Hi Paul,

In the absence of a tidy way to colour a single cell in a standard table field, I might mention one approach I played with a while ago. It involved three “layers”. I first created a simple, blank field whose backgroundColor was white, which I called field “White Backdrop”. On top of this I placed a table field with its opaque property set to false, i.e. you could see its cell divider lines, but it was otherwise transparent, so you saw the backdrop field behind it. Then I created small, borderless cell-sized fields, and gave them the backgroundColor I wanted. I placed them over the cells I wanted coloured, then using the property inspector, size and position, set their layers so they were visible between the white backdrop and the table field. Individual cells, whole or partial rows or columns could be coloured in this way. To make a large table field scrollable, I grouped everything- backdrop, colour fields, and table field, into a single group which had horizontal and vertical scroll bars. Thus when you scrolled, you scrolled the group- everything moved together, i.e. the colour fields “stayed with” the cells they provided a colour background for. Originally, the colour fields were sized and positioned individually by hand, but I seem to recall some potential for doing this with some somewhat obscure scripting if need be. I hope this account is not too confusing- it's a bit "ham fisted" and it may or may not have use for your particular requirements.

Regards,
Michael

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10052
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Set a specific cell in a field to a different color

Post by FourthWorld » Mon Oct 18, 2010 6:16 pm

Nice approach, Mike.

Another option might be to make the field transparent and indicate selections with a graphic object beneath it. You can get the metrics for the object with a combination of the tabstops, the vScroll and hScroll, the borderWidth, and the effective textHeight, and use that to calculated where the selection indicator is drawn.

For discontiguous selection regions, note that you can set the points of a single polygon graphic object to render as any number of discontiguous shapes by putting blank lines between the points that comprise each shape.

Using a single polygon this way is so fast you may find the performance quite acceptable to render on-the-fly during the scrollbardrag message, so you can take full advantage of the size of text you can put into a field and still keep the selection indicator in synch with it.

It's a bit of work to set up, but you only need to do it once. :)
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

Regulae
Posts: 136
Joined: Tue Oct 20, 2009 6:05 am

Re: Set a specific cell in a field to a different color

Post by Regulae » Tue Oct 19, 2010 4:34 am

Hi Richard,
For discontiguous selection regions, note that you can set the points of a single polygon graphic object to render as any number of discontiguous shapes by putting blank lines between the points that comprise each shape.
... that’s something I certainly didn’t know, and would never have thought of. It’s definitely one for the Scrapbook. What I tried was one of those quick compromises which served immediate requirements. Because I was using different objects (fields) for each block of colour, experiments with scripting “bogged down” when it came to managing the multiple colour blocks. I’m glad I posted my attempt, as I’ve learnt from your response.

Yours,
Michael

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10052
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Set a specific cell in a field to a different color

Post by FourthWorld » Tue Oct 19, 2010 3:06 pm

I learned of that trick with discontiguous shapes in a single polygon from Geoff Canyon's Start Battle - check this out:
http://www.inspiredlogic.com/rev/starbattle.rev

Everything you see on that screen is a single polygon object. Amazing work (and tons of fun to play with <g>).
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Re: Set a specific cell in a field to a different color

Post by bn » Tue Oct 19, 2010 9:59 pm

Michael,
you might have some fun at looking at alternating stripes for rows in a table field. A table field and a graphic with gradient does this. See the attached stack. It was more a try to get this going, but seems to work. I was tackling the problem in a different context anyway. Boy, to figure out what Rev does to the lines in a field, especially the first one, proved more difficult than I expected. But I think also a nice use of gradients.
alternatingLinesColorTableField.rev.zip
(3.84 KiB) Downloaded 309 times
As an exercise in patience on my part with regards to the table field see also
http://revonline2.runrev.com/stack/428/ ... agDividers

it lets you adjust the cell width according to content and you can drag the vertical dividers with the mouse.

As an exercise it is ok. Actually it should be all part of the table field object from the beginning.

regards
Bernd

Regulae
Posts: 136
Joined: Tue Oct 20, 2009 6:05 am

Re: Set a specific cell in a field to a different color

Post by Regulae » Sun Oct 24, 2010 2:13 pm

@ Bernd

The stacks you posted really repay close study. The use of fillGradient to produce altenating bands of colour is very clever, when coordinated with the lines of a table field. Taking into account the special spacing of the first line is quite a challenge- I think I’ve stumbled over this at different times, without necessarily recognising it was textSize dependent. In order to update the image when changes are made to the textHeight, textSize, or margins of the table field, I tried this:

Code: Select all

on mouseEnter
   if the textSize of me <> the myTextSize of me OR \
          the textHeight of me <> the myTextHeight of me OR \
          the margins of me <> the myMargins of me then
      resizeControl
      end if
end mouseEnter

on mouseLeave
   set the myTextSize of me to the textSize of me
   set the myTextHeight of me to the textHeight of me
   set the myMargins of me to the margins of me
end mouseLeave
... in the script of the table field. I learnt a great deal from looking at your script, as well as the earlier “OldTableFieldDragDividers” stack. This must have been an exercise in patience, certainly not a task one could complete in a single sitting. Taking into account possible horizontal scroll of the table field was an interesting aspect, and adding the capability to have all the columns automatically the same width, or adjust to fit their contents, was a nice refinement. It’s good you took the trouble to place extensive comments in your script, so the stack is of lasting interest to other “LiveCoders”. In a word:
Ausgezeichnet!

Vielen Dank,
Michael

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Re: Set a specific cell in a field to a different color

Post by bn » Mon Oct 25, 2010 12:14 am

Michael,

thank you for your kind words. When I posted the above stack I was apparently so baffeld by the stripes that I did not notice, that the stripes dont follow the vertical scrolling of the table field. I added that to the stack I append below. The table field is really not suited for this kind of 'enhancement' since Rev does a lot of things behind your back. Very few messages get through that one can use to sync the vertical scrolling of the field and the stripes.
I hope I covered all possibilities and that the two always stay in sync. I added your mouseEnter/mouseLeave handlers, a very good idea to update the objects when text size etc was changed.

kind regards
Bernd
Attachments
TableField with scrolling Stripes.rev.zip
(4.85 KiB) Downloaded 305 times

Regulae
Posts: 136
Joined: Tue Oct 20, 2009 6:05 am

Re: Set a specific cell in a field to a different color

Post by Regulae » Thu Oct 28, 2010 1:01 pm

Hi Bernd,

I haven’t done much previous work with table fields, so comparing the two stacks “alternatingLinesColorTablefield.rev” and “TableField with scrolling Stripes.rev” has been very instructive. To check my understanding of the latter stack, I believe it is structured thus:

stack "Table field with scrolling stripes"
---|
---card id 1002 (script)
------|
------group "tfGroup" (script)
------comprising:
------field "TF" (script)
------group "alGroup"
---------comprising:
---------graphic "alternatingLines"

The main script the user’s mouse interacts with is in field "TF”- it is the resizeControl in this script that “synchronises” the graphic “alternatingLines” with the lines in field “TF”. The user operates the scrollbars of field “TF” to navigate the table field. The scrollBarDrag handler in field “TF” makes the vScroll of group “alGroup” match the vScroll of field “TF”. The advantage of making the graphic "alternatingLines" into the group "alGroup" is that it becomes scrollable, facilitating synchronising its scroll with that of field "TF". In the resizeControl handler, the "lock screen" command is accidentally commented out (just before “the owner of me is group “Tfgroup” comment), making resizing not as smooth as intended (indicated by the “unlock screen” later on). I was interested in the use of the “max” function to ensure the width of the graphic "alternatingLines" is never less than 0- I was not aware of this function, and it’s handy to know.

Getting the alternating stripes scrollable with the table field is definitely “easier said than done”. The problem is, you can add new lines to the table field by clicking in the lowest line of cells. This “shifts” all the previous lines upwards, and the alternating stripes should follow. However, the scroll changes, without generating a scrollBarDrag message. The “mouseDown” work-around is very elegant.(I well know the importance of locking messages when you set a scroll, if there is also a scrollBarDrag handler involved- the “lock up loop” I experienced when I neglected this was quite memorable.) From the seemingly simple “let’s make the alternating stripes scroll with the table field” a whole chain of implications follow- making graphic “alternatingLines” very large, then “packaging” everything in group “tfGroup”, then having a resizeControl handler in the script of group “tfGroup” to allow the user to resize the whole assembly correctly (necessitating the nice “selectedGroupControls” test) ... every piece must be in place for things to work correctly.

There’s another scenario to cover- if the down arrow is pressed repeatedly, it gets to the bottom of the visible table field then starts to add lines. Somehow the graphic “alternatingLines” must be made to scroll to match. rawKeyDown messages are sent to the focused control, and then on to the card. It's interesting that rawKeyDown does not go to the table field when you type in a cell, hence it is evidently not the focused object when you type, so the message goes to the card instead (as per the Rev Dictionary). We can conclude that Rev must be creating fields "on the fly", and when you click elsewhere, or hit the enter key, Rev uses the contents of the temporary field to update the text property of the table field itself, then deletes the temporary field. You can see this process in action if you place an object partially obscuring the table field, then press the arrow key repeatedly. The temporary field is created over its position in the cell (visible over the obscuring object because the new temporary field is created on top of everything else). Another thing I thought to try was putting:

Code: Select all

on mouseMove
   if the shiftKey is down then
      put (the name of the mouseControl)&return&(the focusedObject)
   end if
   pass mouseMove
end mouseMove
... in a frontScript, which lets you see the name of the cell, and its id. We can also see that the temporary field is the focused object, and thus if we are to respond to the rawKeyDown message, we have to put the rawKeyDown handler in the card script.

It’s interesting that the arrowKey message itself is not passed- this I imagine has something to do with the frontScript Rev uses to implement the table field. The rawKeyDown handler that triggers the “adapt” handler is the work-around that gets the graphic “alternatingLines” to synchronise with the table field when the “down” arrow is pressed. (One thing I wasn’t entirely sure of is why “adapt” had to be sent, rather than being incorporated in the rawKeyDown conditional).

I suspect the problem with the scroll resetting to 0 if you edit a cell, then click in another cell, is also buried in one of Rev's frontScripts:
button id 1116 of group id 1016 of card id 1002 of stack "C:/Program Files/Revolution Studio/4.0.0-gm-1/Toolset/revlibrary.rev"
... seems a likely candidate (of course, the path to the stack may be different on your computer, but I imagine the id’s are the same).

Looking at the frontScript which implements table fields offers a useful perspective. It’s not an easy thing to achieve, and in fairness to the original programmer/s it would be more reasonable to regard table fields as appreciably enhanced text fields, rather than as deficient datagrids. Table fields give a useful “add on” to a normal text field, lending it basic “spreadsheet-like” behaviour, though as we have seen, it is difficult to take it much further. The simplicity of table fields suffices in many circumstances.

This post is rather long, and while it serves to test my understanding, I hope there is also something of interest to others, who may be encouraged to inspect the relevant stacks.

Regards,
Michael

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Re: Set a specific cell in a field to a different color

Post by bn » Thu Oct 28, 2010 2:05 pm

Michael,
you describe the structure of the stack and what Rev does with the temporary fields very clearly and concise. I always find it fascinating when someone grasps the logic and can explain it also. I am a lot less systematic in my approach.
You even ventured into the realms of frontscripts, where I did not go. I used the behavior of the table field and the temporary field as guidance. (a complex system describes itself by its behavior). But you went on deeper into the topic, and more appropriately so.
One thing I wasn’t entirely sure of is why “adapt” had to be sent, rather than being incorporated in the rawKeyDown conditiona
I did not want to tie adapt to the rawkeyDown message but it should trigger right after the message was passed. Turns out this made for a lot faster response than what I had previously. I suppose (did not test) that the rawkeyDown -> rawkeyUp finishes before the "adapt" message gets handled. I used to have adapt in a rawkeyUp handler and it was slower.

max function: you probably read in the dictionary. What I find very handy is from the dictionary:
You can use the max and min functions together to limit a value to a certain range. For example, the expression
max(10,min(myValue,100))
yields a number between 10 and 100. If myValue is within the limits, the expression is equal to myValue; if it is greater than 100, the expression evaluates to 100; and if it is less than 10, the expression evaluates to 10.
again thank your for taking the time to look at the stack and explaining it so brilliantly.

Kind regards
Bernd

Post Reply