ui/cocoa/window.m

changeset 110
c00e968d018b
parent 108
77254bd6dccb
child 112
c3f2f16fa4b8
--- a/ui/cocoa/window.m	Sun Aug 24 15:24:16 2025 +0200
+++ b/ui/cocoa/window.m	Sat Oct 04 14:52:59 2025 +0200
@@ -42,14 +42,14 @@
 #include <cx/mempool.h>
 
 
-static UiObject* create_window(const char *title, BOOL simple) {
+static UiObject* create_window(const char *title, BOOL simple, BOOL sidebar) {
     CxMempool *mp = cxMempoolCreateSimple(256);
     UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject));
     obj->ref = 0;
     
     obj->ctx = uic_context(obj, mp);
     
-    MainWindow *window = [[MainWindow alloc] init:obj];
+    MainWindow *window = [[MainWindow alloc] init:obj withSidebar:sidebar];
     [[WindowManager sharedWindowManager] addWindow:window];
     window.releasedWhenClosed = false;
     
@@ -64,13 +64,169 @@
 }
 
 UiObject* ui_window(const char *title, void *window_data) {
-    UiObject *obj = create_window(title, FALSE);
+    UiObject *obj = create_window(title, FALSE, FALSE);
     obj->window = window_data;
     return obj;
 }
 
 UiObject* ui_simple_window(const char *title, void *window_data) {
-    UiObject *obj = create_window(title, TRUE);
+    UiObject *obj = create_window(title, TRUE, FALSE);
+    obj->window = window_data;
+    return obj;
+}
+
+UiObject* ui_sidebar_window(const char *title, void *window_data) {
+    UiObject *obj = create_window(title, FALSE, TRUE);
     obj->window = window_data;
     return obj;
 }
+
+/* --------------------------------- File Dialogs --------------------------------- */
+
+void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) {
+    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
+    if((mode & UI_FILEDIALOG_SELECT_MULTI) == UI_FILEDIALOG_SELECT_MULTI) {
+        openPanel.allowsMultipleSelection = YES;
+    }
+    if((mode & UI_FILEDIALOG_SELECT_FOLDER) == UI_FILEDIALOG_SELECT_FOLDER) {
+        openPanel.canChooseFiles = NO;
+        openPanel.canChooseDirectories = YES;
+    }
+    
+    NSWindow *window = (__bridge NSWindow*)obj->wobj;
+    [openPanel beginSheetModalForWindow:window completionHandler:^(NSModalResponse result) {
+        UiEvent event;
+        event.obj = obj;
+        event.window = obj->window;
+        event.document = obj->ctx->document;
+        event.intval = 0;
+        event.set = 0;
+        
+        UiFileList flist = { NULL, 0 };
+        event.eventdata = &flist;
+        event.eventdatatype = UI_EVENT_DATA_FILE_LIST;
+        
+        if(result == NSModalResponseOK) {
+            NSArray<NSURL *> *urls = [openPanel URLs];
+            flist.files = calloc(urls.count, sizeof(char*));
+            for(NSURL *url in urls) {
+                if([url isFileURL]) {
+                    flist.files[flist.nfiles++] = strdup(url.path.UTF8String);
+                }
+            }
+        }
+        
+        if(file_selected_callback) {
+            file_selected_callback(&event, cbdata);
+        }
+        ui_filelist_free(flist);
+    }];
+}
+
+void ui_savefiledialog(UiObject *obj, const char *name, ui_callback file_selected_callback, void *cbdata) {
+    NSSavePanel *savePanel = [NSSavePanel savePanel];
+    if(name) {
+        NSString *nameStr = [[NSString alloc] initWithUTF8String:name];
+        [savePanel setNameFieldStringValue: nameStr];
+    }
+    
+    NSWindow *window = (__bridge NSWindow*)obj->wobj;
+    [savePanel beginSheetModalForWindow:window completionHandler:^(NSModalResponse result) {
+        UiEvent event;
+        event.obj = obj;
+        event.window = obj->window;
+        event.document = obj->ctx->document;
+        event.intval = 0;
+        event.set = 0;
+        
+        UiFileList flist = { NULL, 0 };
+        event.eventdata = &flist;
+        event.eventdatatype = UI_EVENT_DATA_FILE_LIST;
+        
+        if(result == NSModalResponseOK) {
+            NSURL *url = [savePanel URL];
+            if([url isFileURL]) {
+                NSString *path = url.path;
+                flist.files = malloc(sizeof(char*));
+                flist.files[0] = strdup(path.UTF8String);
+                flist.nfiles = 1;
+            }
+            file_selected_callback(NULL, NULL);
+        }
+        if(file_selected_callback) {
+            file_selected_callback(&event, cbdata);
+        }
+        ui_filelist_free(flist);
+    }];
+}
+
+/* ------------------------------------- Dialog ------------------------------------- */
+
+void ui_dialog_create(UiObject *parent, UiDialogArgs *args) {
+    NSAlert *dialog = [[NSAlert alloc] init];
+    
+    if(args->title) {
+        dialog.messageText = [[NSString alloc]initWithUTF8String:args->title];
+    }
+    if(args->content) {
+        dialog.informativeText = [[NSString alloc]initWithUTF8String:args->content];
+    }
+    NSTextField *textfield = nil;
+    if(args->input) {
+        NSRect frame = NSMakeRect(0,0,300,22);
+        textfield = args->password ? [[NSSecureTextField alloc] initWithFrame:frame] : [[NSTextField alloc]initWithFrame:frame];
+        if(args->input_value) {
+            textfield.stringValue = [[NSString alloc]initWithUTF8String:args->input_value];
+        }
+        dialog.accessoryView = textfield;
+    }
+    
+    int b = 0;
+    int b1 = -1;
+    int b2 = -1;
+    if(args->button1_label) {
+        [dialog addButtonWithTitle:[[NSString alloc]initWithUTF8String:args->button1_label]];
+        b1 = b++;
+    }
+    if(args->button2_label) {
+        [dialog addButtonWithTitle:[[NSString alloc]initWithUTF8String:args->button2_label]];
+        b2 = b;
+    }
+    if(args->closebutton_label) {
+        [dialog addButtonWithTitle:[[NSString alloc]initWithUTF8String:args->closebutton_label]];
+    }
+    
+    ui_callback callback = args->result;
+    void *userdata = args->resultdata;
+    
+    NSWindow *window = (__bridge NSWindow*)parent->wobj;
+    [dialog beginSheetModalForWindow:window completionHandler:^(NSModalResponse returnCode) {
+        UiEvent event;
+        event.obj = parent;
+        event.window = event.obj->window;
+        event.document = event.obj->ctx->document;
+        event.eventdata = NULL;
+        event.eventdatatype = 0;
+        event.set = 0;
+        event.intval = 0;
+        
+        long ret = returnCode - NSAlertFirstButtonReturn;
+        if(ret == b1) {
+            event.intval = 1;
+        } else if(ret == b2) {
+            event.intval = 2;
+        }
+        
+        NSString *value = nil;
+        if(textfield) {
+            value = textfield.stringValue;
+            event.eventdata = (void*)value.UTF8String;
+            event.eventdatatype = UI_EVENT_DATA_STRING;
+        }
+        
+        if(callback) {
+            callback(&event, userdata);
+        }
+    }];
+    
+}

mercurial