| 104 Widget w = children[i]; |
104 Widget w = children[i]; |
| 105 if(type == XmNUMERIC) { |
105 if(type == XmNUMERIC) { |
| 106 textfield = children[i]; |
106 textfield = children[i]; |
| 107 } |
107 } |
| 108 } |
108 } |
| 109 |
109 |
| 110 UiSpinBox *data = malloc(sizeof(UiSpinBox)); |
110 UiSpinBox *data = malloc(sizeof(UiSpinBox)); |
| 111 data->obj = obj; |
111 data->obj = obj; |
| 112 data->textfield = textfield; |
112 data->textfield = textfield; |
| 113 data->var = var; |
113 data->var = var; |
| 114 data->vartype = vartype; |
114 data->vartype = vartype; |
| |
115 data->obs = NULL; |
| 115 data->onchange = args->onchange; |
116 data->onchange = args->onchange; |
| 116 data->onchangedata = args->onchangedata; |
117 data->onchangedata = args->onchangedata; |
| 117 data->last_value = 0; |
118 data->value = 0; |
| 118 data->min = min; |
119 data->min = min; |
| 119 data->max = max; |
120 data->max = max; |
| 120 data->increment = args->step; |
121 data->increment = args->step; |
| 121 data->digits = args->digits; |
122 data->digits = args->digits; |
| |
123 |
| |
124 UiObserver **obs = NULL; |
| |
125 if(var) { |
| |
126 double value = 0; |
| |
127 switch(vartype) { |
| |
128 default: break; |
| |
129 case UI_VAR_INTEGER: { |
| |
130 UiInteger *i = var->value; |
| |
131 i->get = ui_spinbutton_getint; |
| |
132 i->set = ui_spinbutton_setint; |
| |
133 i->obj = data; |
| |
134 value = (double)i->value; |
| |
135 obs = &i->observers; |
| |
136 break; |
| |
137 } |
| |
138 case UI_VAR_DOUBLE: { |
| |
139 UiDouble *d = var->value; |
| |
140 d->get = ui_spinbutton_getdouble; |
| |
141 d->set = ui_spinbutton_setdouble; |
| |
142 d->obj = data; |
| |
143 value = d->value; |
| |
144 obs = &d->observers; |
| |
145 break; |
| |
146 } |
| |
147 case UI_VAR_RANGE: { |
| |
148 UiRange *r = var->value; |
| |
149 r->get = ui_spinbutton_getrangeval; |
| |
150 r->set = ui_spinbutton_setrangeval; |
| |
151 r->setrange = ui_spinbutton_setrange; |
| |
152 r->setextent = ui_spinbutton_setextent; |
| |
153 r->obj = data; |
| |
154 value = r->value; |
| |
155 obs = &r->observers; |
| |
156 break; |
| |
157 } |
| |
158 } |
| |
159 ui_spinbox_set_value(data, value); |
| |
160 } |
| |
161 data->obs = obs; |
| 122 |
162 |
| 123 XtAddCallback( |
163 XtAddCallback( |
| 124 spinbox, |
164 spinbox, |
| 125 XmNvalueChangedCallback, |
165 XmNvalueChangedCallback, |
| 126 (XtCallbackProc)ui_spinbox_value_changed, |
166 (XtCallbackProc)ui_spinbox_value_changed, |
| 127 data); |
167 data); |
| 128 |
168 |
| |
169 XtAddCallback( |
| |
170 spinbox, |
| |
171 XmNdestroyCallback, |
| |
172 (XtCallbackProc)ui_destroy_data, |
| |
173 data); |
| |
174 |
| 129 XmTextFieldSetString(textfield, "0"); |
175 XmTextFieldSetString(textfield, "0"); |
| 130 |
176 |
| 131 |
177 |
| 132 return spinbox; |
178 return spinbox; |
| 133 } |
179 } |
| 134 |
180 |
| |
181 void ui_spinbox_set_value(UiSpinBox *spinbox, double value) { |
| |
182 if(value < spinbox->min) { |
| |
183 value = spinbox->min; |
| |
184 } |
| |
185 if(value > spinbox->max) { |
| |
186 value = spinbox->max; |
| |
187 } |
| |
188 |
| |
189 char buf[32]; |
| |
190 snprintf(buf, 32, "%.*f", spinbox->digits, spinbox->value); |
| |
191 XmTextFieldSetString(spinbox->textfield, buf); |
| |
192 spinbox->value = value; |
| |
193 } |
| |
194 |
| 135 void ui_spinbox_value_changed(Widget widget, UiSpinBox *spinbox, XmSpinBoxCallbackStruct *cb) { |
195 void ui_spinbox_value_changed(Widget widget, UiSpinBox *spinbox, XmSpinBoxCallbackStruct *cb) { |
| 136 char buf[32]; |
196 Boolean update_value = TRUE; |
| |
197 double value = spinbox->value; |
| 137 switch(cb->reason) { |
198 switch(cb->reason) { |
| 138 case 62: { |
199 case XmCR_OK: { |
| 139 spinbox->last_value += spinbox->increment; |
200 update_value = FALSE; |
| 140 snprintf(buf, 32, "%.*f", spinbox->digits, spinbox->last_value); |
|
| 141 XmTextFieldSetString(spinbox->textfield, buf); |
|
| 142 break; |
201 break; |
| 143 } |
202 } |
| 144 case 63: { |
203 case XmCR_SPIN_NEXT: { |
| 145 spinbox->last_value -= spinbox->increment; |
204 value += spinbox->increment; |
| 146 snprintf(buf, 32, "%.*f", spinbox->digits, spinbox->last_value); |
|
| 147 XmTextFieldSetString(spinbox->textfield, buf); |
|
| 148 break; |
205 break; |
| 149 } |
206 } |
| 150 } |
207 case XmCR_SPIN_PRIOR: { |
| 151 } |
208 value -= spinbox->increment; |
| |
209 break; |
| |
210 } |
| |
211 } |
| |
212 |
| |
213 if(update_value) { |
| |
214 ui_spinbox_set_value(spinbox, value); |
| |
215 } |
| |
216 } |
| |
217 |
| |
218 int64_t ui_spinbutton_getint(UiInteger *i) { |
| |
219 UiSpinBox *spinbox = i->obj; |
| |
220 i->value = (int64_t)spinbox->value; |
| |
221 return i->value; |
| |
222 } |
| |
223 |
| |
224 void ui_spinbutton_setint(UiInteger *i, int64_t val) { |
| |
225 UiSpinBox *spinbox = i->obj; |
| |
226 ui_spinbox_set_value(spinbox, (double)val); |
| |
227 i->value = spinbox->value; |
| |
228 } |
| |
229 |
| |
230 double ui_spinbutton_getdouble(UiDouble *d) { |
| |
231 UiSpinBox *spinbox = d->obj; |
| |
232 d->value = spinbox->value; |
| |
233 return d->value; |
| |
234 } |
| |
235 |
| |
236 void ui_spinbutton_setdouble(UiDouble *d, double val) { |
| |
237 UiSpinBox *spinbox = d->obj; |
| |
238 ui_spinbox_set_value(spinbox, val); |
| |
239 d->value = spinbox->value; |
| |
240 } |
| |
241 |
| |
242 double ui_spinbutton_getrangeval(UiRange *r) { |
| |
243 UiSpinBox *spinbox = r->obj; |
| |
244 r->value = spinbox->value; |
| |
245 return r->value; |
| |
246 } |
| |
247 |
| |
248 void ui_spinbutton_setrangeval(UiRange *r, double val) { |
| |
249 UiSpinBox *spinbox = r->obj; |
| |
250 ui_spinbox_set_value(spinbox, val); |
| |
251 r->value = spinbox->value; |
| |
252 } |
| |
253 void ui_spinbutton_setrange(UiRange *r, double min, double max) { |
| |
254 UiSpinBox *spinbox = r->obj; |
| |
255 spinbox->min = min; |
| |
256 spinbox->max = max; |
| |
257 r->min = min; |
| |
258 r->max = max; |
| |
259 } |
| |
260 |
| |
261 void ui_spinbutton_setextent(UiRange *r, double extent) { |
| |
262 UiSpinBox *spinbox = r->obj; |
| |
263 spinbox->increment = extent; |
| |
264 r->extent = extent; |
| |
265 } |