Fri, 14 Nov 2025 22:02:00 +0100
add spinbox (Motif)
/* * 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; } } }