ui/motif/entry.c

changeset 898
0484fc666c1d
parent 897
0d488f04078d
child 899
7e153ce81477
--- a/ui/motif/entry.c	Fri Nov 14 22:02:00 2025 +0100
+++ b/ui/motif/entry.c	Sat Nov 15 09:24:55 2025 +0100
@@ -106,46 +106,160 @@
             textfield = children[i];
         }
     }
-    
+     
     UiSpinBox *data = malloc(sizeof(UiSpinBox));
     data->obj = obj;
     data->textfield = textfield;
     data->var = var;
     data->vartype = vartype;
+    data->obs = NULL;
     data->onchange = args->onchange;
     data->onchangedata = args->onchangedata;
-    data->last_value = 0;
+    data->value = 0;
     data->min = min;
     data->max = max;
     data->increment = args->step;
     data->digits = args->digits;
     
+    UiObserver **obs = NULL;
+    if(var) {
+        double value = 0;
+        switch(vartype) {
+            default: break;
+            case UI_VAR_INTEGER: {
+                UiInteger *i = var->value;
+                i->get = ui_spinbutton_getint;
+                i->set = ui_spinbutton_setint;
+                i->obj = data;
+                value = (double)i->value;
+                obs = &i->observers;
+                break;
+            }
+            case UI_VAR_DOUBLE: {
+                UiDouble *d = var->value;
+                d->get = ui_spinbutton_getdouble;
+                d->set = ui_spinbutton_setdouble;
+                d->obj = data;
+                value = d->value;
+                obs = &d->observers;
+                break;
+            }
+            case UI_VAR_RANGE: {
+                UiRange *r = var->value;
+                r->get = ui_spinbutton_getrangeval;
+                r->set = ui_spinbutton_setrangeval;
+                r->setrange = ui_spinbutton_setrange;
+                r->setextent = ui_spinbutton_setextent;
+                r->obj = data;
+                value = r->value;
+                obs = &r->observers;
+                break;
+            }
+        }
+        ui_spinbox_set_value(data, value);
+    }
+    data->obs = obs;
+    
     XtAddCallback(
             spinbox,
             XmNvalueChangedCallback,
             (XtCallbackProc)ui_spinbox_value_changed,
             data);
     
+    XtAddCallback(
+            spinbox,
+            XmNdestroyCallback,
+            (XtCallbackProc)ui_destroy_data,
+            data);
+    
     XmTextFieldSetString(textfield, "0");
     
     
     return spinbox;
 }
 
+void ui_spinbox_set_value(UiSpinBox *spinbox, double value) {
+    if(value < spinbox->min) {
+        value = spinbox->min;
+    }
+    if(value > spinbox->max) {
+        value = spinbox->max;
+    }
+    
+    char buf[32];
+    snprintf(buf, 32, "%.*f", spinbox->digits, spinbox->value);
+    XmTextFieldSetString(spinbox->textfield, buf);
+    spinbox->value = value;
+}
+
 void ui_spinbox_value_changed(Widget widget, UiSpinBox *spinbox, XmSpinBoxCallbackStruct *cb) {
-    char buf[32];
+    Boolean update_value = TRUE;
+    double value = spinbox->value;
     switch(cb->reason) {
-        case 62: {
-            spinbox->last_value += spinbox->increment;
-            snprintf(buf, 32, "%.*f", spinbox->digits, spinbox->last_value);
-            XmTextFieldSetString(spinbox->textfield, buf);
+        case XmCR_OK: {
+            update_value = FALSE;
             break;
         }
-        case 63: {
-            spinbox->last_value -= spinbox->increment;
-            snprintf(buf, 32, "%.*f", spinbox->digits, spinbox->last_value);
-            XmTextFieldSetString(spinbox->textfield, buf);
+        case XmCR_SPIN_NEXT: {
+            value += spinbox->increment;
+            break;
+        }
+        case XmCR_SPIN_PRIOR: {
+            value -= spinbox->increment;
             break;
         }
     }
+    
+    if(update_value) {
+        ui_spinbox_set_value(spinbox, value);
+    }
 }
+
+int64_t ui_spinbutton_getint(UiInteger *i) {
+    UiSpinBox *spinbox = i->obj;
+    i->value = (int64_t)spinbox->value;
+    return i->value;
+}
+
+void ui_spinbutton_setint(UiInteger *i, int64_t val) {
+    UiSpinBox *spinbox = i->obj;
+    ui_spinbox_set_value(spinbox, (double)val);
+    i->value = spinbox->value;
+}
+
+double ui_spinbutton_getdouble(UiDouble *d) {
+    UiSpinBox *spinbox = d->obj;
+    d->value = spinbox->value;
+    return d->value;
+}
+
+void ui_spinbutton_setdouble(UiDouble *d, double val) {
+    UiSpinBox *spinbox = d->obj;
+    ui_spinbox_set_value(spinbox, val);
+    d->value = spinbox->value;
+}
+
+double ui_spinbutton_getrangeval(UiRange *r) {
+    UiSpinBox *spinbox = r->obj;
+    r->value = spinbox->value;
+    return r->value;
+}
+
+void ui_spinbutton_setrangeval(UiRange *r, double val) {
+    UiSpinBox *spinbox = r->obj;
+    ui_spinbox_set_value(spinbox, val);
+    r->value = spinbox->value;
+}
+void ui_spinbutton_setrange(UiRange *r, double min, double max) {
+    UiSpinBox *spinbox = r->obj;
+    spinbox->min = min;
+    spinbox->max = max;
+    r->min = min;
+    r->max = max;
+}
+
+void ui_spinbutton_setextent(UiRange *r, double extent) {
+    UiSpinBox *spinbox = r->obj;
+    spinbox->increment = extent;
+    r->extent = extent;
+}

mercurial