Implemented the new uiCombobox behavior on OS X.
This commit is contained in:
parent
eb96d5edb0
commit
8fb5d1212f
|
@ -8,8 +8,78 @@ struct uiCombobox {
|
||||||
NSArrayController *pbac;
|
NSArrayController *pbac;
|
||||||
NSComboBox *cb;
|
NSComboBox *cb;
|
||||||
NSObject *handle; // for uiControlHandle()
|
NSObject *handle; // for uiControlHandle()
|
||||||
|
void (*onSelected)(uiCombobox *, void *);
|
||||||
|
void *onSelectedData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@interface comboboxDelegateClass : NSObject<NSComboBoxDelegate> {
|
||||||
|
NSMapTable *comboboxes;
|
||||||
|
}
|
||||||
|
- (void)comboBoxSelectionDidChange:(NSNotification *)note;
|
||||||
|
- (IBAction)onSelected:(id)sender;
|
||||||
|
- (void)registerCombobox:(uiCombobox *)c;
|
||||||
|
- (void)unregisterCombobox:(uiCombobox *)c;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation comboboxDelegateClass
|
||||||
|
|
||||||
|
- (id)init
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self)
|
||||||
|
self->comboboxes = newMap();
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
if ([self->comboboxes count] != 0)
|
||||||
|
complain("attempt to destroy shared combobox delegate but comboboxes are still registered to it");
|
||||||
|
[self->comboboxes release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: does not trigger when text changed
|
||||||
|
// TODO not perfect either:
|
||||||
|
// - triggered when keyboard navigating the open menu
|
||||||
|
// - does not trigger when the text is changed to a menu item (which normally selects that item; IDK how to inhibit that behavior - TODO)
|
||||||
|
- (void)comboBoxSelectionDidChange:(NSNotification *)note
|
||||||
|
{
|
||||||
|
[self onSelected:[note object]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)onSelected:(id)sender
|
||||||
|
{
|
||||||
|
uiCombobox *c;
|
||||||
|
|
||||||
|
c = (uiCombobox *) mapGet(self->comboboxes, sender);
|
||||||
|
(*(c->onSelected))(c, c->onSelectedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)registerCombobox:(uiCombobox *)c
|
||||||
|
{
|
||||||
|
mapSet(self->comboboxes, c->handle, c);
|
||||||
|
if (c->editable)
|
||||||
|
[c->cb setDelegate:self];
|
||||||
|
else {
|
||||||
|
[c->pb setTarget:self];
|
||||||
|
[c->pb setAction:@selector(onSelected:)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)unregisterCombobox:(uiCombobox *)c
|
||||||
|
{
|
||||||
|
if (c->editable)
|
||||||
|
[c->cb setDelegate:nil];
|
||||||
|
else
|
||||||
|
[c->pb setTarget:nil];
|
||||||
|
[self->comboboxes removeObjectForKey:c->handle];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
static comboboxDelegateClass *comboboxDelegate = nil;
|
||||||
|
|
||||||
static void onDestroy(uiCombobox *);
|
static void onDestroy(uiCombobox *);
|
||||||
|
|
||||||
uiDarwinDefineControlWithOnDestroy(
|
uiDarwinDefineControlWithOnDestroy(
|
||||||
|
@ -21,6 +91,7 @@ uiDarwinDefineControlWithOnDestroy(
|
||||||
|
|
||||||
static void onDestroy(uiCombobox *c)
|
static void onDestroy(uiCombobox *c)
|
||||||
{
|
{
|
||||||
|
[comboboxDelegate unregisterCombobox:c];
|
||||||
if (!c->editable) {
|
if (!c->editable) {
|
||||||
[c->pb unbind:@"contentObjects"];
|
[c->pb unbind:@"contentObjects"];
|
||||||
[c->pb unbind:@"selectedIndex"];
|
[c->pb unbind:@"selectedIndex"];
|
||||||
|
@ -36,6 +107,24 @@ void uiComboboxAppend(uiCombobox *c, const char *text)
|
||||||
[c->pbac addObject:toNSString(text)];
|
[c->pbac addObject:toNSString(text)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intmax_t uiComboboxSelected(uiCombobox *c)
|
||||||
|
{
|
||||||
|
if (c->editable)
|
||||||
|
return [c->cb indexOfSelectedItem];
|
||||||
|
return [c->pb indexOfSelectedItem];
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data)
|
||||||
|
{
|
||||||
|
c->onSelected = f;
|
||||||
|
c->onSelectedData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void defaultOnSelected(uiCombobox *c, void *data)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
static uiCombobox *finishNewCombobox(BOOL editable)
|
static uiCombobox *finishNewCombobox(BOOL editable)
|
||||||
{
|
{
|
||||||
uiCombobox *c;
|
uiCombobox *c;
|
||||||
|
@ -78,6 +167,13 @@ static uiCombobox *finishNewCombobox(BOOL editable)
|
||||||
options:nil];
|
options:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (comboboxDelegate == nil) {
|
||||||
|
comboboxDelegate = [comboboxDelegateClass new];
|
||||||
|
[delegates addObject:comboboxDelegate];
|
||||||
|
}
|
||||||
|
[comboboxDelegate registerCombobox:c];
|
||||||
|
uiComboboxOnSelected(c, defaultOnSelected, NULL);
|
||||||
|
|
||||||
uiDarwinFinishNewControl(c, uiCombobox);
|
uiDarwinFinishNewControl(c, uiCombobox);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
|
Loading…
Reference in New Issue