--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/motif/entry.c Fri Nov 14 22:02:00 2025 +0100 @@ -0,0 +1,151 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 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 "entry.h" + + +UIWIDGET ui_spinbox_create(UiObject *obj, UiSpinBoxArgs *args) { + Arg xargs[16]; + int n = 0; + + double min = args->min; + double max = args->max != 0 ? args->max : 1000; + + UiVar *var = NULL; + UiVarType vartype = 0; + if(args->varname) { + var = uic_get_var(obj->ctx, args->varname); + if(var) { + vartype = var->type; + } else { + var = uic_widget_var(obj->ctx, obj->ctx, args->rangevalue, args->varname, UI_VAR_RANGE); + vartype = UI_VAR_RANGE; + } + } + + if(!var) { + if(args->intvalue) { + var = uic_widget_var(obj->ctx, obj->ctx, args->intvalue, NULL, UI_VAR_INTEGER); + vartype = UI_VAR_INTEGER; + } else if(args->doublevalue) { + var = uic_widget_var(obj->ctx, obj->ctx, args->doublevalue, NULL, UI_VAR_DOUBLE); + vartype = UI_VAR_DOUBLE; + } else if(args->rangevalue) { + var = uic_widget_var(obj->ctx, obj->ctx, args->rangevalue, NULL, UI_VAR_RANGE); + vartype = UI_VAR_RANGE; + } + } + + if(vartype == UI_VAR_RANGE) { + UiRange *r = var->value; + min = r->min; + max = r->max; + } + if(args->step == 0) { + args->step = 1; + } + + UiContainerPrivate *ctn = ui_obj_container(obj); + UiLayout layout = UI_ARGS2LAYOUT(args); + + + XtSetArg(xargs[n], XmNminimumValue, 0); n++; + XtSetArg(xargs[n], XmNmaximumValue, 100); n++; + XtSetArg(xargs[n], XmNincrementValue, 1); n++; + XtSetArg(xargs[n], XmNspinBoxChildType, XmNUMERIC); n++; + + Widget parent = ui_container_prepare(ctn, &layout, xargs, &n); + + char *name = args->name ? (char*)args->name : "button"; + Widget spinbox = XmCreateSimpleSpinBox(parent, name, xargs, n); + XtManageChild(spinbox); + ui_container_add(ctn, spinbox); + + ui_set_widget_groups(obj->ctx, spinbox, args->groups); + + WidgetList children; + Cardinal num_children; + unsigned char type; + + Widget textfield = NULL; + XtVaGetValues( + spinbox, + XmNchildren, &children, + XmNnumChildren, &num_children, + NULL); + + for(int i = 0;i<num_children;i++) { + XtVaGetValues(children[i], XmNspinBoxChildType, &type, NULL); + Widget w = children[i]; + if(type == XmNUMERIC) { + textfield = children[i]; + } + } + + UiSpinBox *data = malloc(sizeof(UiSpinBox)); + data->obj = obj; + data->textfield = textfield; + data->var = var; + data->vartype = vartype; + data->onchange = args->onchange; + data->onchangedata = args->onchangedata; + data->last_value = 0; + data->min = min; + data->max = max; + data->increment = args->step; + data->digits = args->digits; + + XtAddCallback( + spinbox, + XmNvalueChangedCallback, + (XtCallbackProc)ui_spinbox_value_changed, + data); + + XmTextFieldSetString(textfield, "0"); + + + return spinbox; +} + +void ui_spinbox_value_changed(Widget widget, UiSpinBox *spinbox, XmSpinBoxCallbackStruct *cb) { + char buf[32]; + switch(cb->reason) { + case 62: { + spinbox->last_value += spinbox->increment; + snprintf(buf, 32, "%.*f", spinbox->digits, spinbox->last_value); + XmTextFieldSetString(spinbox->textfield, buf); + break; + } + case 63: { + spinbox->last_value -= spinbox->increment; + snprintf(buf, 32, "%.*f", spinbox->digits, spinbox->last_value); + XmTextFieldSetString(spinbox->textfield, buf); + break; + } + } +}