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