I need help figuring out how to get the index of the selected menu item. When the menu is selected it calls a subroutine like this. I can get the title of the sender and that’s the menu item that was selected. But what if I wanted the index of the item?
on menuSelected_(sender)
end
I found a couple clues on Apple’s page but can’t find a good example of how to phrase that in ASObjC to get a non-error result.
indexOfItem(withTitle:)
I tried stuff like this: menuOutlet’s indexOfItem_withTitle:(“Menu Name”)
You have to get a little circular with your code, here:
set itemIndex to sender's |menu|'s indexOfItem:sender
When you click a menu, it sends a reference to the menu item that was clicked into the ‘sender’ variable. You use the ‘menu’ property of that menu item to get the menu that sent it, and then you ask that menu for the index of the menu item it sent.
That works, sort of… I have some disabled items in the menu and it appears to be returning the index position of the enabled items only, so it’s throwing it off.
Maybe another direction at this is to ask is there a way to set a controllers selection by name…?
Right now I am doing this:
groupListController's setSelectionIndex:(5)
But, given something like this
set sidebarList to {{title:"TEST HEADER", isHeader:true}, {title:"TEST ITEM", isHeader:false}, etc.
Err… ‘wonky’ is a bit difficult to diagnose. Try going to your doctor and saying “I feel wonky”, and then make sure you do not take whatever she prescribes.
Two possibilities to consider here.
First, AppleScript uses a 1-based index for lists, while Objective-C uses a 0-based index for NSArrays. usually the system figures it out, but if ‘wonky’ means you’re always off by one (e.g. it should do 4 but it does 3), then you may have to account for it manually by adding or subtracting 1 from the index.
Second, one of the functions of NSArrayController is to allow you to sort/filter items in the GUI without sorting them in the model. When you first dump an array into an array controller, the sequence of the model and the GUI should be the same, but if you’ve somehow re-sorted or filtered the controller, then you can’t refer to the model directly using indexes. Best practice is to avoid invoking the model object (in this case, ‘sidebarList’) and always refer to the array controller’s ‘arrangedObjects’ property. That way you’re assured to get the model objects ordered as they are presented in the GUI.
Now it’s “super wonky” and… working. Weird. It’s hard to describe the setup in text…
Menu and Sidebar/Controller
Header (non-selectable in menu and sidebar)
Item 1
Item 2
Header (non-selectable in menu and sidebar)
Item 3
Item 4
etc.
At first the menu would work, selecting item 1, item 2 correctly, based on the index of 1 and 2 (with the header being 0). But once I started selecting item 3, 4, etc. it was off by one or two or varied. In one case, it even selected a non-selectable header in the table when I selected a menu item an index below it.
It DOES seem to work now, so either:
I was delirious this morning.
Rebuild fixed it.
It is a problem that will reappear later due to some other issue.
I’m not explicitly sorting or changing the sidebar once established… but maybe something is affecting it somewhere. I will keep an eye on it for now.
No, still a problem. Derp. I had the test code being override by later code I forgot to comment out. So, there is a selection drift the further I go down the line but its not making a pattern that makes sense to me.
After the first non-selectable heading, it selects item at index 1 and 2 correctly.
Then after the second non-selectable heading, with the item at index 4, 5, 6, it is shifted one lower than it should be.
But then, after the third non-selectable heading, when I select menu item 8 (index) it selects the heading record at index 7 in the table. So, it goes back one.
Then I pick the item at index 9, it thinks I picked 11 and selects that.
set listItems to groupListController's arrangedObjects
repeat with a from 1 to count items of listItems
if (title of (item a of listItems)) as string = nameItem then
groupListController's setSelectionIndex:(a-1)
exit repeat
end
end
But that’s a lot more code than I hoped, but it works.
Almost certainly the problem is there, in the way you’ve wired it, but without seeing the code… If you can’t debug it, I’ll suggest a left-field solution (which I haven’t tested, but which ought to work in theory). First, when you create each menu item, set its representedObject to the appropriate data source object you want it to invoke: