1 /**************************************************************************\
2 *
3 * This file is part of the Coin 3D visualization library.
4 * Copyright (C) by Kongsberg Oil & Gas Technologies.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * ("GPL") version 2 as published by the Free Software Foundation.
9 * See the file LICENSE.GPL at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using Coin with software that can not be combined with the GNU
13 * GPL, and for taking advantage of the additional benefits of our
14 * support services, please contact Kongsberg Oil & Gas Technologies
15 * about acquiring a Coin Professional Edition License.
16 *
17 * See http://www.coin3d.org/ for more information.
18 *
19 * Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, NORWAY.
20 * http://www.sim.no/ sales@sim.no coin-support@coin3d.org
21 *
22 \**************************************************************************/
23
24 #include <assert.h>
25 #include <stdlib.h>
26
27 #include <X11/Intrinsic.h>
28 #include <Xm/Xm.h>
29 #include <Xm/Form.h>
30 #include <Xm/Label.h>
31 #include <Xm/Scale.h>
32 #include <Xm/Text.h>
33 #include <Xm/PushB.h>
34
35 #include <Inventor/errors/SoDebugError.h>
36 #include <Inventor/SbPList.h>
37
38 #include <soxtdefs.h>
39 #include <Inventor/Xt/SoXtBasic.h>
40
41 #include <Inventor/Xt/widgets/SoXtSlider.h>
42
43 /*!
44 \class SoXtSlider Inventor/Xt/widgets/compound/SoXtSlider.h
45 \brief The SoXtSlider class manages a compound widget containing a
46 generic slider.
47
48 This class is internal to SoXt and may change interface without notice.
49 */
50
51 // *************************************************************************
52
53 /*!
54 */
55
SoXtSlider(const char * const thetitle)56 SoXtSlider::SoXtSlider(
57 const char * const thetitle)
58 {
59 this->s_form = NULL;
60 this->s_value = NULL;
61 this->s_slider = NULL;
62
63 this->r_form = NULL;
64 this->r_value = NULL;
65 this->r_slider = NULL;
66 this->r_minValue = NULL;
67 this->r_maxValue = NULL;
68
69 this->f_form = NULL;
70 this->f_value = NULL;
71 this->f_slider = NULL;
72 this->f_min = NULL;
73 this->f_minValue = NULL;
74 this->f_max = NULL;
75 this->f_maxValue = NULL;
76 this->f_label = NULL;
77
78 this->o_form = NULL;
79 this->o_value = NULL;
80 this->o_slider = NULL;
81 this->o_label = NULL;
82
83 if ( thetitle ) {
84 this->title = new char [strlen(thetitle)+1];
85 assert(this->title);
86 strcpy(this->title, thetitle);
87 } else {
88 this->title = NULL;
89 }
90 this->callbacks = NULL;
91
92 this->current = 0.0f;
93 this->minimum = 0.0f;
94 this->maximum = 1.0f;
95 } // SoXtSlider()
96
97 /*!
98 */
99
~SoXtSlider(void)100 SoXtSlider::~SoXtSlider(
101 void)
102 {
103 delete [] this->title;
104 } // ~SoXtSlider()
105
106 // *************************************************************************
107
108 /*!
109 */
110
111 void
setValue(float value)112 SoXtSlider::setValue(
113 float value)
114 {
115 this->current = value;
116 // FIXME: update widgets
117 } // setValue()
118
119 /*!
120 */
121
122 float
getValue(void) const123 SoXtSlider::getValue(
124 void) const
125 {
126 return this->current;
127 } // getValue()
128
129 // *************************************************************************
130
131 /*!
132 */
133
134 void
setRange(float min,float max)135 SoXtSlider::setRange(
136 float min,
137 float max)
138 {
139 this->minimum = min;
140 this->maximum = max;
141 } // setRange()
142
143 /*!
144 */
145
146 void
getRange(float & min,float & max) const147 SoXtSlider::getRange(
148 float & min,
149 float & max) const
150 {
151 min = this->minimum;
152 max = this->maximum;
153 } // getRange()
154
155 // *************************************************************************
156
157 struct SoXtSliderCallbackInfo {
158 SoXtSliderCB * callback;
159 void * closure;
160 };
161
162 /*!
163 */
164
165 void
addCallback(SoXtSliderCB * callback,void * closure)166 SoXtSlider::addCallback(
167 SoXtSliderCB * callback,
168 void * closure)
169 {
170 if (this->callbacks == NULL)
171 this->callbacks = new SbPList;
172 SoXtSliderCallbackInfo * info = new SoXtSliderCallbackInfo;
173 info->callback = callback;
174 info->closure = closure;
175 this->callbacks->append(info);
176 } // addCallback()
177
178 /*!
179 */
180
181 void
removeCallback(SoXtSliderCB * callback,void * closure)182 SoXtSlider::removeCallback(
183 SoXtSliderCB * callback,
184 void * closure)
185 {
186 if (this->callbacks == NULL) {
187 #if SOXT_DEBUG
188 SoDebugError::postInfo("SoXtSlider::removeCallback",
189 "no callbacks");
190 #endif // SOXT_DEBUG
191 return;
192 }
193 const int num = this->callbacks->getLength();
194 for (int i = 0; i < num; i++) {
195 SoXtSliderCallbackInfo * info =
196 (SoXtSliderCallbackInfo *) (*this->callbacks)[i];
197 if (info->callback == callback && info->closure == closure) {
198 this->callbacks->remove(i);
199 return;
200 }
201 }
202 #if SOXT_DEBUG
203 SoDebugError::postInfo("SoXtSlider::removeCallback",
204 "no such callback");
205 #endif // SOXT_DEBUG
206 } // removeCallback()
207
208 /*!
209 */
210
211 void
invokeCallbacks(void)212 SoXtSlider::invokeCallbacks(
213 void)
214 {
215 if (this->callbacks != NULL) {
216 const int num = this->callbacks->getLength();
217 for (int i = 0; i < num; i++) {
218 SoXtSliderCallbackInfo * info =
219 (SoXtSliderCallbackInfo *) (*this->callbacks)[i];
220 info->callback(info->closure, this->title, this->current);
221 }
222 }
223 } // invokeCallbacks()
224
225 // *************************************************************************
226
227 /*!
228 */
229
230 Widget
buildSimpleWidget(const Widget parent)231 SoXtSlider::buildSimpleWidget(// protected
232 const Widget parent)
233 {
234 if (this->s_form == (Widget) NULL) {
235 this->s_form = XtVaCreateManagedWidget("simple",
236 xmFormWidgetClass, parent,
237 NULL);
238
239 this->s_value = XtVaCreateManagedWidget("value",
240 xmTextWidgetClass, this->s_form,
241 XmNleftAttachment, XmATTACH_FORM,
242 XmNtopAttachment, XmATTACH_FORM,
243 XmNrightAttachment, XmATTACH_NONE,
244 XmNbottomAttachment, XmATTACH_NONE,
245 XmNwidth, 60,
246 XmNhighlightThickness, 0,
247 NULL);
248
249 char text[16];
250 sprintf(text, "%g", this->current);
251 XmTextSetString(this->s_value, text);
252 XmTextSetCursorPosition(this->s_value, strlen(text));
253
254 XtAddCallback(this->s_value, XmNactivateCallback,
255 SoXtSlider::value_cb, (XtPointer) this);
256 XtAddCallback(this->s_value, XmNlosingFocusCallback,
257 SoXtSlider::value_cb, (XtPointer) this);
258
259 this->s_slider = XtVaCreateManagedWidget("slider",
260 xmScaleWidgetClass, this->s_form,
261 XmNleftAttachment, XmATTACH_WIDGET,
262 XmNleftWidget, this->s_value,
263 XmNleftOffset, 2,
264 XmNtopAttachment, XmATTACH_FORM,
265 XmNtopOffset, 2,
266 XmNrightAttachment, XmATTACH_FORM,
267 XmNrightOffset, 2,
268 XmNbottomAttachment, XmATTACH_FORM,
269 XmNbottomOffset, 2,
270 XmNorientation, XmHORIZONTAL,
271 XmNtraversalOn, False,
272 XmNminimum, 0,
273 XmNvalue, 0,
274 XmNmaximum, 999,
275 XmNshowValue, False,
276 XmNhighlightThickness, 0,
277 XtVaTypedArg,
278 XmNtitleString, XmRString,
279 "", 0,
280 NULL);
281
282 XtAddCallback(this->s_slider, XmNdragCallback,
283 SoXtSlider::slider_cb, (XtPointer) this);
284 XtAddCallback(this->s_slider, XmNvalueChangedCallback,
285 SoXtSlider::slider_cb, (XtPointer) this);
286 }
287 return this->s_form;
288 } // buildSimpleWidget()
289
290 /*!
291 */
292
293 Widget
buildRangedWidget(const Widget parent)294 SoXtSlider::buildRangedWidget(
295 const Widget parent)
296 {
297 if (this->r_form == (Widget) NULL) {
298 this->r_form = XtVaCreateManagedWidget("ranged",
299 xmFormWidgetClass, parent,
300 NULL);
301
302 this->r_slider = XtVaCreateManagedWidget("slider",
303 xmScaleWidgetClass, this->r_form,
304 XmNorientation, XmHORIZONTAL,
305 XmNtraversalOn, False,
306 XmNminimum, 0,
307 XmNvalue, 0,
308 XmNmaximum, 999,
309 XmNshowValue, False,
310 XmNhighlightThickness, 0,
311 XtVaTypedArg,
312 XmNtitleString, XmRString, "", 0,
313 NULL);
314
315 XtAddCallback(this->r_slider, XmNdragCallback,
316 SoXtSlider::slider_cb, (XtPointer) this);
317 XtAddCallback(this->r_slider, XmNvalueChangedCallback,
318 SoXtSlider::slider_cb, (XtPointer) this);
319
320 this->r_value = XtVaCreateManagedWidget("value",
321 xmTextWidgetClass, this->r_form,
322 XmNhighlightThickness, 0,
323 NULL);
324
325 char text[16];
326 sprintf(text, "%g", this->current);
327 XmTextSetString(this->r_value, text);
328 XmTextSetCursorPosition(this->r_value, strlen(text));
329
330 XtAddCallback(this->r_value, XmNactivateCallback,
331 SoXtSlider::value_cb, (XtPointer) this);
332 XtAddCallback(this->r_value, XmNlosingFocusCallback,
333 SoXtSlider::value_cb, (XtPointer) this);
334
335 this->r_minValue = XtVaCreateManagedWidget("minValue",
336 xmTextWidgetClass, this->r_form,
337 XmNhighlightThickness, 0,
338 NULL);
339
340 sprintf(text, "%g", this->minimum);
341 XmTextSetString(this->r_minValue, text);
342 XmTextSetCursorPosition(this->r_minValue, strlen(text));
343
344 XtAddCallback(this->r_minValue, XmNactivateCallback,
345 SoXtSlider::min_value_cb, (XtPointer) this);
346 XtAddCallback(this->r_minValue, XmNlosingFocusCallback,
347 SoXtSlider::min_value_cb, (XtPointer) this);
348
349 this->r_maxValue = XtVaCreateManagedWidget("maxValue",
350 xmTextWidgetClass, this->r_form,
351 XmNhighlightThickness, 0,
352 NULL);
353
354 sprintf(text, "%g", this->maximum);
355 XmTextSetString(this->r_maxValue, text);
356 XmTextSetCursorPosition(this->r_maxValue, strlen(text));
357
358 XtAddCallback(this->r_maxValue, XmNactivateCallback,
359 SoXtSlider::max_value_cb, (XtPointer) this);
360 XtAddCallback(this->r_maxValue, XmNlosingFocusCallback,
361 SoXtSlider::max_value_cb, (XtPointer) this);
362
363 XtVaSetValues(this->r_value,
364 XmNleftAttachment, XmATTACH_FORM,
365 XmNtopAttachment, XmATTACH_FORM,
366 XmNrightAttachment, XmATTACH_NONE,
367 XmNbottomAttachment, XmATTACH_NONE,
368 XmNwidth, 60,
369 NULL);
370
371 XtVaSetValues(this->r_minValue,
372 XmNleftAttachment, XmATTACH_WIDGET,
373 XmNleftWidget, this->r_value,
374 XmNtopAttachment, XmATTACH_FORM,
375 XmNrightAttachment, XmATTACH_NONE,
376 XmNbottomAttachment, XmATTACH_NONE,
377 XmNwidth, 50,
378 NULL);
379
380 XtVaSetValues(this->r_maxValue,
381 XmNleftAttachment, XmATTACH_NONE,
382 XmNtopAttachment, XmATTACH_FORM,
383 XmNrightAttachment, XmATTACH_FORM,
384 XmNbottomAttachment, XmATTACH_NONE,
385 XmNwidth, 50,
386 NULL);
387
388 XtVaSetValues(this->r_slider,
389 XmNleftAttachment, XmATTACH_WIDGET,
390 XmNleftWidget, this->r_minValue,
391 XmNleftOffset, 2,
392 XmNtopAttachment, XmATTACH_FORM,
393 XmNtopOffset, 2,
394 XmNrightAttachment, XmATTACH_WIDGET,
395 XmNrightWidget, this->r_maxValue,
396 XmNrightOffset, 2,
397 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
398 XmNbottomWidget, this->r_minValue,
399 XmNbottomOffset, 2,
400 XtVaTypedArg,
401 XmNtitleString, XmRString,
402 "", 0,
403 NULL);
404 }
405 return this->r_form;
406 } // buildRangedWidget()
407
408 /*!
409 */
410
411 Widget
buildFullWidget(const Widget parent)412 SoXtSlider::buildFullWidget(
413 const Widget parent)
414 {
415 if (this->f_form == (Widget) NULL) {
416 char text[16];
417
418 this->f_form = XtVaCreateManagedWidget("slider",
419 xmFormWidgetClass, parent,
420 NULL);
421
422 this->f_minValue = XtVaCreateManagedWidget("minValue",
423 xmTextWidgetClass, this->f_form,
424 XmNleftAttachment, XmATTACH_FORM,
425 XmNtopAttachment, XmATTACH_FORM,
426 XmNrightAttachment, XmATTACH_NONE,
427 XmNbottomAttachment, XmATTACH_NONE,
428 XmNwidth, 50,
429 XmNhighlightThickness, 0,
430 NULL);
431
432 sprintf(text, "%g", this->minimum);
433 XmTextSetString(this->f_minValue, text);
434 XmTextSetCursorPosition(this->f_minValue, strlen(text));
435
436 XtAddCallback(this->f_minValue, XmNactivateCallback,
437 SoXtSlider::min_value_cb, (XtPointer) this);
438 XtAddCallback(this->f_minValue, XmNlosingFocusCallback,
439 SoXtSlider::min_value_cb, (XtPointer) this);
440
441 this->f_maxValue = XtVaCreateManagedWidget("maxValue",
442 xmTextWidgetClass, this->f_form,
443 XmNleftAttachment, XmATTACH_NONE,
444 XmNtopAttachment, XmATTACH_FORM,
445 XmNrightAttachment, XmATTACH_FORM,
446 XmNbottomAttachment, XmATTACH_NONE,
447 XmNwidth, 50,
448 XmNhighlightThickness, 0,
449 NULL);
450
451 sprintf(text, "%g", this->maximum);
452 XmTextSetString(this->f_maxValue, text);
453 XmTextSetCursorPosition(this->f_maxValue, strlen(text));
454
455 XtAddCallback(this->f_maxValue, XmNactivateCallback,
456 SoXtSlider::max_value_cb, (XtPointer) this);
457 XtAddCallback(this->f_maxValue, XmNlosingFocusCallback,
458 SoXtSlider::max_value_cb, (XtPointer) this);
459
460 this->f_value = XtVaCreateManagedWidget("value",
461 xmTextWidgetClass, this->f_form,
462 XmNleftAttachment, XmATTACH_WIDGET,
463 XmNleftWidget, this->f_minValue,
464 XmNleftOffset, 2,
465 XmNtopAttachment, XmATTACH_FORM,
466 XmNrightAttachment, XmATTACH_WIDGET,
467 XmNrightWidget, this->f_maxValue,
468 XmNrightOffset, 2,
469 XmNhighlightThickness, 0,
470 NULL);
471
472 sprintf(text, "%g", this->current);
473 XmTextSetString(this->f_value, text);
474 XmTextSetCursorPosition(this->f_value, strlen(text));
475
476 XtAddCallback(this->f_value, XmNactivateCallback,
477 SoXtSlider::value_cb, (XtPointer) this);
478 XtAddCallback(this->f_value, XmNlosingFocusCallback,
479 SoXtSlider::value_cb, (XtPointer) this);
480
481 this->f_min = XtVaCreateManagedWidget("min",
482 xmPushButtonWidgetClass, this->f_form,
483 XmNleftAttachment, XmATTACH_FORM,
484 XmNtopAttachment, XmATTACH_WIDGET,
485 XmNtopWidget, this->f_minValue,
486 XmNtopOffset, 2,
487 XmNbottomOffset, 2,
488 XmNwidth, 50,
489 XmNtraversalOn, False,
490 NULL);
491
492 XtAddCallback(this->f_min, XmNactivateCallback,
493 SoXtSlider::min_cb, (XtPointer) this);
494
495 this->f_max = XtVaCreateManagedWidget("max",
496 xmPushButtonWidgetClass, this->f_form,
497 XmNtopAttachment, XmATTACH_WIDGET,
498 XmNtopWidget, this->f_maxValue,
499 XmNtopOffset, 2,
500 XmNrightAttachment, XmATTACH_FORM,
501 XmNbottomOffset, 2,
502 XmNwidth, 50,
503 XmNtraversalOn, False,
504 NULL);
505
506 XtAddCallback(this->f_max, XmNactivateCallback,
507 SoXtSlider::max_cb, (XtPointer) this);
508
509 this->f_slider = XtVaCreateManagedWidget("slider",
510 xmScaleWidgetClass, this->f_form,
511 XmNleftAttachment, XmATTACH_WIDGET,
512 XmNleftWidget, this->f_minValue,
513 XmNleftOffset, 2,
514 XmNtopAttachment, XmATTACH_WIDGET,
515 XmNtopWidget, this->f_value,
516 XmNtopOffset, 2,
517 XmNrightAttachment, XmATTACH_WIDGET,
518 XmNrightWidget, this->f_maxValue,
519 XmNrightOffset, 2,
520 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
521 XmNbottomWidget, this->f_min,
522 XmNbottomOffset, 2,
523 XmNorientation, XmHORIZONTAL,
524 XmNtraversalOn, False,
525 XmNminimum, 0,
526 XmNvalue, 0,
527 XmNmaximum, 999,
528 XmNshowValue, False,
529 XmNhighlightThickness, 0,
530 NULL);
531
532 XtAddCallback(this->f_slider, XmNdragCallback,
533 SoXtSlider::slider_cb, (XtPointer) this);
534 XtAddCallback(this->f_slider, XmNvalueChangedCallback,
535 SoXtSlider::slider_cb, (XtPointer) this);
536
537 this->f_label = XtVaCreateManagedWidget("label",
538 xmLabelWidgetClass, this->f_form,
539 XmNleftAttachment, XmATTACH_WIDGET,
540 XmNleftWidget, this->f_min,
541 XmNtopAttachment, XmATTACH_WIDGET,
542 XmNtopWidget, this->f_slider,
543 XmNrightAttachment, XmATTACH_WIDGET,
544 XmNrightWidget, this->f_max,
545 XmNalignment, XmALIGNMENT_BEGINNING,
546 XtVaTypedArg,
547 XmNlabelString, XmRString,
548 this->title, strlen(this->title)+1,
549 NULL);
550
551 }
552 return this->f_form;
553 } // buildFullWidget()
554
555 /*!
556 */
557
558 Widget
buildOrderlyWidget(const Widget parent)559 SoXtSlider::buildOrderlyWidget(
560 const Widget parent)
561 {
562 if (this->o_form == (Widget) NULL) {
563 this->o_form = XtVaCreateManagedWidget("orderly",
564 xmFormWidgetClass, parent,
565 NULL);
566
567 this->o_value = XtVaCreateManagedWidget("value",
568 xmTextWidgetClass, this->o_form,
569 XmNleftAttachment, XmATTACH_FORM,
570 XmNtopAttachment, XmATTACH_FORM,
571 XmNrightAttachment, XmATTACH_FORM,
572 XmNhighlightThickness, 0,
573 NULL);
574
575 char text[16];
576 sprintf(text, "%g", this->current);
577 XmTextSetString(this->o_value, text);
578 XmTextSetCursorPosition(this->o_value, strlen(text));
579
580 XtAddCallback(this->o_value, XmNactivateCallback,
581 SoXtSlider::value_cb, (XtPointer) this);
582 XtAddCallback(this->o_value, XmNlosingFocusCallback,
583 SoXtSlider::value_cb, (XtPointer) this);
584
585 this->o_slider = XtVaCreateManagedWidget("slider",
586 xmScaleWidgetClass, this->o_form,
587 XmNleftAttachment, XmATTACH_FORM,
588 XmNtopAttachment, XmATTACH_WIDGET,
589 XmNtopWidget, this->o_value,
590 XmNtopOffset, 2,
591 XmNrightAttachment, XmATTACH_FORM,
592 XmNorientation, XmHORIZONTAL,
593 XmNtraversalOn, False,
594 XmNminimum, 0,
595 XmNvalue, 0,
596 XmNmaximum, 999,
597 XmNshowValue, False,
598 XmNhighlightThickness, 0,
599 NULL);
600
601 XtAddCallback(this->o_slider, XmNdragCallback,
602 SoXtSlider::slider_cb, (XtPointer) this);
603 XtAddCallback(this->o_slider, XmNvalueChangedCallback,
604 SoXtSlider::slider_cb, (XtPointer) this);
605
606 this->o_label = XtVaCreateManagedWidget("label",
607 xmLabelWidgetClass, this->o_form,
608 XmNleftAttachment, XmATTACH_FORM,
609 XmNtopAttachment, XmATTACH_WIDGET,
610 XmNtopWidget, this->o_slider,
611 XmNrightAttachment, XmATTACH_FORM,
612 XmNbottomAttachment, XmATTACH_FORM,
613 XtVaTypedArg,
614 XmNlabelString, XmRString,
615 this->title, strlen(this->title)+1,
616 XmNalignment, XmALIGNMENT_BEGINNING,
617 NULL);
618 }
619 return this->o_form;
620 } // buildOrderlyWidget()
621
622 // *************************************************************************
623
624 /*!
625 */
626
627 void
slider_cb(Widget widget,XtPointer closure,XtPointer call_data)628 SoXtSlider::slider_cb(
629 Widget widget,
630 XtPointer closure,
631 XtPointer call_data)
632 {
633 assert(closure != NULL);
634 SoXtSlider * slider = (SoXtSlider *) closure;
635 XmScaleCallbackStruct * data = (XmScaleCallbackStruct *) call_data;
636 float previous = slider->current;
637 slider->current = slider->minimum +
638 (slider->maximum - slider->minimum) / 999 * (float) data->value;
639 slider->current = SoXtMax(slider->current, slider->minimum);
640 slider->current = SoXtMin(slider->current, slider->maximum);
641 char text[16];
642
643 sprintf(text, "%.2g", slider->current);
644 const int pos = strlen(text);
645 XmTextSetString(slider->s_value, text);
646 XmTextSetString(slider->r_value, text);
647 XmTextSetString(slider->f_value, text);
648 XmTextSetString(slider->o_value, text);
649 XmTextSetCursorPosition(slider->s_value, pos);
650 XmTextSetCursorPosition(slider->r_value, pos);
651 XmTextSetCursorPosition(slider->f_value, pos);
652 XmTextSetCursorPosition(slider->o_value, pos);
653 XmScaleSetValue(slider->s_slider, data->value);
654 XmScaleSetValue(slider->r_slider, data->value);
655 XmScaleSetValue(slider->f_slider, data->value);
656 XmScaleSetValue(slider->o_slider, data->value);
657
658 if (previous != slider->current)
659 slider->invokeCallbacks();
660 } // slider_cb()
661
662 /*!
663 */
664
665 void
value_cb(Widget widget,XtPointer closure,XtPointer call_data)666 SoXtSlider::value_cb(
667 Widget widget,
668 XtPointer closure,
669 XtPointer call_data)
670 {
671 assert(closure != NULL);
672 SoXtSlider * slider = (SoXtSlider *) closure;
673
674 float previous = slider->current;
675 slider->current = atof(XmTextGetString(widget));
676 slider->current = SoXtMax(slider->current, slider->minimum);
677 slider->current = SoXtMin(slider->current, slider->maximum);
678
679 char text[16];
680 sprintf(text, "%.2g", slider->current);
681 const int cpos = strlen(text);
682 const int pos = (int) ((slider->current - slider->minimum) /
683 (slider->maximum - slider->minimum) * 999.0f);
684
685 XmTextSetString(slider->s_value, text);
686 XmTextSetString(slider->r_value, text);
687 XmTextSetString(slider->f_value, text);
688 XmTextSetString(slider->o_value, text);
689 XmTextSetCursorPosition(slider->s_value, cpos);
690 XmTextSetCursorPosition(slider->r_value, cpos);
691 XmTextSetCursorPosition(slider->f_value, cpos);
692 XmTextSetCursorPosition(slider->o_value, cpos);
693 XmScaleSetValue(slider->s_slider, pos);
694 XmScaleSetValue(slider->r_slider, pos);
695 XmScaleSetValue(slider->f_slider, pos);
696 XmScaleSetValue(slider->o_slider, pos);
697
698 if (previous != slider->current)
699 slider->invokeCallbacks();
700 } // value_cb()
701
702 /*!
703 */
704
705 void
min_cb(Widget widget,XtPointer closure,XtPointer call_data)706 SoXtSlider::min_cb(
707 Widget widget,
708 XtPointer closure,
709 XtPointer call_data)
710 {
711 assert(closure != NULL);
712 SoXtSlider * slider = (SoXtSlider *) closure;
713 slider->minimum = slider->current;
714 char text[16];
715 sprintf(text, "%.2g", slider->minimum);
716 const int cpos = strlen(text);
717
718 XmTextSetString(slider->r_minValue, text);
719 XmTextSetString(slider->f_minValue, text);
720 XmTextSetCursorPosition(slider->r_minValue, cpos);
721 XmTextSetCursorPosition(slider->f_minValue, cpos);
722 XmScaleSetValue(slider->r_slider, 0);
723 XmScaleSetValue(slider->f_slider, 0);
724 } // min_cb()
725
726 /*!
727 */
728
729 void
min_value_cb(Widget widget,XtPointer closure,XtPointer call_data)730 SoXtSlider::min_value_cb(
731 Widget widget,
732 XtPointer closure,
733 XtPointer call_data)
734 {
735 assert(closure != NULL);
736 SoXtSlider * slider = (SoXtSlider *) closure;
737 float previous = slider->current;
738 float prevmax = slider->maximum;
739 slider->minimum = atof(XmTextGetString(widget));
740 slider->maximum = SoXtMax(slider->maximum, slider->minimum);
741 slider->current = SoXtMax(slider->current, slider->minimum);
742
743 #if SOXT_DEBUG && 0
744 SoDebugError::postInfo("SoXtSlider::min_value_cb", "[invoked]");
745 #endif // SOXT_DEBUG
746
747 char text[16];
748 sprintf(text, "%.2g", slider->minimum);
749 int cpos = strlen(text);
750 int pos = 0;
751 if (slider->minimum != slider->maximum)
752 pos = (int) ((slider->current - slider->minimum) /
753 (slider->maximum - slider->minimum) * 999.0f);
754
755 XmTextSetString(slider->r_minValue, text);
756 XmTextSetString(slider->f_minValue, text);
757 XmTextSetCursorPosition(slider->r_minValue, cpos);
758 XmTextSetCursorPosition(slider->f_minValue, cpos);
759
760 if (prevmax != slider->maximum) {
761 sprintf(text, "%.2g", slider->maximum);
762 cpos = strlen(text);
763 XmTextSetString(slider->r_maxValue, text);
764 XmTextSetString(slider->f_maxValue, text);
765 XmTextSetCursorPosition(slider->r_maxValue, cpos);
766 XmTextSetCursorPosition(slider->f_maxValue, cpos);
767 }
768
769 XmScaleSetValue(slider->s_slider, pos);
770 XmScaleSetValue(slider->r_slider, pos);
771 XmScaleSetValue(slider->f_slider, pos);
772 XmScaleSetValue(slider->o_slider, pos);
773
774 if (previous != slider->current) {
775 sprintf(text, "%.2g", slider->current);
776 cpos = strlen(text);
777 XmTextSetString(slider->s_value, text);
778 XmTextSetString(slider->r_value, text);
779 XmTextSetString(slider->f_value, text);
780 XmTextSetString(slider->o_value, text);
781 XmTextSetCursorPosition(slider->s_value, cpos);
782 XmTextSetCursorPosition(slider->r_value, cpos);
783 XmTextSetCursorPosition(slider->f_value, cpos);
784 XmTextSetCursorPosition(slider->o_value, cpos);
785 }
786 if (previous != slider->current)
787 slider->invokeCallbacks();
788 } // min_value_cb()
789
790 /*!
791 */
792
793 void
max_cb(Widget widget,XtPointer closure,XtPointer call_data)794 SoXtSlider::max_cb(
795 Widget widget,
796 XtPointer closure,
797 XtPointer call_data)
798 {
799 assert(closure != NULL);
800 SoXtSlider * slider = (SoXtSlider *) closure;
801 slider->maximum = slider->current;
802 char text[16];
803 sprintf(text, "%.2g", slider->maximum);
804 const int cpos = strlen(text);
805 int pos = 999;
806 if (slider->minimum == slider->maximum)
807 pos = 0;
808
809 XmTextSetString(slider->r_maxValue, text);
810 XmTextSetString(slider->f_maxValue, text);
811 XmTextSetCursorPosition(slider->r_maxValue, cpos);
812 XmTextSetCursorPosition(slider->f_maxValue, cpos);
813 XmScaleSetValue(slider->r_slider, pos);
814 XmScaleSetValue(slider->f_slider, pos);
815 } // max_cb()
816
817 /*!
818 */
819
820 void
max_value_cb(Widget widget,XtPointer closure,XtPointer call_data)821 SoXtSlider::max_value_cb(
822 Widget widget,
823 XtPointer closure,
824 XtPointer call_data)
825 {
826 assert(closure != NULL);
827 SoXtSlider * slider = (SoXtSlider *) closure;
828 float previous = slider->current;
829 float prevmin = slider->minimum;
830 slider->maximum = atof(XmTextGetString(widget));
831 slider->minimum = SoXtMin(slider->minimum, slider->maximum);
832 slider->current = SoXtMin(slider->current, slider->maximum);
833
834 #if SOXT_DEBUG && 0
835 SoDebugError::postInfo("SoXtSlider::max_value_cb", "[invoked]");
836 #endif // SOXT_DEBUG
837
838 char text[16];
839 sprintf(text, "%.2g", slider->maximum);
840 int cpos = strlen(text);
841 int pos = 0;
842 if (slider->minimum != slider->maximum)
843 pos = (int) ((slider->current - slider->minimum) /
844 (slider->maximum - slider->minimum) * 999.0f);
845
846 XmTextSetString(slider->r_maxValue, text);
847 XmTextSetString(slider->f_maxValue, text);
848 XmTextSetCursorPosition(slider->r_maxValue, cpos);
849 XmTextSetCursorPosition(slider->f_maxValue, cpos);
850
851 if (prevmin != slider->minimum) {
852 sprintf(text, "%.2g", slider->minimum);
853 cpos = strlen(text);
854 XmTextSetString(slider->r_minValue, text);
855 XmTextSetString(slider->f_minValue, text);
856 XmTextSetCursorPosition(slider->r_minValue, cpos);
857 XmTextSetCursorPosition(slider->f_minValue, cpos);
858 }
859
860 XmScaleSetValue(slider->s_slider, pos);
861 XmScaleSetValue(slider->r_slider, pos);
862 XmScaleSetValue(slider->f_slider, pos);
863 XmScaleSetValue(slider->o_slider, pos);
864
865 if (previous != slider->current) {
866 sprintf(text, "%.2g", slider->current);
867 cpos = strlen(text);
868 XmTextSetString(slider->s_value, text);
869 XmTextSetString(slider->r_value, text);
870 XmTextSetString(slider->f_value, text);
871 XmTextSetString(slider->o_value, text);
872 XmTextSetCursorPosition(slider->s_value, cpos);
873 XmTextSetCursorPosition(slider->r_value, cpos);
874 XmTextSetCursorPosition(slider->f_value, cpos);
875 XmTextSetCursorPosition(slider->o_value, cpos);
876 }
877 if (previous != slider->current)
878 slider->invokeCallbacks();
879 } // max_value_cb()
880
881 // *************************************************************************
882
883