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 32 #include "button.h" 33 #include "container.h" 34 #include <ucx/mempool.h> 35 #include "../common/context.h" 36 #include "../common/object.h" 37 38 UIWIDGET ui_button(UiObject *obj, char *label, ui_callback f, void *data) { 39 GtkWidget *button = gtk_button_new_with_label(label); 40 41 if(f) { 42 UiEventData *event = malloc(sizeof(UiEventData)); 43 event->obj = obj; 44 event->userdata = data; 45 event->callback = f; 46 event->value = 0; 47 48 g_signal_connect( 49 button, 50 "clicked", 51 G_CALLBACK(ui_button_clicked), 52 event); 53 g_signal_connect( 54 button, 55 "destroy", 56 G_CALLBACK(ui_destroy_userdata), 57 event); 58 } 59 60 UiContainer *ct = uic_get_current_container(obj); 61 ct->add(ct, button, FALSE); 62 63 return button; 64 } 65 66 67 void ui_button_clicked(GtkWidget *widget, UiEventData *event) { 68 UiEvent e; 69 e.obj = event->obj; 70 e.window = event->obj->window; 71 e.document = event->obj->ctx->document; 72 e.eventdata = NULL; 73 e.intval = event->value; 74 event->callback(&e, event->userdata); 75 } 76 77 int64_t ui_toggle_button_get(UiInteger *integer) { 78 GtkToggleButton *button = integer->obj; 79 integer->value = (int)gtk_toggle_button_get_active(button); 80 return integer->value; 81 } 82 83 void ui_toggle_button_set(UiInteger *integer, int64_t value) { 84 GtkToggleButton *button = integer->obj; 85 integer->value = value; 86 gtk_toggle_button_set_active(button, value != 0 ? TRUE : FALSE); 87 } 88 89 void ui_toggled_obs(GtkToggleToolButton *widget, UiVarEventData *event) { 90 UiEvent e; 91 e.obj = event->obj; 92 e.window = event->obj->window; 93 e.document = event->obj->ctx->document; 94 e.eventdata = event->var->value; 95 e.intval = gtk_toggle_tool_button_get_active(widget); 96 97 UiInteger *i = event->var->value; 98 ui_notify_evt(i->observers, &e); 99 } 100 101 UIWIDGET ui_checkbox_var(UiObject *obj, char *label, UiVar *var) { 102 GtkWidget *button = gtk_check_button_new_with_label(label); 103 104 // bind value 105 if(var) { 106 UiInteger *value = var->value; 107 value->obj = GTK_TOGGLE_BUTTON(button); 108 value->get = ui_toggle_button_get; 109 value->set = ui_toggle_button_set; 110 gtk_toggle_button_set_active(value->obj, value->value); 111 112 UiVarEventData *event = malloc(sizeof(UiVarEventData)); 113 event->obj = obj; 114 event->var = var; 115 event->observers = NULL; 116 117 g_signal_connect( 118 button, 119 "clicked", 120 G_CALLBACK(ui_toggled_obs), 121 event); 122 g_signal_connect( 123 button, 124 "destroy", 125 G_CALLBACK(ui_destroy_vardata), 126 event); 127 } 128 129 UiContainer *ct = uic_get_current_container(obj); 130 ct->add(ct, button, FALSE); 131 132 return button; 133 } 134 135 UIWIDGET ui_checkbox(UiObject *obj, char *label, UiInteger *value) { 136 UiVar *var = NULL; 137 if(value) { 138 var = malloc(sizeof(UiVar)); 139 var->value = value; 140 var->type = UI_VAR_SPECIAL; 141 } 142 return ui_checkbox_var(obj, label, var); 143 } 144 145 UIWIDGET ui_checkbox_nv(UiObject *obj, char *label, char *varname) { 146 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_INTEGER); 147 return ui_checkbox_var(obj, label, var); 148 } 149 150 151 UIWIDGET ui_radiobutton_var(UiObject *obj, char *label, UiVar *var) { 152 GSList *rg = NULL; 153 UiInteger *rgroup; 154 155 if(var) { 156 rgroup = var->value; 157 rg = rgroup->obj; 158 } 159 160 GtkWidget *rbutton = gtk_radio_button_new_with_label(rg, label); 161 rg = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbutton)); 162 163 if(rgroup) { 164 rgroup->obj = rg; 165 rgroup->get = ui_radiobutton_get; 166 rgroup->set = ui_radiobutton_set; 167 168 ui_radiobutton_set(rgroup, rgroup->value); 169 170 UiVarEventData *event = malloc(sizeof(UiVarEventData)); 171 event->obj = obj; 172 event->var = var; 173 event->observers = NULL; 174 175 g_signal_connect( 176 rbutton, 177 "clicked", 178 G_CALLBACK(ui_radio_obs), 179 event); 180 g_signal_connect( 181 rbutton, 182 "destroy", 183 G_CALLBACK(ui_destroy_vardata), 184 event); 185 } 186 187 UiContainer *ct = uic_get_current_container(obj); 188 ct->add(ct, rbutton, FALSE); 189 190 return rbutton; 191 } 192 193 UIWIDGET ui_radiobutton(UiObject *obj, char *label, UiInteger *rgroup) { 194 UiVar *var = NULL; 195 if(rgroup) { 196 var = malloc(sizeof(UiVar)); 197 var->value = rgroup; 198 var->type = UI_VAR_SPECIAL; 199 } 200 return ui_radiobutton_var(obj, label, var); 201 } 202 203 UIWIDGET ui_radiobutton_nv(UiObject *obj, char *label, char *varname) { 204 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_INTEGER); 205 return ui_radiobutton_var(obj, label, var); 206 } 207 208 void ui_radio_obs(GtkToggleToolButton *widget, UiVarEventData *event) { 209 UiInteger *i = event->var->value; 210 211 UiEvent e; 212 e.obj = event->obj; 213 e.window = event->obj->window; 214 e.document = event->obj->ctx->document; 215 e.eventdata = NULL; 216 e.intval = i->get(i); 217 218 ui_notify_evt(i->observers, &e); 219 } 220 221 int64_t ui_radiobutton_get(UiInteger *value) { 222 int selection = 0; 223 GSList *ls = value->obj; 224 int i = 0; 225 guint len = g_slist_length(ls); 226 while(ls) { 227 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ls->data))) { 228 selection = len - i - 1; 229 break; 230 } 231 ls = ls->next; 232 i++; 233 } 234 235 value->value = selection; 236 return selection; 237 } 238 239 void ui_radiobutton_set(UiInteger *value, int64_t i) { 240 GSList *ls = value->obj; 241 int s = g_slist_length(ls) - 1 - i; 242 int j = 0; 243 while(ls) { 244 if(j == s) { 245 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ls->data), TRUE); 246 break; 247 } 248 ls = ls->next; 249 j++; 250 } 251 252 value->value = i; 253 } 254 255