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