update uwproj
[mizunara.git] / ui / motif / window.c
1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3  *
4  * Copyright 2014 Olaf Wintermann. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *   1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above copyright
13  *      notice, this list of conditions and the following disclaimer in the
14  *      documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "toolkit.h"
33 #include "menu.h"
34 #include "toolbar.h"
35 #include "container.h"
36 #include "../ui/window.h"
37 #include "../common/context.h"
38
39 static int nwindows = 0;
40
41 static int window_default_width = 600;
42 static int window_default_height = 500;
43
44 static void window_close_handler(Widget window, void *udata, void *cdata) {
45     UiObject *obj = udata;
46     UiEvent ev;
47     ev.window = obj->window;
48     ev.document = obj->ctx->document;
49     ev.obj = obj;
50     ev.eventdata = NULL;
51     ev.intval = 0;
52     
53     if(obj->ctx->close_callback) {
54         obj->ctx->close_callback(&ev, obj->ctx->close_data);
55     }
56     // TODO: free UiObject
57     
58     nwindows--;
59     if(nwindows == 0) {
60         ui_exit_mainloop();
61     }
62 }
63
64 static UiObject* create_window(char *title, void *window_data, UiBool simple) {
65     UcxMempool *mp = ucx_mempool_new(256);
66     UiObject *obj = ucx_mempool_calloc(mp, 1, sizeof(UiObject));
67     obj->ctx = uic_context(obj, mp);
68     obj->window = window_data;
69     
70     Arg args[16];
71     int n = 0;
72     
73     XtSetArg(args[0], XmNtitle, title);
74     //XtSetArg(args[1], XmNbaseWidth, window_default_width);
75     //XtSetArg(args[2], XmNbaseHeight, window_default_height);
76     XtSetArg(args[1], XmNminWidth, 100);
77     XtSetArg(args[2], XmNminHeight, 50);
78     XtSetArg(args[3], XmNwidth, window_default_width);
79     XtSetArg(args[4], XmNheight, window_default_height);
80     
81     Widget toplevel = XtAppCreateShell(
82             "Test123",
83             "abc",
84             //applicationShellWidgetClass,
85             vendorShellWidgetClass,
86             ui_get_display(),
87             args,
88             5);
89     
90     Atom wm_delete_window;
91     wm_delete_window = XmInternAtom(
92             XtDisplay(toplevel),
93             "WM_DELETE_WINDOW",
94             0);
95     XmAddWMProtocolCallback(
96             toplevel,
97             wm_delete_window,
98             window_close_handler,
99             obj);
100     
101     // TODO: use callback
102     ui_set_active_window(toplevel);
103     
104     Widget window = XtVaCreateManagedWidget(
105             title,
106             xmMainWindowWidgetClass,
107             toplevel,
108             NULL);
109     obj->widget = window;
110     Widget form = XtVaCreateManagedWidget(
111             "window_form",
112             xmFormWidgetClass,
113             window,
114             NULL);
115     Widget toolbar = NULL;
116     
117     if(!simple) {
118         ui_create_menubar(obj);
119         toolbar = ui_create_toolbar(obj, form);
120     }
121     
122     // window content
123     XtSetArg(args[0], XmNshadowType, XmSHADOW_ETCHED_OUT);
124     XtSetArg(args[1], XmNshadowThickness, 0);
125     XtSetArg(args[2], XmNleftAttachment, XmATTACH_FORM);
126     XtSetArg(args[3], XmNrightAttachment, XmATTACH_FORM);
127     XtSetArg(args[4], XmNbottomAttachment, XmATTACH_FORM);
128     if(toolbar) {
129         XtSetArg(args[5], XmNtopAttachment, XmATTACH_WIDGET);
130         XtSetArg(args[6], XmNtopWidget, toolbar);
131         n = 7;
132     } else {
133         XtSetArg(args[5], XmNtopAttachment, XmATTACH_FORM);
134         n = 6;
135     }
136     Widget frame = XmCreateFrame(form, "content_frame", args, n);
137     XtManageChild(frame);
138     
139     Widget content_form = XmCreateForm(frame, "content_form", NULL, 0);
140     XtManageChild(content_form);
141     obj->container = ui_box_container(obj, content_form, 0, 0, UI_BOX_VERTICAL);
142     
143     XtManageChild(form);
144       
145     obj->widget = toplevel;
146     nwindows++;
147     return obj;
148 }
149
150 UiObject* ui_window(char *title, void *window_data) {
151     return create_window(title, window_data, FALSE);
152 }
153
154 UiObject* ui_simplewindow(char *title, void *window_data) {
155     return create_window(title, window_data, TRUE);
156 }
157
158 void ui_close(UiObject *obj) {
159     XtDestroyWidget(obj->widget);
160     window_close_handler(obj->widget, obj, NULL);
161 }
162
163 typedef struct FileDialogData {
164     int  running;
165     char *file;
166 } FileDialogData;
167
168 static void filedialog_select(
169         Widget widget,
170         FileDialogData *data,
171         XmFileSelectionBoxCallbackStruct *selection)
172 {
173     char *path = NULL;
174     XmStringGetLtoR(selection->value, XmSTRING_DEFAULT_CHARSET, &path);
175     data->running = 0;
176     data->file = strdup(path);
177     XtFree(path);
178     XtUnmanageChild(widget);
179 }
180
181 static void filedialog_cancel(
182         Widget widget,
183         FileDialogData *data,
184         XmFileSelectionBoxCallbackStruct *selection)
185
186 {
187     data->running = 0;
188     XtUnmanageChild(widget);
189 }
190
191 char* ui_openfiledialog(UiObject *obj) {
192     Widget dialog = XmCreateFileSelectionDialog(obj->widget, "openfiledialog", NULL, 0);
193     XtManageChild(dialog);
194     
195     FileDialogData data;
196     data.running = 1;
197     data.file = NULL;
198     
199     XtAddCallback(dialog, XmNokCallback, (XtCallbackProc)filedialog_select, &data);
200     XtAddCallback(dialog, XmNcancelCallback, (XtCallbackProc)filedialog_cancel, &data);
201     
202     ui_secondary_event_loop(&data.running);
203     return data.file;
204 }
205
206 char* ui_savefiledialog(UiObject *obj) {
207     return ui_openfiledialog(obj);
208 }