Saturday, July 26, 2008

Cocoa Bindings - Pop Ups

Here is a minimally reworked example from the old page. We have two Pop Up Buttons in the window, where the values available in the lower one depend on what is selected in the upper one.



The code uses a dummy class to which we add attributes (at least, I think that's what they're called). All I know is, you can't just use an NSObject here. I don't remember where I saw this originally. But this is pretty slick.

class PyBind5AppDelegate(NSObject):

def init(self):
self = super(PyBind5AppDelegate, self).init()

family = MyObject.alloc().init()
family.name = 'family'
family.who = ['Sean', 'Tom', 'Joan']
friends = MyObject.alloc().init()
friends.name = 'friends'
friends.who = ['Nyles', 'Slawek']

self.people = [family,friends]
return self

class MyObject(NSObject):
def init(self): return self

Here is how the bindings are set up. The Array controller and the first (top) popup's Content binding are standard. The first popup has an additional binding to get the selection index and the second popup is bound to that selection as the Controller key.



The next thing is to use bindings to update the model based on what is selected. I could solve this by setting the popups as outlets of the AppDelegate and asking them directly. To do it with bindings, I tried using the popup bindings for SelectionIndex and SelectedObject. (Only one of these can be used at a time---why?) Anyway, the SelectedObject worked, but only for the bottom button, and...it screwed up how the buttons look when the app runs. The method that worked was to add variables it and ib (for index top and index bottom) with set methods, and also a button / action method to report on their values. The popups SelectionIndex bindings are set as follows:



When the app first loads, report gives 'None' for both variables. If I click on a popup but don't change the value, it reports correctly, and if I change the value it reports correctly. So as long as you test for None, it works!