| 40 #include "../common/toolbar.h" |
40 #include "../common/toolbar.h" |
| 41 |
41 |
| 42 #include <cx/mempool.h> |
42 #include <cx/mempool.h> |
| 43 |
43 |
| 44 |
44 |
| 45 static UiObject* create_window(const char *title, BOOL simple) { |
45 static UiObject* create_window(const char *title, BOOL simple, BOOL sidebar) { |
| 46 CxMempool *mp = cxMempoolCreateSimple(256); |
46 CxMempool *mp = cxMempoolCreateSimple(256); |
| 47 UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); |
47 UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); |
| 48 obj->ref = 0; |
48 obj->ref = 0; |
| 49 |
49 |
| 50 obj->ctx = uic_context(obj, mp); |
50 obj->ctx = uic_context(obj, mp); |
| 51 |
51 |
| 52 MainWindow *window = [[MainWindow alloc] init:obj]; |
52 MainWindow *window = [[MainWindow alloc] init:obj withSidebar:sidebar]; |
| 53 [[WindowManager sharedWindowManager] addWindow:window]; |
53 [[WindowManager sharedWindowManager] addWindow:window]; |
| 54 window.releasedWhenClosed = false; |
54 window.releasedWhenClosed = false; |
| 55 |
55 |
| 56 obj->wobj = (__bridge void*)window; |
56 obj->wobj = (__bridge void*)window; |
| 57 |
57 |
| 62 |
62 |
| 63 return obj; |
63 return obj; |
| 64 } |
64 } |
| 65 |
65 |
| 66 UiObject* ui_window(const char *title, void *window_data) { |
66 UiObject* ui_window(const char *title, void *window_data) { |
| 67 UiObject *obj = create_window(title, FALSE); |
67 UiObject *obj = create_window(title, FALSE, FALSE); |
| 68 obj->window = window_data; |
68 obj->window = window_data; |
| 69 return obj; |
69 return obj; |
| 70 } |
70 } |
| 71 |
71 |
| 72 UiObject* ui_simple_window(const char *title, void *window_data) { |
72 UiObject* ui_simple_window(const char *title, void *window_data) { |
| 73 UiObject *obj = create_window(title, TRUE); |
73 UiObject *obj = create_window(title, TRUE, FALSE); |
| 74 obj->window = window_data; |
74 obj->window = window_data; |
| 75 return obj; |
75 return obj; |
| 76 } |
76 } |
| |
77 |
| |
78 UiObject* ui_sidebar_window(const char *title, void *window_data) { |
| |
79 UiObject *obj = create_window(title, FALSE, TRUE); |
| |
80 obj->window = window_data; |
| |
81 return obj; |
| |
82 } |
| |
83 |
| |
84 /* --------------------------------- File Dialogs --------------------------------- */ |
| |
85 |
| |
86 void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { |
| |
87 NSOpenPanel *openPanel = [NSOpenPanel openPanel]; |
| |
88 if((mode & UI_FILEDIALOG_SELECT_MULTI) == UI_FILEDIALOG_SELECT_MULTI) { |
| |
89 openPanel.allowsMultipleSelection = YES; |
| |
90 } |
| |
91 if((mode & UI_FILEDIALOG_SELECT_FOLDER) == UI_FILEDIALOG_SELECT_FOLDER) { |
| |
92 openPanel.canChooseFiles = NO; |
| |
93 openPanel.canChooseDirectories = YES; |
| |
94 } |
| |
95 |
| |
96 NSWindow *window = (__bridge NSWindow*)obj->wobj; |
| |
97 [openPanel beginSheetModalForWindow:window completionHandler:^(NSModalResponse result) { |
| |
98 UiEvent event; |
| |
99 event.obj = obj; |
| |
100 event.window = obj->window; |
| |
101 event.document = obj->ctx->document; |
| |
102 event.intval = 0; |
| |
103 event.set = 0; |
| |
104 |
| |
105 UiFileList flist = { NULL, 0 }; |
| |
106 event.eventdata = &flist; |
| |
107 event.eventdatatype = UI_EVENT_DATA_FILE_LIST; |
| |
108 |
| |
109 if(result == NSModalResponseOK) { |
| |
110 NSArray<NSURL *> *urls = [openPanel URLs]; |
| |
111 flist.files = calloc(urls.count, sizeof(char*)); |
| |
112 for(NSURL *url in urls) { |
| |
113 if([url isFileURL]) { |
| |
114 flist.files[flist.nfiles++] = strdup(url.path.UTF8String); |
| |
115 } |
| |
116 } |
| |
117 } |
| |
118 |
| |
119 if(file_selected_callback) { |
| |
120 file_selected_callback(&event, cbdata); |
| |
121 } |
| |
122 ui_filelist_free(flist); |
| |
123 }]; |
| |
124 } |
| |
125 |
| |
126 void ui_savefiledialog(UiObject *obj, const char *name, ui_callback file_selected_callback, void *cbdata) { |
| |
127 NSSavePanel *savePanel = [NSSavePanel savePanel]; |
| |
128 if(name) { |
| |
129 NSString *nameStr = [[NSString alloc] initWithUTF8String:name]; |
| |
130 [savePanel setNameFieldStringValue: nameStr]; |
| |
131 } |
| |
132 |
| |
133 NSWindow *window = (__bridge NSWindow*)obj->wobj; |
| |
134 [savePanel beginSheetModalForWindow:window completionHandler:^(NSModalResponse result) { |
| |
135 UiEvent event; |
| |
136 event.obj = obj; |
| |
137 event.window = obj->window; |
| |
138 event.document = obj->ctx->document; |
| |
139 event.intval = 0; |
| |
140 event.set = 0; |
| |
141 |
| |
142 UiFileList flist = { NULL, 0 }; |
| |
143 event.eventdata = &flist; |
| |
144 event.eventdatatype = UI_EVENT_DATA_FILE_LIST; |
| |
145 |
| |
146 if(result == NSModalResponseOK) { |
| |
147 NSURL *url = [savePanel URL]; |
| |
148 if([url isFileURL]) { |
| |
149 NSString *path = url.path; |
| |
150 flist.files = malloc(sizeof(char*)); |
| |
151 flist.files[0] = strdup(path.UTF8String); |
| |
152 flist.nfiles = 1; |
| |
153 } |
| |
154 file_selected_callback(NULL, NULL); |
| |
155 } |
| |
156 if(file_selected_callback) { |
| |
157 file_selected_callback(&event, cbdata); |
| |
158 } |
| |
159 ui_filelist_free(flist); |
| |
160 }]; |
| |
161 } |
| |
162 |
| |
163 /* ------------------------------------- Dialog ------------------------------------- */ |
| |
164 |
| |
165 void ui_dialog_create(UiObject *parent, UiDialogArgs *args) { |
| |
166 NSAlert *dialog = [[NSAlert alloc] init]; |
| |
167 |
| |
168 if(args->title) { |
| |
169 dialog.messageText = [[NSString alloc]initWithUTF8String:args->title]; |
| |
170 } |
| |
171 if(args->content) { |
| |
172 dialog.informativeText = [[NSString alloc]initWithUTF8String:args->content]; |
| |
173 } |
| |
174 NSTextField *textfield = nil; |
| |
175 if(args->input) { |
| |
176 NSRect frame = NSMakeRect(0,0,300,22); |
| |
177 textfield = args->password ? [[NSSecureTextField alloc] initWithFrame:frame] : [[NSTextField alloc]initWithFrame:frame]; |
| |
178 if(args->input_value) { |
| |
179 textfield.stringValue = [[NSString alloc]initWithUTF8String:args->input_value]; |
| |
180 } |
| |
181 dialog.accessoryView = textfield; |
| |
182 } |
| |
183 |
| |
184 int b = 0; |
| |
185 int b1 = -1; |
| |
186 int b2 = -1; |
| |
187 if(args->button1_label) { |
| |
188 [dialog addButtonWithTitle:[[NSString alloc]initWithUTF8String:args->button1_label]]; |
| |
189 b1 = b++; |
| |
190 } |
| |
191 if(args->button2_label) { |
| |
192 [dialog addButtonWithTitle:[[NSString alloc]initWithUTF8String:args->button2_label]]; |
| |
193 b2 = b; |
| |
194 } |
| |
195 if(args->closebutton_label) { |
| |
196 [dialog addButtonWithTitle:[[NSString alloc]initWithUTF8String:args->closebutton_label]]; |
| |
197 } |
| |
198 |
| |
199 ui_callback callback = args->result; |
| |
200 void *userdata = args->resultdata; |
| |
201 |
| |
202 NSWindow *window = (__bridge NSWindow*)parent->wobj; |
| |
203 [dialog beginSheetModalForWindow:window completionHandler:^(NSModalResponse returnCode) { |
| |
204 UiEvent event; |
| |
205 event.obj = parent; |
| |
206 event.window = event.obj->window; |
| |
207 event.document = event.obj->ctx->document; |
| |
208 event.eventdata = NULL; |
| |
209 event.eventdatatype = 0; |
| |
210 event.set = 0; |
| |
211 event.intval = 0; |
| |
212 |
| |
213 long ret = returnCode - NSAlertFirstButtonReturn; |
| |
214 if(ret == b1) { |
| |
215 event.intval = 1; |
| |
216 } else if(ret == b2) { |
| |
217 event.intval = 2; |
| |
218 } |
| |
219 |
| |
220 NSString *value = nil; |
| |
221 if(textfield) { |
| |
222 value = textfield.stringValue; |
| |
223 event.eventdata = (void*)value.UTF8String; |
| |
224 event.eventdatatype = UI_EVENT_DATA_STRING; |
| |
225 } |
| |
226 |
| |
227 if(callback) { |
| |
228 callback(&event, userdata); |
| |
229 } |
| |
230 }]; |
| |
231 |
| |
232 } |