Wednesday, November 22, 2017

#1 2006-03-07 04:25:37 pm

jann
Member
Registered: 2006-02-24
Posts: 22

Change color of cell in Table View (I know it's been discussed before)

To change a single cell's color, I have the following:

I know it is probably not the BEST way to go about it, but I do the following.  When i get to a line in my code that i change a cell AND i want to call attention to it, i set the following:

Applescript:


set ChangeTheColorOfMailingLogCells to 1
set ChangeTheColorForOrderID to "999-999-999"
set the contents of data cell "table_status" of myRow to trackinginfo

here is the will change cell handler:

Applescript:


on will display cell theObject cell theCell row theRow table column tableColumn
if ChangeTheColorOfMailingLogCells is equal to 1 then
       if the name of theObject is equal to "mailinglog_table" then
           if the identifier of tableColumn is equal to "table_status" then
               set EndiciaDetailDataSource to the data source of theObject
               
               set rowcounter to 1
               repeat with i in every data row of EndiciaDetailDataSource
                   if rowcounter is equal to theRow then
                       if contents of data cell "table_ordernumber" of i is equal to ChangeTheColorForOrderID then
                           log "Would highlight row # " & rowcounter & " or " & theRow & " having the email: " & contents of data cell "table_customeremail" of i
                           set text color of theCell to {30000, 0, 0}
                           set ChangeTheColorOfMailingLogCells to 0
                           set ChangeTheColorForOrderID to ""
                           -- works without the following
                           -- update theObject
                           exit repeat
                       end if
                       
                   end if
                   set rowcounter to rowcounter + 1
               end repeat
               
               
           end if
           
       end if
   end if
end will display cell

Okay, what happens is the following:

If the row to change is the 3rd row, then the 3rd through the last rows (that column only) turn red.  IF I SCROLL the table view or in any way cause it to update (by resizeing or such) then the ENTIRE column for all the rows (even the first through the second) update to red.

Anyone know why?

TIA

Jann

(edited for misspelling of will display handler)

Last edited by jann (2006-03-07 04:28:56 pm)

Offline

 

#2 2006-04-06 08:31:19 am

Spock
Member
Registered: 2006-03-24
Posts: 24

Re: Change color of cell in Table View (I know it's been discussed before)

try the following:

in the "if" part you set a color.
make an Else part, where you set the color to black (or whatever you prefer)

Offline

 

#3 2006-10-01 04:31:49 pm

tdog
Member
Registered: 2006-07-28
Posts: 46

Re: Change color of cell in Table View (I know it's been discussed before)

Have you actually been able to get either text or the data cell to have a specified color?  It seems to be one of the great secrets of applescript.  I've found all kinds of people asking the question but have never found an answer.

Offline

 

#4 2006-10-03 05:18:05 am

Dominik
Member
Registered: 2006-02-09
Posts: 493

Re: Change color of cell in Table View (I know it's been discussed before)

Jann,

many thanks for this - I didn't know this is possible from AppleScript (I always used to subclass NSTableColumn for this + override 'dataCellForRow:'). 'on will display cell' is a much easier solution :-)

@tdog:

here an example to set text and background colors in a table view (single column with an NSTextFieldCell, 'Draw background' option checked):

Applescript:

global ds

on awake from nib theObject
   set content of theObject to {"red background", "green text", "blue text", "red text", "green background", "blue background", "nothing", "blue text", "red background"}
   set ds to data source of theObject
end awake from nib

on will display cell theObject cell theCell row theRow table column tableColumn
   set cellcontents to (contents of data cell 1 of data row theRow of ds)
   if cellcontents contains "text" then
       set textCol to (my getColor(cellcontents))
       if textCol is not {} then
           set text color of theCell to textCol
           set background color of theCell to {65535, 65535, 65535}
       end if
   else if cellcontents contains "background" then
       set bCol to (my getColor(cellcontents))
       if bCol is not {} then
           set background color of theCell to bCol
           set text color of theCell to {65535, 65535, 65535}
       end if
   else
       set text color of theCell to {0, 0, 0}
       set background color of theCell to {65535, 65535, 65535}
   end if
end will display cell

on getColor(cellcontents)
   if cellcontents contains "red" then
       return {65535, 0, 0}
   else if cellcontents contains "green" then
       return {0, 65535, 0}
   else if cellcontents contains "blue" then
       return {0, 0, 65535}
   else
       return {}
   end if
end getColor

Here a screenshot of the result

D.

Last edited by Dominik (2006-10-03 05:32:25 am)

Offline

 

#5 2006-10-09 10:03:34 pm

tdog
Member
Registered: 2006-07-28
Posts: 46

Re: Change color of cell in Table View (I know it's been discussed before)

OK, this is great.  But It does slow down operation quite a bit if you have a routine to check the contents for validity and color accordingly. 

In fact, for some reason, when I double click in a cell in order to edit, the entire column turns the color of the last text colored cell.  As does the cell itself if I just select it.  Any ideas what might be going on?

Offline

 

#6 2006-10-12 10:21:56 am

Dominik
Member
Registered: 2006-02-09
Posts: 493

Re: Change color of cell in Table View (I know it's been discussed before)

tdog wrote:

OK, this is great.  But It does slow down operation quite a bit if you have a routine to check the contents for validity and color accordingly. 

In fact, for some reason, when I double click in a cell in order to edit, the entire column turns the color of the last text colored cell.  As does the cell itself if I just select it.  Any ideas what might be going on?


tdog,

what's going on? The problem with this method of colorizing the table is, that you really have to tell every cell of the colored column which colors you want - If you don't, they'll get the colors of the last colors specified for this column's cell ... Why? That's because there isn't a permanently existing cell object for every row of a column - the column creates them 'on the fly' - using instances of a 'master cell'. The only chance to influence this process is the applescript handler - as described here - or an Objective-C method (subclass overriding 'dataCellForRow:'). Both methods are called by the column whenever it is about to display a cell. The column says: 'Hey - I want to display the cell object of row n' and here is your chance to say - 'Ok - take it, but change it's textcolor or background color etc.'

If the Applescript way is too slow it's since your script part that determines the colors has to be called everytime the column  updates (which can be quite often).
So what remains might be the NSTableColumn subclass. I've rewritten my example of two msgs above using this method. The big advantage is speed - the subclass holds a list (NSMutableArray) for every row's colors so if there are changes the applescript is only called once to determine the colors of a cell.

1. The subclass files:

- go to Interface Builder -> MainMenu.nib -> Classes Tab and Subclass 'NSTableColumn' (Ctrl+Click it and select the first menu item of the context menu)
- name this Subclass -('ColoredCellsTableColumn' in my example)
- select the new Subclass and Controll-Click it - then select 'Create Files for ...'
- select the column you want to use the subclass for and select the 'Custom Class' Tab of the Inspector Window (or enter Apple+5)
- choose the new Subclass for the column
- save

- then switch to Xcode
- there should be 2 new files added to your project: <yoursubclass>.h and <yoursubclass>.m

copy & paste this:

Applescript:

//File: ColoredCellsTableColumn.h:

#import <Cocoa/Cocoa.h>

@interface ColoredCellsTableColumn : NSTableColumn{
   NSMutableArray *cellColors;
   NSMutableArray *textColors;
}

-(void)initColors;
-(void)setColor:(NSArray *)theColor forRow:(int)row;
-(void)setTextColor:(NSArray *)theColor forRow:(int)row;
-(void)insertRow:(int)row;
-(void)insertRow:(int)row withBackgroundColor:(NSArray *)bColor withTextColor:(NSArray *)tColor;
-(void)deleteRow:(int)row;
@end

Applescript:

//File: ColoredCellsTableColumn.m:

#import "ColoredCellsTableColumn.h"

@implementation ColoredCellsTableColumn

-(void) initColors{
   cellColors = [[NSMutableArray alloc] init];
   textColors = [[NSMutableArray alloc] init];
}

- (void) dealloc {
   [cellColors release];
   [textColors release];
   [super dealloc];
}

- (id)dataCellForRow:(int)row{
   NSTextFieldCell *returnedCell = [super dataCellForRow:row];
   if ( [cellColors objectAtIndex:row] ) {
       [returnedCell setBackgroundColor:[cellColors objectAtIndex:row]];
   } else {
    [returnedCell setBackgroundColor:[NSColor whiteColor]];
   }
   if ( [textColors objectAtIndex:row]) {
       [returnedCell setTextColor:[textColors objectAtIndex:row]];
   } else {
    [returnedCell setTextColor:[NSColor blackColor]];
   }
return returnedCell;
}

-(void)setColor:(NSArray *)theColor forRow:(int)row{
   row--;
   int arrayCount = [cellColors count];
   int n;
   if (arrayCount < row) {
       for(n=arrayCount; n<row; n++) {
           [cellColors addObject:[NSColor whiteColor]];
       }
       [cellColors addObject:theColor];
   } else if (arrayCount == row) {
       [cellColors addObject:
           [NSColor colorWithCalibratedRed:[[theColor objectAtIndex:0] intValue] / 65535.0
                                    green:[[theColor objectAtIndex:1] intValue] / 65535.0
                                    blue:[[theColor objectAtIndex:2] intValue] / 65535.0
                                    alpha:1.0]];
   } else {
       [cellColors replaceObjectAtIndex:row withObject:
           [NSColor colorWithCalibratedRed:[[theColor objectAtIndex:0] intValue] / 65535.0
                                    green:[[theColor objectAtIndex:1] intValue] / 65535.0
                                    blue:[[theColor objectAtIndex:2] intValue] / 65535.0
                                    alpha:1.0]];
   }
}

-(void)setTextColor:(NSArray *)theColor forRow:(int)row{
   row--;
   int arrayCount = [textColors count];
   int n;
   if (arrayCount < row) {
       for (n=arrayCount; n<row; n++) {
           [textColors addObject:[NSColor blackColor]];
       }
       [textColors addObject:theColor];
   } else if (arrayCount == row) {
       [textColors addObject:
           [NSColor colorWithCalibratedRed:[[theColor objectAtIndex:0] intValue] / 65535.0
                                    green:[[theColor objectAtIndex:1] intValue] / 65535.0
                                    blue:[[theColor objectAtIndex:2] intValue] / 65535.0
                                    alpha:1.0]];        
   } else {
       [textColors replaceObjectAtIndex:row withObject:
           [NSColor colorWithCalibratedRed:[[theColor objectAtIndex:0] intValue] / 65535.0
                                    green:[[theColor objectAtIndex:1] intValue] / 65535.0
                                    blue:[[theColor objectAtIndex:2] intValue] / 65535.0
                                    alpha:1.0]];
   }
}


-(void)insertRow:(int)row{
   row--;
   if (row < [textColors count]) {
       [textColors insertObject:[NSColor blackColor] atIndex:row];
   } else {
       [textColors addObject:[NSColor blackColor]];
   }
   if (row < [cellColors count]) {
       [cellColors insertObject:[NSColor whiteColor] atIndex:row];
   } else {
       [cellColors addObject:[NSColor blackColor]];
   }
}

-(void)insertRow:(int)row withBackgroundColor:(NSArray *)bColor withTextColor:(NSArray *)tColor{
   row--;
   if (row < [textColors count]) {
       [cellColors insertObject:
       [NSColor colorWithCalibratedRed:[[bColor objectAtIndex:0] intValue] / 65535.0
                                green:[[bColor objectAtIndex:1] intValue] / 65535.0
                                blue:[[bColor objectAtIndex:2] intValue] / 65535.0
                                alpha:1.0]
                    atIndex:row];
   } else {
       [cellColors addObject:
       [NSColor colorWithCalibratedRed:[[bColor objectAtIndex:0] intValue] / 65535.0
                                green:[[bColor objectAtIndex:1] intValue] / 65535.0
                                blue:[[bColor objectAtIndex:2] intValue] / 65535.0
                                alpha:1.0]
                   ];
   }
                   
   if (row < [cellColors count]) {    
       [textColors insertObject:    
       [NSColor colorWithCalibratedRed:[[tColor objectAtIndex:0] intValue] / 65535.0
                                green:[[tColor objectAtIndex:1] intValue] / 65535.0
                                blue:[[tColor objectAtIndex:2] intValue] / 65535.0
                                alpha:1.0]
                    atIndex:row];
   } else {
       [textColors addObject:    
       [NSColor colorWithCalibratedRed:[[tColor objectAtIndex:0] intValue] / 65535.0
                                green:[[tColor objectAtIndex:1] intValue] / 65535.0
                                blue:[[tColor objectAtIndex:2] intValue] / 65535.0
                                alpha:1.0]
                    ];
   }
}

-(void)deleteRow:(int)row{
   [textColors removeObjectAtIndex:--row];
   [cellColors removeObjectAtIndex:row];
}

@end

and here's the AppleScript. I've added two buttons to demonstrate how to insert & delete.
The table column is named: table column "coloredCells" of table view "tv" of scroll view "sv" of window "main"
The buttons: button "insert" of window "main" and button "delete" of window "main"


Applescript:

global ds

on awake from nib theObject
   set theStartContent to {"1 red background", "2 green text", "3 blue text", "4 red text", "5 green background", "6 blue background", "7 nothing", "8 blue text", "9 red background"}
   set theRow to 1
   set theColumn to table column "coloredCells" of table view "tv" of scroll view "sv" of window "main"
   call method "initColors" of theColumn
   repeat with nextObj in theStartContent
       my setColors(nextObj, theRow, theColumn)
       set theRow to theRow + 1
   end repeat
   set content of theObject to theStartContent
   set ds to data source of theObject
end awake from nib

on cell value changed theObject row theRow table column tableColumn value theValue
   my setColors(theValue, theRow, tableColumn)
end cell value changed

on clicked theObject
   if (name of theObject) is "delete" then
       tell table view "tv" of scroll view "sv" of window "main"
           set sel to selected rows
           repeat with n from (count of sel) to 1 by -1
               delete data row (item n of sel) in it's data source
               call method "deleteRow:" of table column "coloredCells" with parameter (item n of sel)
           end repeat
           set selected rows to {}
       end tell
   else if (name of theObject) is "insert" then
       tell table view "tv" of scroll view "sv" of window "main"
           tell it's data source
               set newItem to "new item with " & (some item of {"red", "green", "blue"}) & (some item of {" text", " background"})
               set insertBefore to (random number (count of data rows)) + 1
               make new data row at before data row insertBefore
               set contents of data row insertBefore to newItem
           end tell
           call method "insertRow:" of table column "coloredCells" with parameter insertBefore
           my setColors(newItem, insertBefore, table column "coloredCells")
       end tell
   end if
end clicked

on setColors(cellcontents, theRow, theColumn)
   tell theColumn
       if cellcontents contains "text" then
           set textCol to (my getColor(cellcontents))
           if textCol is not {} then
               call method "setTextColor:forRow:" of it with parameters {textCol, theRow}
               call method "setColor:forRow:" of it with parameters {{65535, 65535, 65535}, theRow}
           end if
       else if cellcontents contains "background" then
           set bCol to (my getColor(cellcontents))
           if bCol is not {} then
               call method "setColor:forRow:" of it with parameters {bCol, theRow}
               call method "setTextColor:forRow:" of it with parameters {{65535, 65535, 65535}, theRow}
           end if
       else
           call method "setTextColor:forRow:" of it with parameters {{0, 0, 0}, theRow}
           call method "setColor:forRow:" of it with parameters {{65535, 65535, 65535}, theRow}
       end if
       
   end tell
end setColors

on getColor(cellcontents)
   if cellcontents contains "red" then
       return {65535, 0, 0}
   else if cellcontents contains "green" then
       return {0, 65535, 0}
   else if cellcontents contains "blue" then
       return {0, 0, 65535}
   else
       return {}
   end if
end getColor

D.

Offline

 

#7 2012-05-28 10:35:24 am

ionah
Member
From:: Paris, France
Registered: 2002-12-10
Posts: 26

Re: Change color of cell in Table View (I know it's been discussed before)

Hi Dominik,

Are you still there?

I'm wondering: is it possible to adapt your method for changing text color of the selected row of a table?

Any help would be great.

smile


Jonas Whale

Offline

 

#8 2012-05-28 11:46:15 am

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11482
Website

Re: Change color of cell in Table View (I know it's been discussed before)

just to change the text color of the selected cell(s) try this

Applescript:


on will display cell theObject cell theCell row theRow table column tableColumn
   if theCell is highlighted then
       set text color of theCell to {0, 0, 0}
   end if
end will display cell

as far as I remember you have to connect the event handler of the table view in Interface Builder


regards

Stefan

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)