| 65 ui_window_widget_destroy(obj); |
72 ui_window_widget_destroy(obj); |
| 66 } |
73 } |
| 67 } |
74 } |
| 68 |
75 |
| 69 |
76 |
| 70 static UiObject* create_window(const char *title, void *window_data, Boolean simple) { |
77 static UiObject* create_window(const char *title, Boolean simple) { |
| 71 CxMempool *mp = cxMempoolCreateSimple(256); |
78 CxMempool *mp = cxMempoolCreateSimple(256); |
| 72 const CxAllocator *a = mp->allocator; |
79 const CxAllocator *a = mp->allocator; |
| 73 UiObject *obj = uic_object_new_toplevel(); |
80 UiObject *obj = uic_object_new_toplevel(); |
| 74 obj->window = window_data; |
|
| 75 obj->destroy = ui_window_widget_destroy; |
81 obj->destroy = ui_window_widget_destroy; |
| |
82 |
| |
83 int window_width = window_default_width; |
| |
84 int window_height = window_default_height; |
| |
85 if(!simple) { |
| |
86 ui_get_window_default_width(&window_width, &window_height); |
| |
87 } |
| |
88 |
| |
89 UiMotifAppWindow *appwindow = cxZalloc(a, sizeof(UiMotifAppWindow)); |
| |
90 ui_object_set(obj, "ui_motif_app_window", appwindow); |
| 76 |
91 |
| 77 Arg args[16]; |
92 Arg args[16]; |
| 78 int n = 0; |
93 int n = 0; |
| 79 XtSetArg(args[n], XmNtitle, title); n++; |
94 XtSetArg(args[n], XmNtitle, title); n++; |
| 80 XtSetArg(args[n], XmNminWidth, 100); n++; |
95 XtSetArg(args[n], XmNminWidth, 100); n++; |
| 81 XtSetArg(args[n], XmNminHeight, 50); n++; |
96 XtSetArg(args[n], XmNminHeight, 50); n++; |
| 82 XtSetArg(args[n], XmNwidth, window_default_width); n++; |
97 XtSetArg(args[n], XmNwidth, window_width); n++; |
| 83 XtSetArg(args[n], XmNheight, window_default_height); n++; |
98 XtSetArg(args[n], XmNheight, window_height); n++; |
| 84 |
99 |
| 85 Widget toplevel = XtAppCreateShell( |
100 Widget toplevel = XtAppCreateShell( |
| 86 ui_appname(), |
101 ui_appname(), |
| 87 "mainwindow", |
102 "mainwindow", |
| 88 //applicationShellWidgetClass, |
103 //applicationShellWidgetClass, |
| 133 obj->widget = toplevel; |
148 obj->widget = toplevel; |
| 134 nwindows++; |
149 nwindows++; |
| 135 return obj; |
150 return obj; |
| 136 } |
151 } |
| 137 |
152 |
| 138 UiObject* ui_window(const char *title, void *window_data) { |
153 UiObject* ui_window(const char *title) { |
| 139 return create_window(title, window_data, FALSE); |
154 return create_window(title, FALSE); |
| 140 } |
155 } |
| 141 |
156 |
| 142 UiObject* ui_simple_window(const char *title, void *window_data) { |
157 UiObject* ui_simple_window(const char *title) { |
| 143 return create_window(title, window_data, TRUE); |
158 return create_window(title, TRUE); |
| 144 } |
159 } |
| |
160 |
| |
161 void ui_window_size(UiObject *obj, int width, int height) { |
| |
162 XtVaSetValues(obj->widget, XmNwidth, width, XmNheight, height, NULL); |
| |
163 } |
| |
164 |
| |
165 void ui_window_default_size(int width, int height) { |
| |
166 window_default_width = width; |
| |
167 window_default_height = height; |
| |
168 } |
| |
169 |
| |
170 void ui_window_menubar_set_visible(UiObject *obj, UiBool visible) { |
| |
171 UiMotifAppWindow *window = ui_object_get(obj, "ui_motif_app_window"); |
| |
172 if(window) { |
| |
173 if(window->menubar) { |
| |
174 ui_set_visible(window->menubar, visible); |
| |
175 } |
| |
176 } else { |
| |
177 fprintf(stderr, "Error: obj is not an application window\n"); |
| |
178 } |
| |
179 } |
| |
180 |
| |
181 static Atom net_wm_state; |
| |
182 static Atom net_wm_state_fullscreen; |
| |
183 static int net_wm_atoms_initialized = 0; |
| |
184 |
| |
185 void ui_window_fullscreen(UiObject *obj, UiBool fullscreen) { |
| |
186 Display *dpy = XtDisplay(obj->widget); |
| |
187 |
| |
188 // init net_wm_state atoms |
| |
189 if(!net_wm_atoms_initialized) { |
| |
190 net_wm_state = XInternAtom(dpy, "_NET_WM_STATE", False); |
| |
191 net_wm_state_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); |
| |
192 net_wm_atoms_initialized = 1; |
| |
193 } |
| |
194 |
| |
195 XEvent ev; |
| |
196 memset(&ev, 0, sizeof(XEvent)); |
| |
197 ev.type = ClientMessage; |
| |
198 ev.xclient.window = XtWindow(obj->widget); |
| |
199 ev.xclient.message_type = net_wm_state; |
| |
200 ev.xclient.format = 32; |
| |
201 ev.xclient.data.l[0] = fullscreen ? 1 : 0; |
| |
202 ev.xclient.data.l[1] = net_wm_state_fullscreen; |
| |
203 ev.xclient.data.l[2] = 0; |
| |
204 XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask | SubstructureRedirectMask, &ev); |
| |
205 } |
| |
206 |
| |
207 static void filedialog_event(UiEventData *event, int result, UiFileList flist) { |
| |
208 UiEvent evt; |
| |
209 evt.obj = event->obj; |
| |
210 evt.document = evt.obj->ctx->document; |
| |
211 evt.window = evt.obj->window; |
| |
212 evt.intval = result; |
| |
213 |
| |
214 evt.eventdata = &flist; |
| |
215 evt.eventdatatype = UI_EVENT_DATA_FILE_LIST; |
| |
216 |
| |
217 if(event->callback) { |
| |
218 event->callback(&evt, event->userdata); |
| |
219 } |
| |
220 } |
| |
221 |
| |
222 static void filedialog_select( |
| |
223 Widget widget, |
| |
224 UiEventData *data, |
| |
225 XmFileSelectionBoxCallbackStruct *selection) |
| |
226 { |
| |
227 UiFileList flist; |
| |
228 |
| |
229 char *value = NULL; |
| |
230 XmStringGetLtoR(selection->value, XmSTRING_DEFAULT_CHARSET, &value); |
| |
231 flist.files = &value; |
| |
232 flist.nfiles = 1; |
| |
233 |
| |
234 filedialog_event(data, 1, flist); |
| |
235 |
| |
236 XtFree(value); |
| |
237 |
| |
238 XtUnmanageChild(widget); |
| |
239 XtDestroyWidget(widget); |
| |
240 } |
| |
241 |
| |
242 static void filedialog_cancel( |
| |
243 Widget widget, |
| |
244 UiEventData *data, |
| |
245 XmFileSelectionBoxCallbackStruct *selection) |
| |
246 { |
| |
247 UiFileList flist; |
| |
248 flist.files = NULL; |
| |
249 flist.nfiles = 0; |
| |
250 filedialog_event(data, 0, flist); |
| |
251 |
| |
252 XtUnmanageChild(widget); |
| |
253 XtDestroyWidget(widget); |
| |
254 } |
| |
255 |
| |
256 void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { |
| |
257 Widget dialog = XnCreateFileSelectionDialog(obj->widget, "dialog", NULL, 0); |
| |
258 |
| |
259 UiEventData *data = malloc(sizeof(UiEventData)); |
| |
260 memset(data, 0, sizeof(UiEventData)); |
| |
261 data->obj = obj; |
| |
262 data->callback = file_selected_callback; |
| |
263 data->userdata = cbdata; |
| |
264 |
| |
265 XtAddCallback(dialog, XmNokCallback, (XtCallbackProc)filedialog_select, data); |
| |
266 XtAddCallback(dialog, XmNcancelCallback, (XtCallbackProc)filedialog_cancel, data); |
| |
267 //XtAddCallback(dialog, XmNhelpCallback, (XtCallbackProc)filedialog_help, wd); |
| |
268 |
| |
269 XtManageChild(dialog); |
| |
270 } |
| |
271 |
| |
272 void ui_savefiledialog(UiObject *obj, const char *name, ui_callback file_selected_callback, void *cbdata) { |
| |
273 Arg args[16]; |
| |
274 int n = 0; |
| |
275 |
| |
276 // Save File Dialog needs this parameter |
| |
277 XtSetArg(args[n], XnNfsbType, FILEDIALOG_SAVE); n++; |
| |
278 char *selectedpath = (char*)name; |
| |
279 if(name) { |
| |
280 if(name[0] != '/') { |
| |
281 char cwd[PATH_MAX]; |
| |
282 if(getcwd(cwd, PATH_MAX)) { |
| |
283 pathbar_concat_path(cwd, name); |
| |
284 } else { |
| |
285 fprintf(stderr, "Error: getcwd failed: %s\n", strerror(errno)); |
| |
286 selectedpath = NULL; |
| |
287 } |
| |
288 } |
| |
289 if(selectedpath) { |
| |
290 XtSetArg(args[n], XnNselectedPath, selectedpath); n++; |
| |
291 } |
| |
292 } |
| |
293 Widget dialog = XnCreateFileSelectionDialog(obj->widget, "dialog", args, n); |
| |
294 |
| |
295 UiEventData *data = malloc(sizeof(UiEventData)); |
| |
296 memset(data, 0, sizeof(UiEventData)); |
| |
297 data->obj = obj; |
| |
298 data->callback = file_selected_callback; |
| |
299 data->userdata = cbdata; |
| |
300 |
| |
301 XtAddCallback(dialog, XmNokCallback, (XtCallbackProc)filedialog_select, data); |
| |
302 XtAddCallback(dialog, XmNcancelCallback, (XtCallbackProc)filedialog_cancel, data); |
| |
303 //XtAddCallback(dialog, XmNhelpCallback, (XtCallbackProc)filedialog_help, wd); |
| |
304 |
| |
305 XtManageChild(dialog); |
| |
306 |
| |
307 if(selectedpath != name) { |
| |
308 free(selectedpath); |
| |
309 } |
| |
310 } |