SUMO - Simulation of Urban MObility
FXRealSpinDial.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 //
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2004-2017 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 /********************************************************************************
25 * *
26 * R e a l - V a l u e d S p i n n e r / D i a l W i d g e t *
27 * *
28 *********************************************************************************
29 * Copyright (C) 2004 by Bill Baxter. All Rights Reserved. *
30 *********************************************************************************
31 * This library is free software; you can redistribute it and/or *
32 * modify it under the terms of the GNU Lesser General Public *
33 * License as published by the Free Software Foundation; either *
34 * version 2.1 of the License, or (at your option) any later version. *
35 * *
36 * This library is distributed in the hope that it will be useful, *
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
39 * Lesser General Public License for more details. *
40 * *
41 * You should have received a copy of the GNU Lesser General Public *
42 * License along with this library; if not, write to the Free Software *
43 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
44 *********************************************************************************
45 * $Id: FXRealSpinDial.cpp 23529 2017-03-18 10:22:36Z behrisch $ *
46 ********************************************************************************/
47 
48 /* =========================================================================
49  * included modules
50  * ======================================================================= */
51 #ifdef _MSC_VER
52 #include <windows_config.h>
53 #else
54 #include <config.h>
55 #endif
56 
57 #include <fx.h>
58 #include "xincs.h"
59 #include "fxver.h"
60 #include "fxdefs.h"
61 #include "fxkeys.h"
62 #include "FXStream.h"
63 #include "FXString.h"
64 #include "FXSize.h"
65 #include "FXPoint.h"
66 #include "FXRectangle.h"
67 #include "FXRegistry.h"
68 #include "FXAccelTable.h"
69 #include "FXApp.h"
70 #include "FXLabel.h"
71 #include "FXTextField.h"
72 #include "FXDial.h"
73 #include "FXRealSpinDial.h"
74 
75 #include <float.h>
76 
77 /*
78  Notes:
79  - Based originally on Lyle's FXSpinner.
80  - Can use with spin buttons, dial, or both, and with or without text
81  - Three increment levels, fine, normal, and coarse. Access different modes
82  with CONTROL key (fine control) and SHIFT key (coarse mode). Modifiers
83  affect all of up/down keys, mousewheel, dial and spinbuttons.
84  - Can specify display format for text either as a precision,showExponent pair
85  or an sprintf format string. (String format can include extra text like '$'!)
86  - Wheel mouse increment/decrement in even multiples of fine/norm/coarse scales.
87  (Key modifers sometimes require mouse motion to kick in because FOX doesn't
88  have a [public] way to query the key state asynchronously. Hacked extern to
89  FOX's internal WIN32 function for querying this, so it works on Win32)
90  - Dial warps the pointer at the edge of the screen so you don't run out of
91  screen real estate.
92 */
93 #define DIALINCR 160
94 #define DIALMULT 40
95 #define DIALWIDTH 12
96 #define BUTTONWIDTH 12
97 #define GAPWIDTH 1
98 
99 #define INTMAX 2147483647
100 #define INTMIN (-INTMAX-1)
101 
102 #define SPINDIAL_MASK (SPINDIAL_CYCLIC|SPINDIAL_NOTEXT|SPINDIAL_NOBUTTONS|SPINDIAL_NODIAL|SPINDIAL_NOMAX|SPINDIAL_NOMIN|SPINDIAL_LOG)
103 
104 using namespace FX;
105 
106 /*******************************************************************************/
107 /* Custom FXDial subclass */
108 /*******************************************************************************/
109 namespace FX {
110 class FXRealSpinDialDial : public FXDial {
111  FXDECLARE(FXRealSpinDialDial)
112 protected:
114 private:
117 public:
118  //long onDefault(FXObject*,FXSelector,void* );
119  long onKey(FXObject*, FXSelector, void*);
120  long onButtonPress(FXObject*, FXSelector, void*);
121  long onButtonRelease(FXObject*, FXSelector, void*);
122  long onRightButtonPress(FXObject*, FXSelector, void*);
123  long onRightButtonRelease(FXObject*, FXSelector, void*);
124  long onMotion(FXObject*, FXSelector, void*);
125  long onAuto(FXObject*, FXSelector, void*);
126  enum {
127  ID_AUTOSPIN = FXDial::ID_LAST,
129  };
130 public:
131 
133  FXRealSpinDialDial(FXComposite* p, FXObject* tgt = NULL, FXSelector sel = 0, FXuint opts = DIAL_NORMAL,
134  FXint x = 0, FXint y = 0, FXint w = 0, FXint h = 0,
135  FXint pl = DEFAULT_PAD, FXint pr = DEFAULT_PAD, FXint pt = DEFAULT_PAD, FXint pb = DEFAULT_PAD):
136  FXDial(p, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb) {}
137 
138 };
139 
140 FXDEFMAP(FXRealSpinDialDial) FXSpinDialMap[] = {
141  FXMAPFUNC(SEL_KEYPRESS, 0, FXRealSpinDialDial::onKey),
142  FXMAPFUNC(SEL_KEYRELEASE, 0, FXRealSpinDialDial::onKey),
143  FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, FXRealSpinDialDial::onButtonPress),
144  FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, 0, FXRealSpinDialDial::onRightButtonRelease),
145  FXMAPFUNC(SEL_RIGHTBUTTONPRESS, 0, FXRealSpinDialDial::onRightButtonPress),
146  FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, FXRealSpinDialDial::onButtonRelease),
147  FXMAPFUNC(SEL_MOTION, 0, FXRealSpinDialDial::onMotion),
148 
150 
151  //FXMAPFUNC(SEL_KEYPRESS,0, FXRealSpinDialDial::onKeyPress),
152  //FXMAPFUNC(SEL_KEYRELEASE,0,FXRealSpinDialDial::onKeyRelease),
153 };
154 FXIMPLEMENT(FXRealSpinDialDial, FXDial, FXSpinDialMap, ARRAYNUMBER(FXSpinDialMap))
155 //FXIMPLEMENT(FXRealSpinDialDial,FXDial,0,0)
156 
157 //long FXRealSpinDialDial::onDefault(FXObject*o,FXSelector s,void*p )
158 //{
159 // printf("DEFAULT!\n");
160 // if (target) return target->handle(o,s,p);
161 // return 0;
162 //}
163 long FXRealSpinDialDial::onKey(FXObject* o, FXSelector s, void* p) {
164  if (target) {
165  return target->handle(o, s, p);
166  }
167  return 0;
168 }
169 long FXRealSpinDialDial::onButtonPress(FXObject* o, FXSelector s, void* p) {
170  grabKeyboard();
171  return FXDial::onLeftBtnPress(o, s, p);
172 }
173 long FXRealSpinDialDial::onButtonRelease(FXObject* o, FXSelector s, void* p) {
174  ungrabKeyboard();
175  return FXDial::onLeftBtnRelease(o, s, p);
176 }
177 long FXRealSpinDialDial::onRightButtonPress(FXObject* /*o*/, FXSelector /*s*/, void* p) {
178  if (isEnabled()) {
179  grab();
180  grabKeyboard();
181  //if(target && target->handle(this,FXSEL(SEL_RIGHTBUTTONPRESS,message),ptr)) return 1;
182  FXEvent* event = (FXEvent*)p;
183  if (options & DIAL_HORIZONTAL) {
184  dragpoint = event->win_x;
185  } else {
186  dragpoint = event->win_y;
187  }
188  getApp()->addTimeout(this, ID_AUTOSPIN, getApp()->getScrollSpeed());
189  }
190  return 1;
191 }
192 long FXRealSpinDialDial::onRightButtonRelease(FXObject* /*o*/, FXSelector /*s*/, void* /*p*/) {
193  ungrab();
194  ungrabKeyboard();
195  getApp()->removeTimeout(this, ID_AUTOSPIN);
196  if (isEnabled()) {
197  //if(target && target->handle(this,FXSEL(SEL_RIGHTBUTTONRELEASE,message),p)) return 1;
198  }
199  return 1;
200 
201 }
202 long FXRealSpinDialDial::onAuto(FXObject* /*o*/, FXSelector /*s*/, void* /*p*/) {
203  getApp()->addTimeout(this, ID_AUTOSPIN, getApp()->getScrollSpeed());
204  setValue(getValue() + int((dragpoint - dragpos) / float(5)));
205  int v = getValue();
206  if (target) {
207  target->handle(this, FXSEL(SEL_CHANGED, message), &v);
208  }
209  return 1;
210 }
211 
212 long FXRealSpinDialDial::onMotion(FXObject* o, FXSelector s, void* p) {
213  if (!isEnabled()) {
214  return 0;
215  }
216  if (target && target->handle(this, FXSEL(SEL_MOTION, message), p)) {
217  return 1;
218  }
219 
220  FXbool bJump = FALSE;
221  FXEvent* e = (FXEvent*)p;
222  if (!(flags & FLAG_PRESSED)) { // not doing clickdrag
223  dragpos = e->win_y;
224  }
225  FXWindow* rootWin = getApp()->getRootWindow();
226  FXint x = e->root_x, y = e->root_y;
227  if (e->root_x >= rootWin->getWidth() - 1) {
228  x -= 40;
229  dragpoint -= 40;
230  bJump = TRUE;
231  } else if (e->root_x <= 10) {
232  x += 40;
233  dragpoint += 40;
234  bJump = TRUE;
235  }
236  if (e->root_y >= rootWin->getHeight() - 1) {
237  y -= 40;
238  dragpoint -= 40;
239  bJump = TRUE;
240  } else if (e->root_y <= 10) {
241  y += 40;
242  dragpoint += 40;
243  bJump = TRUE;
244  }
245  if (bJump) {
246  rootWin->setCursorPosition(x, y);
247  return 1;
248  } else {
249  return FXDial::onMotion(o, s, p);
250  }
251 }
252 
253 }
254 
255 /*******************************************************************************/
256 /* Custom FXArrowButton subclass */
257 /*******************************************************************************/
258 namespace FX {
259 class FXRealSpinDialBtn : public FXArrowButton {
260  FXDECLARE(FXRealSpinDialBtn)
261 protected:
263 private:
266 public:
267  //long onDefault(FXObject*,FXSelector,void* );
268  long onKey(FXObject*, FXSelector, void*);
269  long onButtonPress(FXObject*, FXSelector, void*);
270  long onButtonRelease(FXObject*, FXSelector, void*);
271  enum {
272  ID_AUTOSPIN = FXDial::ID_LAST,
274  };
275 public:
276 
278  FXRealSpinDialBtn(FXComposite* p, FXObject* tgt = NULL, FXSelector sel = 0,
279  FXuint opts = ARROW_NORMAL,
280  FXint x = 0, FXint y = 0, FXint w = 0, FXint h = 0,
281  FXint pl = DEFAULT_PAD, FXint pr = DEFAULT_PAD, FXint pt = DEFAULT_PAD, FXint pb = DEFAULT_PAD):
282  FXArrowButton(p, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb) {}
283 
284 };
285 
286 FXDEFMAP(FXRealSpinDialBtn) FXSpinDialBtnMap[] = {
287  FXMAPFUNC(SEL_KEYPRESS, 0, FXRealSpinDialBtn::onKey),
288  FXMAPFUNC(SEL_KEYRELEASE, 0, FXRealSpinDialBtn::onKey),
289  FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, FXRealSpinDialBtn::onButtonPress),
290  FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, FXRealSpinDialBtn::onButtonRelease),
291 
292 
293  //FXMAPFUNC(SEL_KEYPRESS,0, FXRealSpinDialBtn::onKeyPress),
294  //FXMAPFUNC(SEL_KEYRELEASE,0,FXRealSpinDialBtn::onKeyRelease),
295 };
296 FXIMPLEMENT(FXRealSpinDialBtn, FXArrowButton, FXSpinDialBtnMap, ARRAYNUMBER(FXSpinDialBtnMap))
297 //FXIMPLEMENT(FXRealSpinDialBtn,FXDial,0,0)
298 
299 //long FXRealSpinDialBtn::onDefault(FXObject*o,FXSelector s,void*p )
300 //{
301 // printf("DEFAULT!\n");
302 // if (target) return target->handle(o,s,p);
303 // return 0;
304 //}
305 long FXRealSpinDialBtn::onKey(FXObject* o, FXSelector s, void* p) {
306  if (target) {
307  return target->handle(o, s, p);
308  }
309  return 0;
310 }
311 long FXRealSpinDialBtn::onButtonPress(FXObject* o, FXSelector s, void* p) {
312  grabKeyboard();
313  return FXArrowButton::onLeftBtnPress(o, s, p);
314 }
315 long FXRealSpinDialBtn::onButtonRelease(FXObject* o, FXSelector s, void* p) {
316  ungrabKeyboard();
317  return FXArrowButton::onLeftBtnRelease(o, s, p);
318 }
319 
320 
321 }
322 
323 
324 /*******************************************************************************/
325 /* FXTextField subclass */
326 /*******************************************************************************/
327 
328 namespace FX {
329 class FXRealSpinDialText : public FXTextField {
330  FXDECLARE(FXRealSpinDialText)
331 protected:
333 private:
336 public:
337  long onCmdSetRealValue(FXObject*, FXSelector, void*);
338  long onMotion(FXObject*, FXSelector, void*);
339  enum {
340  ID_LAST = FXTextField::ID_LAST
341  };
342  enum {
343  FLAG_FMTSTRING = 0x1
344  };
345 public:
346 
348  FXRealSpinDialText(FXComposite* p, FXint ncols, FXObject* tgt = NULL, FXSelector sel = 0,
349  FXuint opts = TEXTFIELD_NORMAL,
350  FXint x = 0, FXint y = 0, FXint w = 0, FXint h = 0, FXint
351  pl = DEFAULT_PAD, FXint pr = DEFAULT_PAD, FXint pt = DEFAULT_PAD, FXint pb = DEFAULT_PAD
352  ) :
353  FXTextField(p, ncols, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb),
354  precision(3),
355  exponent(FALSE),
356  flags(0) {}
357 
358  void setNumberFormat(FXint prec, FXbool bExp = FALSE) {
359  precision = prec;
360  exponent = bExp;
361  flags &= ~FLAG_FMTSTRING;
362  }
363  FXint getNumberFormatPrecision() const {
364  return precision;
365  }
366  FXbool getNumberFormatExponent() const {
367  return exponent;
368  }
369  void setFormatString(const FXchar* fmt) {
370  fmtString = fmt;
371  flags |= FLAG_FMTSTRING;
372  }
373  FXString getNumberFormatString() const {
374  return fmtString;
375  }
376 
377 protected:
378  FXint precision;
379  FXbool exponent;
380  FXString fmtString;
381  FXuint flags;
382 };
383 
384 FXDEFMAP(FXRealSpinDialText) FXSpinDialTextMap[] = {
385  FXMAPFUNC(SEL_MOTION, 0, FXRealSpinDialText::onMotion),
386  FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETREALVALUE, FXRealSpinDialText::onCmdSetRealValue),
387 };
388 FXIMPLEMENT(FXRealSpinDialText, FXTextField, FXSpinDialTextMap, ARRAYNUMBER(FXSpinDialTextMap))
389 
390 long FXRealSpinDialText::onMotion(FXObject* o, FXSelector s, void* ptr) {
391  // Forward motion events so we can monitor key state. We don't get the modifier
392  // keys themselves if we aren't focused, so this seems the best we can do.
393  if (!isEnabled()) {
394  return 0;
395  }
396  if (target && target->handle(this, FXSEL(SEL_MOTION, message), ptr)) {
397  return 1;
398  }
399  return FXTextField::onMotion(o, s, ptr);
400 }
401 long FXRealSpinDialText::onCmdSetRealValue(FXObject* /*o*/, FXSelector /*s*/, void* ptr) {
402  // setText(FXStringVal(*((FXdouble*)ptr)));
403  if (flags & FLAG_FMTSTRING) {
404  setText(FXStringFormat(fmtString.text(), *((FXdouble*)ptr)));
405  } else {
406  setText(FXStringVal(*((FXdouble*)ptr), precision, exponent));
407  }
408  return 1;
409 }
410 
411 }
412 
413 /*******************************************************************************/
414 /* FXRealSpinDial */
415 /*******************************************************************************/
416 
417 namespace FX {
418 
419 // Message map
420 FXDEFMAP(FXRealSpinDial) FXRealSpinDialMap[] = {
421  FXMAPFUNC(SEL_KEYPRESS, 0, FXRealSpinDial::onKeyPress),
422  FXMAPFUNC(SEL_KEYRELEASE, 0, FXRealSpinDial::onKeyRelease),
423  FXMAPFUNC(SEL_MOTION, 0, FXRealSpinDial::onMotion),
424  FXMAPFUNC(SEL_MOTION, FXRealSpinDial::ID_ENTRY, FXRealSpinDial::onMotion),
425  FXMAPFUNC(SEL_MOTION, FXRealSpinDial::ID_DIAL, FXRealSpinDial::onMotion),
427  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_ENTRY, FXRealSpinDial::onCmdEntry),
428  FXMAPFUNC(SEL_CHANGED, FXRealSpinDial::ID_ENTRY, FXRealSpinDial::onChgEntry),
429  FXMAPFUNC(SEL_UPDATE, FXRealSpinDial::ID_DIAL, FXRealSpinDial::onUpdDial),
430  FXMAPFUNC(SEL_CHANGED, FXRealSpinDial::ID_DIAL, FXRealSpinDial::onChgDial),
431  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_DIAL, FXRealSpinDial::onChgDial),
432  FXMAPFUNC(SEL_MOUSEWHEEL, FXRealSpinDial::ID_ENTRY, FXRealSpinDial::onMouseWheel),
433  FXMAPFUNC(SEL_MOUSEWHEEL, FXRealSpinDial::ID_DIAL, FXRealSpinDial::onMouseWheel),
436  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_SETVALUE, FXRealSpinDial::onCmdSetValue),
437  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_SETINTVALUE, FXRealSpinDial::onCmdSetIntValue),
438  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_GETINTVALUE, FXRealSpinDial::onCmdGetIntValue),
439  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_SETINTRANGE, FXRealSpinDial::onCmdSetIntRange),
440  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_GETINTRANGE, FXRealSpinDial::onCmdGetIntRange),
441  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_SETREALVALUE, FXRealSpinDial::onCmdSetRealValue),
442  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_GETREALVALUE, FXRealSpinDial::onCmdGetRealValue),
443  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_SETREALRANGE, FXRealSpinDial::onCmdSetRealRange),
444  FXMAPFUNC(SEL_COMMAND, FXRealSpinDial::ID_GETREALRANGE, FXRealSpinDial::onCmdGetRealRange),
449 };
450 
451 
452 // Object implementation
453 FXIMPLEMENT(FXRealSpinDial, FXPacker, FXRealSpinDialMap, ARRAYNUMBER(FXRealSpinDialMap))
454 
455 
456 // Construct spinner out of two buttons and a text field
458  flags = (flags | FLAG_ENABLED | FLAG_SHOWN) & ~FLAG_UPDATE;
459  textField = 0;
460  dial = 0;
461  upButton = 0;
462  downButton = 0;
463  range[0] = -DBL_MAX;
464  range[1] = DBL_MAX;
465  incr[0] = 0.1;
466  incr[1] = 1.0;
467  incr[2] = 10;
468  pos = 1;
469  dialpos = 0;
470 }
471 
472 
473 // Construct spinner out of dial and a text field
474 FXRealSpinDial::FXRealSpinDial(FXComposite* p, FXint cols, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h, FXint pl, FXint pr, FXint pt, FXint pb):
475  FXPacker(p, opts & ~(FRAME_RIDGE), x, y, w, h, 0, 0, 0, 0, 0, 0) {
476  flags = (flags | FLAG_ENABLED | FLAG_SHOWN) & ~FLAG_UPDATE;
477  target = tgt;
478  message = sel;
479  dial = new FXRealSpinDialDial(this, this, ID_DIAL, DIAL_VERTICAL, 0, 0, 0, 0, 0, 0, 0, 0);
480  dial->setNotchSpacing(450);
481  dial->setRevolutionIncrement(DIALINCR);
482  upButton = new FXRealSpinDialBtn(this, this, ID_INCREMENT, FRAME_RAISED | FRAME_THICK | ARROW_UP | ARROW_REPEAT, 0, 0, 0, 0, 0, 0, 0, 0);
483  downButton = new FXRealSpinDialBtn(this, this, ID_DECREMENT, FRAME_RAISED | FRAME_THICK | ARROW_DOWN | ARROW_REPEAT, 0, 0, 0, 0, 0, 0, 0, 0);
484  // flag SPINDIAL_NOMAX collides with flag TEXTFIELD_PASSWORD
485  // flag SPINDIAL_NOMIN collides with flag TEXTFIELD_INTEGER
486  textField = new FXRealSpinDialText(this, cols, this, ID_ENTRY, (opts & ~(SPINDIAL_NOMAX | SPINDIAL_NOMIN)) | TEXTFIELD_REAL | JUSTIFY_RIGHT, 0, 0, 0, 0, pl, pr, pt, pb);
487  textField->setText("0");
488  range[0] = (options & SPINDIAL_NOMIN) ? -DBL_MAX : 0;
489  range[1] = (options & SPINDIAL_NOMAX) ? DBL_MAX : 100;
490  dial->setRange(INTMIN, INTMAX);
491  dialpos = dial->getValue();
492  incr[0] = 0.1;
493  incr[1] = 1.0;
494  incr[2] = 10;
495  pos = 0;
496  keystate = 0;
497 }
498 
499 
500 // Get default width
502  FXint tw = 0;
503  if (!(options & SPINDIAL_NOTEXT)) {
504  tw = textField->getDefaultWidth();
505  }
506  return tw + DIALWIDTH + GAPWIDTH + (border << 1);
507 }
508 
509 
510 // Get default height
512  return textField->getDefaultHeight() + (border << 1);
513 }
514 
515 
516 // Create window
518  FXPacker::create();
519 }
520 
521 
522 // Enable the widget
524  if (!(flags & FLAG_ENABLED)) {
525  FXPacker::enable();
526  textField->enable();
527  dial->enable();
528  }
529 }
530 
531 
532 // Disable the widget
534  if (flags & FLAG_ENABLED) {
535  FXPacker::disable();
536  textField->disable();
537  dial->disable();
538  }
539 }
540 
541 
542 // Recompute layout
544  FXint dialHeight, buttonHeight, textHeight;
545 
546  textHeight = height - 2 * border;
547  dialHeight = textHeight;
548  buttonHeight = textHeight >> 1;
549 
550  FXuint hideOpts = SPINDIAL_NOTEXT | SPINDIAL_NODIAL | SPINDIAL_NOBUTTONS;
551  if ((options & hideOpts) == hideOpts) {
552  flags &= ~FLAG_DIRTY;
553  return; // nothing to layout
554  }
555 
556  FXint right = width - border;
557 
558  if (options & SPINDIAL_NOTEXT) {
559  // Dial takes up the extra space if shown, otherwise spinbuttons
560  if (!(options & SPINDIAL_NODIAL)) {
561  // HAS DIAL
562  int left = border;
563  if (!(options & SPINDIAL_NOBUTTONS)) {
564  FXint bw = BUTTONWIDTH;
565  upButton->position(border, border, bw, buttonHeight);
566  downButton->position(border, height - buttonHeight - border, bw, buttonHeight);
567  left += bw + GAPWIDTH;
568  }
569  dial->position(left, border, right - left, dialHeight);
570  } else {
571  upButton->position(border, border, right - border, buttonHeight);
572  downButton->position(border, height - buttonHeight - border, right - border, buttonHeight);
573  }
574  } else {
575  // dial/buttons are default width, text stretches to fill the rest
576  if (!(options & SPINDIAL_NODIAL)) {
577  FXint w = DIALWIDTH;
578  dial->position(right - w, border, w, dialHeight);
579  right -= w + GAPWIDTH;
580  }
581  if (!(options & SPINDIAL_NOBUTTONS)) {
582  FXint w = BUTTONWIDTH;
583  upButton->position(right - w, border, w, buttonHeight);
584  downButton->position(right - w, height - buttonHeight - border, w, buttonHeight);
585  right -= w + GAPWIDTH;
586  }
587  textField->position(border, border, right - border, textHeight);
588  }
589  flags &= ~FLAG_DIRTY;
590 }
591 
592 
593 // Respond to dial message
594 long FXRealSpinDial::onUpdDial(FXObject* sender, FXSelector, void*) {
595  if (isEnabled() && ((options & SPINDIAL_CYCLIC) || (pos <= range[1]))) {
596  sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
597  } else {
598  sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
599  }
600  return 1;
601 }
602 
603 
604 // Respond to dial message
605 long FXRealSpinDial::onChgDial(FXObject* /*p*/, FXSelector /*sel*/, void* /*ptr*/) {
606  if (!isEnabled()) {
607  return 0;
608  }
609  FXdouble newpos;
610  FXdouble inc;
611  if (FXApp::instance()->getKeyState(CONTROLMASK)) {
612  inc = incr[0];
613  } else if (FXApp::instance()->getKeyState(SHIFTMASK)) {
614  inc = incr[2];
615  } else {
616  inc = incr[1];
617  }
618  FXint dialdelta = dial->getValue() - dialpos;
619  if (options & SPINDIAL_LOG) {
620  newpos = pos * pow(inc , DIALMULT * FXdouble(dialdelta) / DIALINCR);
621  } else {
622  newpos = pos + DIALMULT * inc * (dialdelta) / DIALINCR;
623  }
624  // Now clamp newpos.
625  if (dialdelta > 0) {
626  if (options & SPINDIAL_LOG) {
627  if (options & SPINDIAL_CYCLIC && newpos > range[1]) {
628  FXdouble lr0 = log(range[0]), lr1 = log(range[1]), lnp = log(newpos);
629  newpos = exp(lr0 + fmod(lnp - lr0, lr1 - lr0));
630  }
631  } else {
632  if (options & SPINDIAL_CYCLIC) {
633  newpos = range[0] + fmod(newpos - range[0], range[1] - range[0] + 1);
634  }
635  }
636  } else {
637  if (options & SPINDIAL_LOG) {
638  if (options & SPINDIAL_CYCLIC && newpos < range[0]) {
639  FXdouble lr0 = log(range[0]), lr1 = log(range[1]), lpos = log(pos);
640  FXdouble span = lr1 - lr0;
641  newpos = exp(lr0 + fmod(lpos - lr0 + 1 + (span - inc), span));
642  }
643  } else {
644  if (options & SPINDIAL_CYCLIC) {
645  newpos = range[0] + fmod(pos + (range[1] - range[0] + 1 + (newpos - pos) - range[0]) , range[1] - range[0] + 1);
646  }
647  }
648  }
649  setValue(newpos);
650  if (target) {
651  target->handle(this, FXSEL(SEL_COMMAND, message), (void*)&pos);
652  }
653  dialpos = dial->getValue();
654  return 1;
655 }
656 
657 // Respond to dial message
658 long FXRealSpinDial::onCmdDial(FXObject*, FXSelector /*sel*/, void*) {
659  if (!isEnabled()) {
660  return 0;
661  }
662  // if(target) target->handle(this,FXSEL(SEL_COMMAND,message),(void*)&pos);
663  dialpos = dial->getValue() % DIALINCR;
664  dial->setValue(dialpos);
665  return 1;
666 }
667 
668 
669 // Respond to increment message
670 long FXRealSpinDial::onUpdIncrement(FXObject* sender, FXSelector, void*) {
671  if (isEnabled() && ((options & REALSPIN_CYCLIC) || (pos < range[1]))) {
672  sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
673  } else {
674  sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
675  }
676  return 1;
677 }
678 
679 
680 // Respond to increment message
681 long FXRealSpinDial::onCmdIncrement(FXObject*, FXSelector, void*) {
682  if (!isEnabled()) {
683  return 0;
684  }
685  FXint mode;
686  if (keystate & CONTROLMASK) {
687  mode = SPINDIAL_INC_FINE;
688  } else if (keystate & SHIFTMASK) {
689  mode = SPINDIAL_INC_COARSE;
690  } else {
691  mode = SPINDIAL_INC_NORMAL;
692  }
693  increment(mode);
694  if (target) {
695  target->handle(this, FXSEL(SEL_COMMAND, message), (void*)&pos);
696  }
697  return 1;
698 }
699 
700 
701 // Disable decrement if at low end already
702 long FXRealSpinDial::onUpdDecrement(FXObject* sender, FXSelector, void*) {
703  if (isEnabled() && ((options & REALSPIN_CYCLIC) || (range[0] < pos))) {
704  sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
705  } else {
706  sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
707  }
708  return 1;
709 }
710 
711 
712 // Respond to decrement message
713 long FXRealSpinDial::onCmdDecrement(FXObject*, FXSelector, void*) {
714  if (!isEnabled()) {
715  return 0;
716  }
717  FXint mode;
718  if (keystate & CONTROLMASK) {
719  mode = SPINDIAL_INC_FINE;
720  } else if (keystate & SHIFTMASK) {
721  mode = SPINDIAL_INC_COARSE;
722  } else {
723  mode = SPINDIAL_INC_NORMAL;
724  }
725  decrement(mode);
726  if (target) {
727  target->handle(this, FXSEL(SEL_COMMAND, message), (void*)&pos);
728  }
729  return 1;
730 }
731 
732 
733 
734 // Update from text field
735 long FXRealSpinDial::onUpdEntry(FXObject*, FXSelector, void*) {
736  return target && target->handle(this, FXSEL(SEL_UPDATE, message), NULL);
737 }
738 
739 long FXRealSpinDial::onMouseWheel(FXObject* /*o*/, FXSelector /*s*/, void* p) {
740  FXint mode;
741  keystate = ((FXEvent*)p)->state;
742  if (keystate & CONTROLMASK) {
743  mode = SPINDIAL_INC_FINE;
744  } else if (keystate & SHIFTMASK) {
745  mode = SPINDIAL_INC_COARSE;
746  } else {
747  mode = SPINDIAL_INC_NORMAL;
748  }
749  if (((FXEvent*)p)->code > 0) {
750  increment(mode);
751  } else {
752  decrement(mode);
753  }
754  if (target) {
755  target->handle(this, FXSEL(SEL_COMMAND, message), (void*)&pos);
756  }
757  return 1;
758 }
759 
760 // Text field changed
761 long FXRealSpinDial::onChgEntry(FXObject*, FXSelector, void*) {
762  register FXdouble value = FXDoubleVal(textField->getText());
763  if (value < range[0]) {
764  value = range[0];
765  }
766  if (value > range[1]) {
767  value = range[1];
768  }
769  if (value != pos) {
770  pos = value;
771  if (target) {
772  target->handle(this, FXSEL(SEL_CHANGED, message), (void*)&pos);
773  }
774  }
775  return 1;
776 }
777 
778 
779 // Text field command
780 long FXRealSpinDial::onCmdEntry(FXObject*, FXSelector, void*) {
781  textField->setText(FXStringVal(pos)); // Put back adjusted value
782  if (target) {
783  target->handle(this, FXSEL(SEL_COMMAND, message), (void*)&pos);
784  }
785  return 1;
786 }
787 
788 
789 // Keyboard press
790 long FXRealSpinDial::onKeyPress(FXObject* sender, FXSelector sel, void* ptr) {
791  FXEvent* event = (FXEvent*)ptr;
792  if (!isEnabled()) {
793  return 0;
794  }
795  keystate = event->state;
796  if (target && target->handle(this, FXSEL(SEL_KEYPRESS, message), ptr)) {
797  return 1;
798  }
799  FXint mode;
800  if (keystate & CONTROLMASK) {
801  mode = SPINDIAL_INC_FINE;
802  } else if (keystate & SHIFTMASK) {
803  mode = SPINDIAL_INC_COARSE;
804  } else {
805  mode = SPINDIAL_INC_NORMAL;
806  }
807  switch (event->code) {
808  case KEY_Up:
809  case KEY_KP_Up:
810  increment(mode);
811  if (target) {
812  target->handle(this, FXSEL(SEL_COMMAND, message), (void*)&pos);
813  }
814  return 1;
815  case KEY_Down:
816  case KEY_KP_Down:
817  decrement(mode);
818  if (target) {
819  target->handle(this, FXSEL(SEL_COMMAND, message), (void*)&pos);
820  }
821  return 1;
822  default:
823  return textField->handle(sender, sel, ptr);
824  }
825 }
826 
827 
828 // Keyboard release
829 long FXRealSpinDial::onKeyRelease(FXObject* sender, FXSelector sel, void* ptr) {
830  FXEvent* event = (FXEvent*)ptr;
831  if (!isEnabled()) {
832  return 0;
833  }
834  keystate = event->state;
835  if (target && target->handle(this, FXSEL(SEL_KEYRELEASE, message), ptr)) {
836  return 1;
837  }
838  switch (event->code) {
839  case KEY_Up:
840  case KEY_KP_Up:
841  case KEY_Down:
842  case KEY_KP_Down:
843  return 1;
844  default:
845  return textField->handle(sender, sel, ptr);
846  }
847 }
848 
849 // Mouse motion
850 long FXRealSpinDial::onMotion(FXObject* /*sender*/, FXSelector /*sel*/, void* ptr) {
851  if (!isEnabled()) {
852  return 0;
853  }
854  keystate = ((FXEvent*)ptr)->state;
855  return 0;
856 }
857 
858 // Update value from a message
859 long FXRealSpinDial::onCmdSetValue(FXObject*, FXSelector, void* ptr) {
860  setValue((FXdouble)(size_t)ptr);
861  return 1;
862 }
863 
864 
865 // Update value from a message
866 long FXRealSpinDial::onCmdSetIntValue(FXObject*, FXSelector, void* ptr) {
867  setValue(FXdouble(*((FXint*)ptr)));
868  return 1;
869 }
870 
871 
872 // Obtain value from spinner
873 long FXRealSpinDial::onCmdGetIntValue(FXObject*, FXSelector, void* ptr) {
874  *((FXint*)ptr) = (FXint)getValue();
875  return 1;
876 }
877 
878 
879 // Update range from a message
880 long FXRealSpinDial::onCmdSetIntRange(FXObject*, FXSelector, void* ptr) {
881  FXdouble lo = (FXdouble)((FXint*)ptr)[0];
882  FXdouble hi = (FXdouble)((FXint*)ptr)[1];
883  setRange(lo, hi);
884  return 1;
885 }
886 
887 
888 // Get range with a message
889 long FXRealSpinDial::onCmdGetIntRange(FXObject*, FXSelector, void* ptr) {
890  ((FXdouble*)ptr)[0] = range[0];
891  ((FXdouble*)ptr)[1] = range[1];
892  return 1;
893 }
894 
895 
896 // Update value from a message
897 long FXRealSpinDial::onCmdSetRealValue(FXObject*, FXSelector, void* ptr) {
898  setValue(*((FXdouble*)ptr));
899  return 1;
900 }
901 
902 
903 // Obtain value from spinner
904 long FXRealSpinDial::onCmdGetRealValue(FXObject*, FXSelector, void* ptr) {
905  *((FXdouble*)ptr) = getValue();
906  return 1;
907 }
908 
909 
910 // Update range from a message
911 long FXRealSpinDial::onCmdSetRealRange(FXObject*, FXSelector, void* ptr) {
912  setRange(((FXdouble*)ptr)[0], ((FXdouble*)ptr)[1]);
913  return 1;
914 }
915 
916 
917 // Get range with a message
918 long FXRealSpinDial::onCmdGetRealRange(FXObject*, FXSelector, void* ptr) {
919  getRange(((FXdouble*)ptr)[0], ((FXdouble*)ptr)[1]);
920  return 1;
921 }
922 
923 
924 
925 // Increment spinner
926 void FXRealSpinDial::increment(FXint incMode) {
927  FXdouble inc = incr[incMode + 1];
928  FXdouble newpos;
929  if (range[0] < range[1]) {
930  if (options & SPINDIAL_LOG) {
931  newpos = pos * inc;
932  if (options & SPINDIAL_CYCLIC && newpos > range[1]) {
933  // can have a huge magnitude disparity here, so better to work in log space
934  FXdouble lr0 = log(range[0]), lr1 = log(range[1]), lnp = log(newpos);
935  newpos = exp(lr0 + fmod(lnp - lr0, lr1 - lr0));
936  }
937  } else {
938  newpos = pos + inc;
939  if (options & SPINDIAL_CYCLIC) {
940  newpos = range[0] + fmod(newpos - range[0], range[1] - range[0] + 1);
941  }
942  }
943  setValue(newpos);
944  }
945 }
946 
947 
948 // Decrement spinner
949 void FXRealSpinDial::decrement(FXint incMode) {
950  FXdouble inc = incr[incMode + 1];
951  FXdouble newpos;
952  if (range[0] < range[1]) {
953  if (options & SPINDIAL_LOG) {
954  newpos = pos / inc;
955  if (options & SPINDIAL_CYCLIC && newpos < range[0]) {
956  // can have a huge magnitude disparity here, so better to work in log space
957  FXdouble lr0 = log(range[0]), lr1 = log(range[1]), lpos = log(pos);
958  FXdouble span = lr1 - lr0;
959  newpos = exp(lr0 + fmod(lpos - lr0 + 1 + (span - inc), span));
960  }
961  } else {
962  newpos = pos - inc;
963  if (options & SPINDIAL_CYCLIC) {
964  newpos = range[0] + fmod(pos + (range[1] - range[0] + 1 + (newpos - pos) - range[0]) , range[1] - range[0] + 1);
965  }
966  }
967  setValue(newpos);
968  }
969 }
970 
971 // True if spinner is cyclic
972 FXbool FXRealSpinDial::isCyclic() const {
973  return (options & SPINDIAL_CYCLIC) != 0;
974 }
975 
976 
977 // Set spinner cyclic mode
978 void FXRealSpinDial::setCyclic(FXbool cyclic) {
979  if (cyclic) {
980  options |= SPINDIAL_CYCLIC;
981  } else {
982  options &= ~SPINDIAL_CYCLIC;
983  }
984 }
985 
986 
987 // Set spinner range; this also revalidates the position,
988 void FXRealSpinDial::setRange(FXdouble lo, FXdouble hi) {
989  if (lo > hi) {
990  fxerror("%s::setRange: trying to set negative range.\n", getClassName());
991  }
992  if (range[0] != lo || range[1] != hi) {
993  range[0] = lo;
994  range[1] = hi;
995  setValue(pos);
996  }
997 }
998 
999 
1000 // Set new value
1001 void FXRealSpinDial::setValue(FXdouble value) {
1002  if (value < range[0]) {
1003  value = range[0];
1004  }
1005  if (value > range[1]) {
1006  value = range[1];
1007  }
1008  if (pos != value) {
1009  textField->handle(this, FXSEL(SEL_COMMAND, ID_SETREALVALUE), &value);
1010  pos = value;
1011  }
1012 }
1013 
1014 
1015 // Change value increment
1016 void FXRealSpinDial::setIncrement(FXdouble inc) {
1017  if (inc < 0) {
1018  fxerror("%s::setIncrement: negative or zero increment specified.\n", getClassName());
1019  }
1020  incr[1] = inc;
1021 }
1023  if (inc < 0) {
1024  fxerror("%s::setIncrement: negative or zero increment specified.\n", getClassName());
1025  }
1026  incr[0] = inc;
1027 }
1029  if (inc < 0) {
1030  fxerror("%s::setIncrement: negative or zero increment specified.\n", getClassName());
1031  }
1032  incr[2] = inc;
1033 }
1034 void FXRealSpinDial::setIncrements(FXdouble fine, FXdouble inc, FXdouble coarse) {
1035  if (inc < 0) {
1036  fxerror("%s::setIncrement: negative or zero increment specified.\n", getClassName());
1037  }
1038  incr[0] = fine;
1039  incr[1] = inc;
1040  incr[2] = coarse;
1041 }
1042 
1043 
1044 // True if text supposed to be visible
1046  return textField->shown();
1047 }
1048 
1049 
1050 // Change text visibility
1052  FXuint opts = shown ? (options & ~SPINDIAL_NOTEXT) : (options | SPINDIAL_NOTEXT);
1053  if (options != opts) {
1054  options = opts;
1055  recalc();
1056  }
1057 }
1058 
1059 
1060 // Set the font used in the text field|
1061 void FXRealSpinDial::setFont(FXFont* fnt) {
1062  textField->setFont(fnt);
1063 }
1064 
1065 
1066 // Return the font used in the text field
1067 FXFont* FXRealSpinDial::getFont() const {
1068  return textField->getFont();
1069 }
1070 
1071 
1072 // Set help text
1073 void FXRealSpinDial::setHelpText(const FXString& text) {
1074  textField->setHelpText(text);
1075  dial->setHelpText(text);
1076  upButton->setHelpText(text);
1077  downButton->setHelpText(text);
1078 }
1079 
1080 
1081 // Get help text
1083  return textField->getHelpText();
1084 }
1085 
1086 
1087 // Set tip text
1088 void FXRealSpinDial::setTipText(const FXString& text) {
1089  textField->setTipText(text);
1090  dial->setTipText(text);
1091  upButton->setTipText(text);
1092  downButton->setTipText(text);
1093 }
1094 
1095 
1096 
1097 // Get tip text
1098 FXString FXRealSpinDial::getTipText() const {
1099  return textField->getTipText();
1100 }
1101 
1102 
1103 // Change spinner style
1105  FXuint opts = (options & ~SPINDIAL_MASK) | (style & SPINDIAL_MASK);
1106  if (options != opts) {
1107  if (opts & SPINDIAL_NOMIN) {
1108  range[0] = -DBL_MAX;
1109  }
1110  if (opts & SPINDIAL_NOMAX) {
1111  range[1] = DBL_MAX;
1112  }
1113  options = opts;
1114  recalc();
1115  }
1116 }
1117 
1118 
1119 // Get spinner style
1121  return (options & SPINDIAL_MASK);
1122 }
1123 
1124 
1125 // Allow editing of the text field
1126 void FXRealSpinDial::setEditable(FXbool edit) {
1127  textField->setEditable(edit);
1128 }
1129 
1130 
1131 // Return TRUE if text field is editable
1133  return textField->isEditable();
1134 }
1135 
1136 // Change color of the dial
1137 void FXRealSpinDial::setDialColor(FXColor clr) {
1138  dial->setBackColor(clr);
1139 }
1140 
1141 // Return color of the dial
1143  return dial->getBackColor();
1144 }
1145 
1146 // Change color of the up arrow
1148  upButton->setArrowColor(clr);
1149 }
1150 
1151 // Return color of the up arrow
1153  return upButton->getArrowColor();
1154 }
1155 
1156 // Change color of the down arrow
1158  downButton->setArrowColor(clr);
1159 }
1160 
1161 // Return color of the the down arrow
1163  return downButton->getArrowColor();
1164 }
1165 
1166 
1167 // Change text color
1168 void FXRealSpinDial::setTextColor(FXColor clr) {
1169  textField->setTextColor(clr);
1170 }
1171 
1172 // Return text color
1174  return textField->getTextColor();
1175 }
1176 
1177 // Change selected background color
1179  textField->setSelBackColor(clr);
1180 }
1181 
1182 // Return selected background color
1184  return textField->getSelBackColor();
1185 }
1186 
1187 // Change selected text color
1189  textField->setSelTextColor(clr);
1190 }
1191 
1192 // Return selected text color
1194  return textField->getSelTextColor();
1195 }
1196 
1197 // Changes the cursor color
1199  textField->setCursorColor(clr);
1200 }
1201 
1202 // Return the cursor color
1204  return textField->getCursorColor();
1205 }
1206 
1207 void FXRealSpinDial::setNumberFormat(FXint prec, FXbool bExp) {
1208  textField->setNumberFormat(prec, bExp);
1209 }
1210 
1213 }
1214 
1217 }
1218 
1219 void FXRealSpinDial::setFormatString(const FXchar* fmt) {
1220  textField->setFormatString(fmt);
1221 }
1222 
1224  return textField->getNumberFormatString();
1225 }
1226 
1227 // Save object to stream
1228 void FXRealSpinDial::save(FXStream& store) const {
1229  FXPacker::save(store);
1230  store << textField;
1231  store << dial;
1232  store << upButton;
1233  store << downButton;
1234  store << range[0] << range[1];
1235  store << incr[0] << incr[1] << incr[2];
1236  store << pos;
1237 }
1238 
1239 
1240 // Load object from stream
1241 void FXRealSpinDial::load(FXStream& store) {
1242  FXPacker::load(store);
1243  store >> textField;
1244  store >> dial;
1245  store >> upButton;
1246  store >> downButton;
1247  store >> range[0] >> range[1];
1248  store >> incr[0] >> incr[1] >> incr[2];
1249  store >> pos;
1250 }
1251 
1252 
1253 // Destruct spinner:- trash it!
1255  textField = 0;
1256  dial = 0;
1257  upButton = 0;
1258  downButton = 0;
1259 }
1260 
1261 }
1262 
1263 
1264 void
1266  textField->selectAll();
1267 }
1268 
1269 
1270 
1271 const FXDial&
1273  return *dial;
1274 }
1275 
1276 
long onCmdDecrement(FXObject *, FXSelector, void *)
long onCmdGetIntRange(FXObject *, FXSelector, void *)
long onCmdGetRealRange(FXObject *, FXSelector, void *)
FXRealSpinDialText(FXComposite *p, FXint ncols, FXObject *tgt=NULL, FXSelector sel=0, FXuint opts=TEXTFIELD_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
Construct a text widget.
FXString getHelpText() const
Get the status line help text for this spinner.
FXbool isEditable() const
Return TRUE if text field is editable.
void selectAll()
Mark the text entry as selected.
void setFineIncrement(FXdouble increment)
Change spinner fine adjustment increment (when CTRL key held down)
FXuint getSpinnerStyle() const
Return current spinner style.
FXColor getDialColor() const
Return color of the dial.
long onKey(FXObject *, FXSelector, void *)
FXFont * getFont() const
Get the text font.
FXString getNumberFormatString() const
Return the format string for number display.
long onUpdEntry(FXObject *, FXSelector, void *)
FXRealSpinDialBtn(FXComposite *p, FXObject *tgt=NULL, FXSelector sel=0, FXuint opts=ARROW_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
Construct a dial widget.
FXbool getNumberFormatExponent() const
void setFont(FXFont *fnt)
Set the text font.
void setDialColor(FXColor clr)
Change color of the dial.
virtual FXint getDefaultHeight()
Return default height.
virtual void load(FXStream &store)
Load spinner from a stream.
FXString getTipText() const
Get the tool tip message for this spinner.
#define SPINDIAL_MASK
virtual void setValue(FXdouble value)
Change current value.
long onButtonPress(FXObject *, FXSelector, void *)
long onCmdSetIntRange(FXObject *, FXSelector, void *)
void setNumberFormat(FXint prec, FXbool bExp=FALSE)
void setCoarseIncrement(FXdouble increment)
Change spinner coarse adjustment increment (when SHIFT key held down)
FXArrowButton * downButton
virtual FXint getDefaultWidth()
Return default width.
void setSpinnerStyle(FXuint style)
Change spinner style.
void setCursorColor(FXColor clr)
Changes the cursor color.
#define DIALWIDTH
FXbool isCyclic() const
Return TRUE if in cyclic mode.
#define INTMIN
FXint getNumberFormatPrecision() const
Return the digits of precision used to display numbers.
long onCmdSetValue(FXObject *, FXSelector, void *)
virtual void create()
Create server-side resources.
long onCmdSetRealRange(FXObject *, FXSelector, void *)
void getRange(FXdouble &lo, FXdouble &hi) const
Get the spinner&#39;s current range.
long onKeyPress(FXObject *, FXSelector, void *)
virtual void disable()
Disable spinner.
long onRightButtonRelease(FXObject *, FXSelector, void *)
FXColor getCursorColor() const
Return the cursor color.
FXRealSpinDialDial & operator=(const FXRealSpinDialDial &)
#define DIALINCR
FXRealSpinDialDial(FXComposite *p, FXObject *tgt=NULL, FXSelector sel=0, FXuint opts=DIAL_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
Construct a dial widget.
void setEditable(FXbool edit=TRUE)
Allow editing of the text field.
void setTextColor(FXColor clr)
Change text color.
long onButtonRelease(FXObject *, FXSelector, void *)
void decrement(FXint incMode=SPINDIAL_INC_NORMAL)
Decrement spinner.
const FXDial & getDial() const
void setSelBackColor(FXColor clr)
Change selected background color.
FXint getNumberFormatPrecision() const
void setRange(FXdouble lo, FXdouble hi)
Change the spinner&#39;s range.
long onCmdEntry(FXObject *, FXSelector, void *)
long onCmdSetIntValue(FXObject *, FXSelector, void *)
long onMotion(FXObject *, FXSelector, void *)
long onButtonPress(FXObject *, FXSelector, void *)
FXColor getSelTextColor() const
Return selected text color.
FXArrowButton * upButton
FXColor getTextColor() const
Return text color.
long onUpdDial(FXObject *, FXSelector, void *)
void setFormatString(const FXchar *fmt)
void setTipText(const FXString &text)
Set the tool tip message for this spinner.
long onButtonRelease(FXObject *, FXSelector, void *)
virtual ~FXRealSpinDial()
Destructor.
FXColor getSelBackColor() const
Return selected background color.
void setCyclic(FXbool cyclic)
Set to cyclic mode, i.e. wrap around at maximum/minimum.
long onKeyRelease(FXObject *, FXSelector, void *)
long onUpdDecrement(FXObject *, FXSelector, void *)
#define GAPWIDTH
#define BUTTONWIDTH
long onCmdDial(FXObject *, FXSelector, void *)
void setFormatString(const FXchar *fmt)
long onCmdGetRealValue(FXObject *, FXSelector, void *)
void setTextVisible(FXbool shown)
Set text visible flag.
FXbool getNumberFormatExponent() const
Return whether the exponent is used in number display.
void setNumberFormat(FXint prec, FXbool bExp=FALSE)
long onKey(FXObject *, FXSelector, void *)
long onCmdIncrement(FXObject *, FXSelector, void *)
long onMotion(FXObject *, FXSelector, void *)
FXString getNumberFormatString() const
void increment(FXint incMode=SPINDIAL_INC_NORMAL)
Increment spinner.
FXdouble getValue() const
Return current value.
long onChgEntry(FXObject *, FXSelector, void *)
long onCmdSetRealValue(FXObject *, FXSelector, void *)
void setHelpText(const FXString &text)
Set the status line help text for this spinner.
void setDownArrowColor(FXColor clr)
Change color of the down arrow.
long onMotion(FXObject *, FXSelector, void *)
#define INTMAX
void setIncrement(FXdouble increment)
Change spinner increment.
long onCmdGetIntValue(FXObject *, FXSelector, void *)
long onUpdIncrement(FXObject *, FXSelector, void *)
void setIncrements(FXdouble fine, FXdouble norm, FXdouble coarse)
Change all spinner increment.
FXDEFMAP(FXRealSpinDialDial) FXSpinDialMap[]
virtual void layout()
Perform layout.
long onMouseWheel(FXObject *, FXSelector, void *)
FXColor getDownArrowColor() const
Return color of the the down arrow.
void setSelTextColor(FXColor clr)
Change selected text color.
FXColor getUpArrowColor() const
Return color of the up arrow.
#define DIALMULT
Spinner control.
FXRealSpinDialText * textField
long onAuto(FXObject *, FXSelector, void *)
long onRightButtonPress(FXObject *, FXSelector, void *)
virtual void enable()
Enable spinner.
void setUpArrowColor(FXColor clr)
Change color of the up arrow.
long onCmdSetRealValue(FXObject *, FXSelector, void *)
FXbool isTextVisible() const
Return TRUE if text is visible.
long onChgDial(FXObject *, FXSelector, void *)
virtual void save(FXStream &store) const
Save spinner to a stream.