UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2017 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 #include <string.h> 32 33 #include "../ui/window.h" 34 #include "../ui/properties.h" 35 #include "../common/context.h" 36 37 #include "menu.h" 38 #include "toolbar.h" 39 #include "container.h" 40 41 static int nwindows = 0; 42 43 static int window_default_width = 650; 44 static int window_default_height = 550; 45 46 void ui_exit_event(GtkWidget *widget, gpointer data) { 47 UiObject *obj = data; 48 UiEvent ev; 49 ev.window = obj->window; 50 ev.document = obj->ctx->document; 51 ev.obj = obj; 52 ev.eventdata = NULL; 53 ev.intval = 0; 54 55 if(obj->ctx->close_callback) { 56 obj->ctx->close_callback(&ev, obj->ctx->close_data); 57 } 58 // TODO: free UiObject 59 60 nwindows--; 61 #ifdef UI_GTK2 62 if(nwindows == 0) { 63 gtk_main_quit(); 64 } 65 #endif 66 } 67 68 static UiObject* create_window(char *title, void *window_data, UiBool simple) { 69 UcxMempool *mp = ucx_mempool_new(256); 70 UiObject *obj = ucx_mempool_calloc(mp, 1, sizeof(UiObject)); 71 72 #ifndef UI_GTK2 73 obj->widget = gtk_application_window_new(ui_get_application()); 74 #else 75 obj->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); 76 #endif 77 78 79 obj->ctx = uic_context(obj, mp); 80 obj->window = window_data; 81 82 if(title != NULL) { 83 gtk_window_set_title(GTK_WINDOW(obj->widget), title); 84 } 85 86 char *width = ui_get_property("ui.window.width"); 87 char *height = ui_get_property("ui.window.height"); 88 if(width && height) { 89 gtk_window_set_default_size( 90 GTK_WINDOW(obj->widget), 91 atoi(width), 92 atoi(height)); 93 } else { 94 gtk_window_set_default_size( 95 GTK_WINDOW(obj->widget), 96 window_default_width, 97 window_default_height); 98 } 99 100 g_signal_connect( 101 obj->widget, 102 "destroy", 103 G_CALLBACK(ui_exit_event), 104 obj); 105 106 GtkWidget *vbox = ui_gtk_vbox_new(0); 107 gtk_container_add(GTK_CONTAINER(obj->widget), vbox); 108 109 if(!simple) { 110 // menu 111 GtkWidget *mb = ui_create_menubar(obj); 112 if(mb) { 113 gtk_box_pack_start(GTK_BOX(vbox), mb, FALSE, FALSE, 0); 114 } 115 116 // toolbar 117 GtkWidget *tb = ui_create_toolbar(obj); 118 if(tb) { 119 gtk_box_pack_start(GTK_BOX(vbox), tb, FALSE, FALSE, 0); 120 } 121 } 122 123 // window content 124 // the content has a (TODO: not yet) configurable frame 125 GtkWidget *frame = gtk_frame_new(NULL); 126 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); 127 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); 128 129 // content vbox 130 GtkWidget *content_box = ui_gtk_vbox_new(0); 131 gtk_container_add(GTK_CONTAINER(frame), content_box); 132 obj->container = ui_box_container(obj, content_box); 133 134 nwindows++; 135 return obj; 136 } 137 138 139 UiObject* ui_window(char *title, void *window_data) { 140 return create_window(title, window_data, FALSE); 141 } 142 143 UiObject* ui_simplewindow(char *title, void *window_data) { 144 return create_window(title, window_data, TRUE); 145 } 146 147 static char* ui_gtkfilechooser(UiObject *obj, GtkFileChooserAction action) { 148 char *button; 149 char *title; 150 151 if(action == GTK_FILE_CHOOSER_ACTION_OPEN) { 152 button = GTK_STOCK_OPEN; 153 title = "Datei öffnen..."; 154 } else { 155 button = GTK_STOCK_SAVE; 156 title = "Datei speichern..."; 157 } 158 159 GtkWidget *dialog = gtk_file_chooser_dialog_new( 160 title, 161 GTK_WINDOW(obj->widget), 162 action, 163 GTK_STOCK_CANCEL, 164 GTK_RESPONSE_CANCEL, 165 button, 166 GTK_RESPONSE_ACCEPT, 167 NULL); 168 if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { 169 char *file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); 170 gtk_widget_destroy(dialog); 171 char *copy = strdup(file); 172 g_free(file); 173 return copy; 174 } else { 175 gtk_widget_destroy(dialog); 176 return NULL; 177 } 178 } 179 180 char* ui_openfiledialog(UiObject *obj) { 181 return ui_gtkfilechooser(obj, GTK_FILE_CHOOSER_ACTION_OPEN); 182 } 183 184 char* ui_savefiledialog(UiObject *obj) { 185 return ui_gtkfilechooser(obj, GTK_FILE_CHOOSER_ACTION_SAVE); 186 } 187 188