# HG changeset patch # User Olaf Wintermann # Date 1756026871 -7200 # Node ID c35b2f18841c209490ff416247830eb3cabbc105 # Parent 99386f34efc9bea966a8ad14e18475b140a69344 add combobox (Cocoa) diff -r 99386f34efc9 -r c35b2f18841c make/xcode/toolkit/toolkit/main.m --- a/make/xcode/toolkit/toolkit/main.m Sun Aug 24 10:15:41 2025 +0200 +++ b/make/xcode/toolkit/toolkit/main.m Sun Aug 24 11:14:31 2025 +0200 @@ -37,6 +37,7 @@ typedef struct MyDocument { UiInteger *tbtoggle; UiList *list1; + UiList *list2; } MyDocument; MyDocument* create_doc(void) { @@ -48,6 +49,15 @@ ui_list_append(doc->list1, "Item 2"); ui_list_append(doc->list1, "Item 3"); ui_list_append(doc->list1, "Item 4"); + + doc->list2 = ui_list_new(ctx, "list2"); + ui_list_append(doc->list2, "Option 1"); + ui_list_append(doc->list2, "Option 2"); + ui_list_append(doc->list2, "Option 3"); + ui_list_append(doc->list2, "Option 4"); + ui_list_append(doc->list2, "Option 5"); + ui_list_append(doc->list2, "Option 6"); + return doc; } @@ -97,6 +107,8 @@ ui_vbox(obj, .spacing = 0, .fill = UI_OFF) { + ui_combobox(obj, .varname = "list2"); + ui_textfield(obj, .varname = "textfield1"); ui_radiobutton(obj, .label = "V Button 1", .varname = "radio1"); ui_radiobutton(obj, .label = "V Button 2", .varname = "radio1"); diff -r 99386f34efc9 -r c35b2f18841c ui/cocoa/list.h --- a/ui/cocoa/list.h Sun Aug 24 10:15:41 2025 +0200 +++ b/ui/cocoa/list.h Sun Aug 24 11:14:31 2025 +0200 @@ -32,6 +32,26 @@ #import "ListDataSource.h" +@interface UiDropDown : NSObject + +@property UiObject *obj; +@property ui_callback onactivate; +@property void *onactivatedata; +@property ui_callback onselection; +@property void *onselectiondata; +@property ui_getvaluefunc2 getvalue; +@property void *getvaluedata; +@property UiVar *var; +@property (weak) NSComboBox *combobox; + +- (id)init:(UiObject*)obj; + +@end + void ui_tableview_update(UiList *list, int i); UiListSelection ui_tableview_getselection(UiList *list); void ui_tableview_setselection(UiList *list, UiListSelection selection); + +void ui_dropdown_update(UiList *list, int i); +UiListSelection ui_dropdown_getselection(UiList *list); +void ui_dropdown_setselection(UiList *list, UiListSelection selection); diff -r 99386f34efc9 -r c35b2f18841c ui/cocoa/list.m --- a/ui/cocoa/list.m Sun Aug 24 10:15:41 2025 +0200 +++ b/ui/cocoa/list.m Sun Aug 24 11:14:31 2025 +0200 @@ -214,3 +214,143 @@ } +/* --------------------------- DropDown --------------------------- */ + +@implementation UiDropDown + +- (id)init:(UiObject*)obj { + _obj = obj; + return self; +} + +- (void) comboBoxSelectionDidChange:(NSNotification *) notification { + int index = (int)_combobox.indexOfSelectedItem; + + void *eventdata = NULL; + if(_var) { + UiList *list = _var->value; + if(index >= 0) { + eventdata = list->get(list, index); + } + } else { + NSString *str = _combobox.objectValueOfSelectedItem; + if(str) { + eventdata = (void*)str.UTF8String; + } + } + + UiEvent event; + event.obj = _obj; + event.window = event.obj->window; + event.document = event.obj->ctx->document; + event.eventdata = eventdata; + event.eventdatatype = UI_EVENT_DATA_LIST_ELM; + event.intval = index; + + if(_onselection) { + _onselection(&event, _onselectiondata); + } + + if(_onactivate) { + _onactivate(&event, _onactivatedata); + } +} + +@end + +UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs *args) { + NSComboBox *dropdown = [[NSComboBox alloc] init]; + dropdown.editable = NO; + + UiDropDown *uidropdown = [[UiDropDown alloc] init:obj]; + objc_setAssociatedObject(dropdown, "ui_dropdown", uidropdown, OBJC_ASSOCIATION_RETAIN); + uidropdown.onactivate = args->onactivate; + uidropdown.onactivatedata = args->onactivatedata; + uidropdown.onselection = args->onselection; + uidropdown.onselectiondata = args->onselectiondata; + uidropdown.combobox = dropdown; + + if(!args->getvalue2) { + if(args->getvalue) { + args->getvalue2 = getvalue_wrapper; + args->getvalue2data = (void*)args->getvalue; + } else { + args->getvalue2 = str_getvalue; + } + } + uidropdown.getvalue = args->getvalue2; + uidropdown.getvaluedata = args->getvalue2data; + + UiLayout layout = UI_INIT_LAYOUT(args); + ui_container_add(obj, dropdown, &layout, FALSE); + + UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); + if(var) { + UiList *list = var->value; + list->obj = (__bridge void*)dropdown; + list->update = ui_dropdown_update; + list->getselection = ui_dropdown_getselection; + list->setselection = ui_dropdown_setselection; + ui_dropdown_update(list, -1); + } else { + for(int i=0;istatic_nelm;i++) { + char *str = args->static_elements[i]; + NSString *item = [[NSString alloc] initWithUTF8String:str]; + [dropdown addItemWithObjectValue:item]; + } + } + + uidropdown.var = var; + + return (__bridge void*)dropdown; +} + +void ui_dropdown_update(UiList *list, int i) { + NSComboBox *combobox = (__bridge NSComboBox*)list->obj; + UiDropDown *dropdown = objc_getAssociatedObject(combobox, "ui_dropdown"); + if(dropdown) { + [combobox removeAllItems]; + + ui_getvaluefunc2 getvalue = dropdown.getvalue; + void *getvaluedata = dropdown.getvaluedata; + + int index = 0; + void *elm = list->first(list); + while(elm) { + UiBool freeResult = FALSE; + char *str = getvalue(list, elm, index, 0, getvaluedata, &freeResult); + if(str) { + NSString *item = [[NSString alloc] initWithUTF8String:str]; + [combobox addItemWithObjectValue:item]; + } + if(freeResult) { + free(str); + } + elm = list->next(list); + index++; + } + } else { + fprintf(stderr, "Error: obj is not a dropdown\n"); + } +} + +UiListSelection ui_dropdown_getselection(UiList *list) { + UiListSelection sel = { 0, NULL }; + NSComboBox *combobox = (__bridge NSComboBox*)list->obj; + NSInteger index = combobox.indexOfSelectedItem; + if(index >= 0) { + sel.rows = malloc(sizeof(int)); + sel.count = 1; + sel.rows[0] = (int)index; + } + return sel; +} + +void ui_dropdown_setselection(UiList *list, UiListSelection selection) { + NSComboBox *combobox = (__bridge NSComboBox*)list->obj; + if(selection.count > 0) { + [combobox selectItemAtIndex:selection.rows[0]]; + } else { + [combobox selectItemAtIndex: -1]; + } +}