[Xcode] Enabled state of table row

asobjc
(Jonas Whale) #1

I would like to set the enabled state of a table row in Xcode, depending on the content of one of its cells.
Is it possible?
:wink:

0 Likes

(Shane Stanley) #2

Yes, it is possible :wink:

0 Likes

(Jonas Whale) #3

Ok. Here is the situation:
I need to make each row which first cell starts with ‘[‘ disabled and not selectable.

How to achieve this?

0 Likes

(Ed Stockly) #4

I like where you’re going with this script. I’m doing something similar with Myriad Tables.

An appleScript palette could be very cool.

0 Likes

(Jonas Whale) #5

Hi Ed,

It’s not a script but a Xcode app.
The window is a NSPanel that stays above documents.
It does not dismiss when a button is clicked.

It’s almost a real palette…
:slight_smile:

0 Likes

(Shane Stanley) #6

You need to provide more information. Is it a cell-based table or view-based? Are you using bindings or a data-source? Is the info you show in an array of dictionaries?

0 Likes

(Jonas Whale) #7

The table is cell-based.
It uses bindings and the info is in a list of records.

In fact, I started with your « File table » from AppleScriptObjC Explored as a reference.

0 Likes

(Shane Stanley) #8

OK, you need to implement the delegate method -tableView:shouldSelectRow:, which should return true or false depending on whether you want the selection to go ahead. Assuming the key for the relevant value in your records is theName, you would use something like this:

on tableView:theTable shouldSelectRow:theRow
	set rowObject to thearrayController's arrangedObjects()'s objectAtIndex:theRow
	return not (((rowObject's objectForKey:"theName")'s hasPrefix:"[") as boolean)
end tableView:shouldSelectRow:

It might be cleaner to add and extra value to your records when you build the array — say, a boolean value for the key canSelect. Then the handler would be:

on tableView:theTable shouldSelectRow:theRow
	set rowObject to thearrayController's arrangedObjects()'s objectAtIndex:theRow
	return (rowObject's objectForKey:"canSelect") as boolean
end tableView:shouldSelectRow:
0 Likes

(Jonas Whale) #9

Can’t make it work.
Do I have to bind something to the delegate or just copy/paste your snippet in the AppDelegate script?

0 Likes

(Shane Stanley) #10

You need to make your app delegate also the delegate of the table. Drag from delegate in that HUD view to the icon for your app delegate.

0 Likes

(Jonas Whale) #11

I’m not lucky…
Every single row is now unselectable.
I get these errors in the log console:

2019-04-16 12:48:31.342485+0200 Script Palette[47924:7428374] *** -[AppDelegate tableView:shouldSelectRow:]: -[_NSControllerArrayProxy objectAtindex:]: unrecognized selector sent to instance 0x620000003a90 (error -10000)
2019-04-16 12:48:31.342683+0200 Script Palette[47924:7428374] -[_NSControllerArrayProxy objectAtindex:]: unrecognized selector sent to instance 0x620000003a90
2019-04-16 12:48:31.342798+0200 Script Palette[47924:7428374] *** -[AppDelegate tableView:shouldSelectRow:]: -[_NSControllerArrayProxy objectAtindex:]: unrecognized selector sent to instance 0x620000003a90 (error -10000)

The binding:

aaa

0 Likes

(Shane Stanley) #12

Oops: objectAtIndex:. I’ll amend the post for future lurkers.

0 Likes

(Jonas Whale) #13

Ahhhhhh! I’m loosing my eyes!

May I ask for a last thing?
How to disable the same rows that are not selectable?
Or at least their 1st cell (those who’s text content is wrapped in brackets).
I thought about binding, but…
:wink:

0 Likes

(Shane Stanley) #14

Assuming you add the canSelect value, you could probably bind the Enabled property of the column to the array controller using that key.

Otherwise you need to implement another delegate method, -tableView:willDisplayCell:forTableColumn:row:, and set enabled or not accordingly.

0 Likes

(Jonas Whale) #15

Like this?

capture%20003

It has no effect.

0 Likes

(Jonas Whale) #16

The panel has a dark gray box in background, the view and the table does not draw background, each window item has an “Divide Blend Mode” Core Animation filter.
I guess it’s the reason why the binding seems to have no effect.
So I’m using the tableView:willDisplayCell:forTableColumn:row: method to change the text color.

Here’s the snippet:

	on tableView:theTable willDisplayCell:theCell forTableColumn:theCol row:theRow
		set {grey1, grey2} to {0.7, 0.95}
		set rowObject to theArrayController's arrangedObjects()'s objectAtIndex:theRow
		if (not (rowObject's objectForKey:"theSelect") as boolean) then theCell's setTextColor:(current application's NSColor's colorWithRed:grey1 green:grey1 blue:grey1 alpha:1) 
		if ((rowObject's objectForKey:"theSelect") as boolean) then theCell's setTextColor:(current application's NSColor's colorWithRed:grey2 green:grey2 blue:grey2 alpha:1) 
	end tableView:willDisplayCell:forTableColumn:row:

Shane, I want to thank you again for your willingness to help.
Without your books, examples and answers here, I could not achieve this project.
:wink:

0 Likes

(Shane Stanley) #17

I suspect the reason is even simpler: disabling a text field doesn’t change its appearance.

0 Likes

(Jonas Whale) #18

Yes, it does.
In an earlier version I thought that, with the good predicate, I could disable the rows.
Here is how it looks like:

The entire column was disable because the predicate was badly written and always returning false.
[I don’t know if a predicate can be used here…]

0 Likes