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 "../common/context.h" 33 #include "../common/object.h" 34 #include "container.h" 35 #include "entry.h" 36 37 #include <ucx/mempool.h> 38 39 UIWIDGET ui_spinner(UiObject *obj, int step, UiInteger *i) { 40 UiVar *var = malloc(sizeof(UiVar)); 41 var->value = i; 42 var->type = UI_VAR_SPECIAL; 43 return ui_spinner_var(obj, step, 0, var, UI_VAR_INTEGER); 44 } 45 46 UIWIDGET ui_spinnerf(UiObject *obj, double step, int digits, UiDouble *d) { 47 UiVar *var = malloc(sizeof(UiVar)); 48 var->value = d; 49 var->type = UI_VAR_SPECIAL; 50 return ui_spinner_var(obj, step, digits, var, UI_VAR_DOUBLE); 51 } 52 53 UIWIDGET ui_spinnerr(UiObject *obj, UiRange *r) { 54 UiVar *var = malloc(sizeof(UiVar)); 55 var->value = r; 56 var->type = UI_VAR_SPECIAL; 57 return ui_spinner_var(obj, r->extent, 1, var, UI_VAR_RANGE); 58 } 59 60 UIWIDGET ui_spinner_nv(UiObject *obj, int step, char *varname) { 61 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_INTEGER); 62 return ui_spinner_var(obj, step, 0, var, UI_VAR_INTEGER); 63 } 64 65 UIWIDGET ui_spinnerf_nv(UiObject *obj, double step, int digits, char *varname) { 66 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_DOUBLE); 67 return ui_spinner_var(obj, step, digits, var, UI_VAR_DOUBLE); 68 } 69 70 UIWIDGET ui_spinnerr_nv(UiObject *obj, char *varname) { 71 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_RANGE); 72 UiRange *r = var->value; 73 return ui_spinner_var(obj, r->extent, 1, var, UI_VAR_RANGE); 74 } 75 76 UIWIDGET ui_spinner_var(UiObject *obj, double step, int digits, UiVar *var, UiVarType type) { 77 double min = 0; 78 double max = 1000; 79 if(type == UI_VAR_RANGE) { 80 UiRange *r = var->value; 81 min = r->min; 82 max = r->max; 83 } 84 if(step == 0) { 85 step = 1; 86 } 87 #ifdef UI_GTK2LEGACY 88 if(min == max) { 89 max = min + 1; 90 } 91 #endif 92 GtkWidget *spin = gtk_spin_button_new_with_range(min, max, step); 93 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), digits); 94 if(var) { 95 double value = 0; 96 UiObserver **obs = NULL; 97 switch(type) { 98 default: break; 99 case UI_VAR_INTEGER: { 100 UiInteger *i = var->value; 101 i->get = ui_spinbutton_getint; 102 i->set = ui_spinbutton_setint; 103 i->obj = spin; 104 value = (double)i->value; 105 obs = &i->observers; 106 break; 107 } 108 case UI_VAR_DOUBLE: { 109 UiDouble *d = var->value; 110 d->get = ui_spinbutton_getdouble; 111 d->set = ui_spinbutton_setdouble; 112 d->obj = spin; 113 value = d->value; 114 obs = &d->observers; 115 break; 116 } 117 case UI_VAR_RANGE: { 118 UiRange *r = var->value; 119 r->get = ui_spinbutton_getrangeval; 120 r->set = ui_spinbutton_setrangeval; 121 r->setrange = ui_spinbutton_setrange; 122 r->setextent = ui_spinbutton_setextent; 123 r->obj = spin; 124 value = r->value; 125 obs = &r->observers; 126 break; 127 } 128 } 129 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), value); 130 131 UiVarEventData *event = malloc(sizeof(UiVarEventData)); 132 event->obj = obj; 133 event->var = var; 134 event->observers = obs; 135 136 g_signal_connect( 137 spin, 138 "value-changed", 139 G_CALLBACK(ui_spinner_changed), 140 event); 141 g_signal_connect( 142 spin, 143 "destroy", 144 G_CALLBACK(ui_destroy_vardata), 145 event); 146 } 147 148 UiContainer *ct = uic_get_current_container(obj); 149 ct->add(ct, spin, FALSE); 150 151 return spin; 152 } 153 154 void ui_spinner_setrange(UIWIDGET spinner, double min, double max) { 155 gtk_spin_button_set_range(GTK_SPIN_BUTTON(spinner), min, max); 156 } 157 158 void ui_spinner_setdigits(UIWIDGET spinner, int digits) { 159 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spinner), digits); 160 } 161 162 163 void ui_spinner_changed(GtkSpinButton *spinner, UiVarEventData *event) { 164 UiEvent e; 165 e.obj = event->obj; 166 e.window = event->obj->window; 167 e.document = event->obj->ctx->document; 168 e.eventdata = event->var->value; 169 e.intval = 0; 170 171 UiObserver *observer = *event->observers; 172 ui_notify_evt(observer, &e); 173 } 174 175 176 int64_t ui_spinbutton_getint(UiInteger *i) { 177 i->value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(i->obj)); 178 return i->value; 179 } 180 181 void ui_spinbutton_setint(UiInteger *i, int64_t val) { 182 gtk_spin_button_set_value(GTK_SPIN_BUTTON(i->obj), (double)val); 183 i->value = val; 184 } 185 186 double ui_spinbutton_getdouble(UiDouble *d) { 187 d->value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(d->obj)); 188 return d->value; 189 } 190 191 void ui_spinbutton_setdouble(UiDouble *d, double val) { 192 gtk_spin_button_set_value(GTK_SPIN_BUTTON(d->obj), val); 193 d->value = val; 194 } 195 196 double ui_spinbutton_getrangeval(UiRange *r) { 197 r->value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(r->obj)); 198 return r->value; 199 } 200 201 void ui_spinbutton_setrangeval(UiRange *r, double val) { 202 gtk_spin_button_set_value(GTK_SPIN_BUTTON(r->obj), val); 203 r->value = val; 204 } 205 void ui_spinbutton_setrange(UiRange *r, double min, double max) { 206 gtk_spin_button_set_range(GTK_SPIN_BUTTON(r->obj), min, max); 207 r->min = min; 208 r->max = max; 209 } 210 211 void ui_spinbutton_setextent(UiRange *r, double extent) { 212 gtk_spin_button_set_increments(GTK_SPIN_BUTTON(r->obj), extent, extent*10); 213 r->extent = extent; 214 } 215