diff options
| author | Pietro Gagliardi <[email protected]> | 2014-07-02 22:53:03 -0400 |
|---|---|---|
| committer | Pietro Gagliardi <[email protected]> | 2014-07-02 22:53:03 -0400 |
| commit | 8a81650b3da7ce00725336df9e03b38e935c5a65 (patch) | |
| tree | 08af843f0460e7226f305cf7162021ef54e8c3f7 /combobox_darwin.m | |
| parent | 4dd5ceb11d62bd6b9af4847936314a9d8c45707f (diff) | |
Moved it all back; the preemptive multitaksing during an event handler kills us on all platforms. Going to have to restrict ALL GUI accss to happening from one t hread, so going to need to drop uitask entirely and have just a start() callback for startup code and a post() function for posting requests to windows (like channel sends but into a perpetual buffer).
Diffstat (limited to 'combobox_darwin.m')
| -rw-r--r-- | combobox_darwin.m | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/combobox_darwin.m b/combobox_darwin.m new file mode 100644 index 0000000..8d337b9 --- /dev/null +++ b/combobox_darwin.m @@ -0,0 +1,105 @@ +// 17 may 2014 + +#include "objc_darwin.h" +#import <AppKit/NSPopUpButton.h> +#import <AppKit/NSComboBox.h> +#import <AppKit/NSArrayController.h> + +/* +Cocoa doesn't have combo boxes in the sense that other systems do. NSPopUpButton is not editable and technically behaves like a menu on a menubar. NSComboBox is editable and is the more traditional combo box, but the edit field and list are even more separated than they are on other platforms. + +Unfortunately, their default internal storage mechanisms exhibit the automatic selection behavior I DON'T want, so we're going to have to do that ourselves. + +The NSArrayController we use in our Listboxes already behaves the way we want. Consequently, you'll notice a bunch of functions here call functions in listbox_darwin.m. How convenient =P (TODO separate into objc_darwin.m?) + +TODO should we use NSComboBox's dataSource feature? +*/ + +extern NSRect dummyRect; + +#define to(T, x) ((T *) (x)) +#define toNSPopUpButton(x) to(NSPopUpButton, (x)) +#define toNSComboBox(x) to(NSComboBox, (x)) + +#define toNSInteger(x) ((NSInteger) (x)) +#define fromNSInteger(x) ((intptr_t) (x)) + +#define COMBOBOXKEY @"cbitem" +static NSString *comboboxKey = COMBOBOXKEY; +static NSString *comboboxBinding = @"contentValues"; +static NSString *comboboxKeyPath = @"arrangedObjects." COMBOBOXKEY; + +id makeCombobox(BOOL editable) +{ + NSArrayController *ac; + + ac = makeListboxArray(); +#define BIND bind:comboboxBinding toObject:ac withKeyPath:comboboxKeyPath options:nil +// for NSPopUpButton, we need a little extra work to make it respect the NSArrayController's selection behavior properties +// thanks to stevesliva (http://stackoverflow.com/questions/23715275/cocoa-how-do-i-suppress-nspopupbutton-automatic-selection-synchronization-nsar) +// note: selectionIndex isn't listed in the Cocoa Bindings Reference for NSArrayController under exposed bindings, but is in the Cocoa Bindings Programming Topics under key-value observant properties, so we can still bind to it +#define BINDSEL bind:@"selectedIndex" toObject:ac withKeyPath:@"selectionIndex" options:nil + + if (!editable) { + NSPopUpButton *pb; + + pb = [[NSPopUpButton alloc] + initWithFrame:dummyRect + pullsDown:NO]; + [pb BIND]; + [pb BINDSEL]; + return pb; + } + + NSComboBox *cb; + + cb = [[NSComboBox alloc] + initWithFrame:dummyRect]; + [cb setUsesDataSource:NO]; + [cb BIND]; + // no need to bind selection + return cb; +} + +id comboboxText(id c, BOOL editable) +{ + if (!editable) + return [toNSPopUpButton(c) titleOfSelectedItem]; + return [toNSComboBox(c) stringValue]; +} + +void comboboxAppend(id c, BOOL editable, id str) +{ + id ac; + + ac = boundListboxArray(c, comboboxBinding); + listboxArrayAppend(ac, toListboxItem(comboboxKey, str)); +} + +void comboboxInsertBefore(id c, BOOL editable, id str, intptr_t before) +{ + id ac; + + ac = boundListboxArray(c, comboboxBinding); + listboxArrayInsertBefore(ac, toListboxItem(comboboxKey, str), before); +} + +intptr_t comboboxSelectedIndex(id c) +{ + // both satisfy the selector + return fromNSInteger([toNSPopUpButton(c) indexOfSelectedItem]); +} + +void comboboxDelete(id c, intptr_t index) +{ + id ac; + + ac = boundListboxArray(c, comboboxBinding); + listboxArrayDelete(ac, index); +} + +intptr_t comboboxLen(id c) +{ + // both satisfy the selector + return fromNSInteger([toNSPopUpButton(c) numberOfItems]); +} |
