ui/motif/window.c

changeset 0
804d8803eade
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/motif/window.c	Wed Dec 09 11:32:01 2020 +0100
@@ -0,0 +1,208 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2014 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "toolkit.h"
+#include "menu.h"
+#include "toolbar.h"
+#include "container.h"
+#include "../ui/window.h"
+#include "../common/context.h"
+
+static int nwindows = 0;
+
+static int window_default_width = 600;
+static int window_default_height = 500;
+
+static void window_close_handler(Widget window, void *udata, void *cdata) {
+    UiObject *obj = udata;
+    UiEvent ev;
+    ev.window = obj->window;
+    ev.document = obj->ctx->document;
+    ev.obj = obj;
+    ev.eventdata = NULL;
+    ev.intval = 0;
+    
+    if(obj->ctx->close_callback) {
+        obj->ctx->close_callback(&ev, obj->ctx->close_data);
+    }
+    // TODO: free UiObject
+    
+    nwindows--;
+    if(nwindows == 0) {
+        ui_exit_mainloop();
+    }
+}
+
+static UiObject* create_window(char *title, void *window_data, UiBool simple) {
+    UcxMempool *mp = ucx_mempool_new(256);
+    UiObject *obj = ucx_mempool_calloc(mp, 1, sizeof(UiObject));
+    obj->ctx = uic_context(obj, mp);
+    obj->window = window_data;
+    
+    Arg args[16];
+    int n = 0;
+    
+    XtSetArg(args[0], XmNtitle, title);
+    //XtSetArg(args[1], XmNbaseWidth, window_default_width);
+    //XtSetArg(args[2], XmNbaseHeight, window_default_height);
+    XtSetArg(args[1], XmNminWidth, 100);
+    XtSetArg(args[2], XmNminHeight, 50);
+    XtSetArg(args[3], XmNwidth, window_default_width);
+    XtSetArg(args[4], XmNheight, window_default_height);
+    
+    Widget toplevel = XtAppCreateShell(
+            "Test123",
+            "abc",
+            //applicationShellWidgetClass,
+            vendorShellWidgetClass,
+            ui_get_display(),
+            args,
+            5);
+    
+    Atom wm_delete_window;
+    wm_delete_window = XmInternAtom(
+            XtDisplay(toplevel),
+            "WM_DELETE_WINDOW",
+            0);
+    XmAddWMProtocolCallback(
+            toplevel,
+            wm_delete_window,
+            window_close_handler,
+            obj);
+    
+    // TODO: use callback
+    ui_set_active_window(toplevel);
+    
+    Widget window = XtVaCreateManagedWidget(
+            title,
+            xmMainWindowWidgetClass,
+            toplevel,
+            NULL);
+    obj->widget = window;
+    Widget form = XtVaCreateManagedWidget(
+            "window_form",
+            xmFormWidgetClass,
+            window,
+            NULL);
+    Widget toolbar = NULL;
+    
+    if(!simple) {
+        ui_create_menubar(obj);
+        toolbar = ui_create_toolbar(obj, form);
+    }
+    
+    // window content
+    XtSetArg(args[0], XmNshadowType, XmSHADOW_ETCHED_OUT);
+    XtSetArg(args[1], XmNshadowThickness, 0);
+    XtSetArg(args[2], XmNleftAttachment, XmATTACH_FORM);
+    XtSetArg(args[3], XmNrightAttachment, XmATTACH_FORM);
+    XtSetArg(args[4], XmNbottomAttachment, XmATTACH_FORM);
+    if(toolbar) {
+        XtSetArg(args[5], XmNtopAttachment, XmATTACH_WIDGET);
+        XtSetArg(args[6], XmNtopWidget, toolbar);
+        n = 7;
+    } else {
+        XtSetArg(args[5], XmNtopAttachment, XmATTACH_FORM);
+        n = 6;
+    }
+    Widget frame = XmCreateFrame(form, "content_frame", args, n);
+    XtManageChild(frame);
+    
+    Widget content_form = XmCreateForm(frame, "content_form", NULL, 0);
+    XtManageChild(content_form);
+    obj->container = ui_box_container(obj, content_form, 0, 0, UI_BOX_VERTICAL);
+    
+    XtManageChild(form);
+      
+    obj->widget = toplevel;
+    nwindows++;
+    return obj;
+}
+
+UiObject* ui_window(char *title, void *window_data) {
+    return create_window(title, window_data, FALSE);
+}
+
+UiObject* ui_simplewindow(char *title, void *window_data) {
+    return create_window(title, window_data, TRUE);
+}
+
+void ui_close(UiObject *obj) {
+    XtDestroyWidget(obj->widget);
+    window_close_handler(obj->widget, obj, NULL);
+}
+
+typedef struct FileDialogData {
+    int  running;
+    char *file;
+} FileDialogData;
+
+static void filedialog_select(
+        Widget widget,
+        FileDialogData *data,
+        XmFileSelectionBoxCallbackStruct *selection)
+{
+    char *path = NULL;
+    XmStringGetLtoR(selection->value, XmSTRING_DEFAULT_CHARSET, &path);
+    data->running = 0;
+    data->file = strdup(path);
+    XtFree(path);
+    XtUnmanageChild(widget);
+}
+
+static void filedialog_cancel(
+        Widget widget,
+        FileDialogData *data,
+        XmFileSelectionBoxCallbackStruct *selection)
+
+{
+    data->running = 0;
+    XtUnmanageChild(widget);
+}
+
+char* ui_openfiledialog(UiObject *obj) {
+    Widget dialog = XmCreateFileSelectionDialog(obj->widget, "openfiledialog", NULL, 0);
+    XtManageChild(dialog);
+    
+    FileDialogData data;
+    data.running = 1;
+    data.file = NULL;
+    
+    XtAddCallback(dialog, XmNokCallback, (XtCallbackProc)filedialog_select, &data);
+    XtAddCallback(dialog, XmNcancelCallback, (XtCallbackProc)filedialog_cancel, &data);
+    
+    ui_secondary_event_loop(&data.running);
+    return data.file;
+}
+
+char* ui_savefiledialog(UiObject *obj) {
+    return ui_openfiledialog(obj);
+}

mercurial