42 #include "FXRectangle.h"
43 #include "FXRegistry.h"
44 #include "FXAccelTable.h"
47 #include "FXTextField.h"
53 #ifdef CHECK_MEMORY_LEAKS
55 #endif // CHECK_MEMORY_LEAKS
75 #define BUTTONWIDTH 12
78 #define INTMAX 2147483647
79 #define INTMIN (-INTMAX-1)
81 #define SPINDIAL_MASK (SPINDIAL_CYCLIC|SPINDIAL_NOTEXT|SPINDIAL_NOBUTTONS|SPINDIAL_NODIAL|SPINDIAL_NOMAX|SPINDIAL_NOMIN|SPINDIAL_LOG)
98 long onKey(
FXObject*, FXSelector,
void*);
99 long onButtonPress(
FXObject*, FXSelector,
void*);
100 long onButtonRelease(
FXObject*, FXSelector,
void*);
101 long onRightButtonPress(
FXObject*, FXSelector,
void*);
102 long onRightButtonRelease(
FXObject*, FXSelector,
void*);
103 long onMotion(
FXObject*, FXSelector,
void*);
104 long onAuto(
FXObject*, FXSelector,
void*);
106 ID_AUTOSPIN = FXDial::ID_LAST,
113 FXint x = 0, FXint y = 0, FXint w = 0, FXint h = 0,
114 FXint pl = DEFAULT_PAD, FXint pr = DEFAULT_PAD, FXint pt = DEFAULT_PAD, FXint pb = DEFAULT_PAD):
115 FXDial(p, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb) {}
144 return target->handle(o, s, p);
150 return FXDial::onLeftBtnPress(o, s, p);
154 return FXDial::onLeftBtnRelease(o, s, p);
161 FXEvent*
event = (FXEvent*)p;
162 if (options & DIAL_HORIZONTAL) {
163 dragpoint =
event->win_x;
165 dragpoint =
event->win_y;
167 getApp()->addTimeout(
this, ID_AUTOSPIN, getApp()->getScrollSpeed());
174 getApp()->removeTimeout(
this, ID_AUTOSPIN);
182 getApp()->addTimeout(
this, ID_AUTOSPIN, getApp()->getScrollSpeed());
183 setValue(getValue() +
int((dragpoint - dragpos) /
float(5)));
186 target->handle(
this, FXSEL(SEL_CHANGED, message), &v);
195 if (target && target->handle(
this, FXSEL(SEL_MOTION, message), p)) {
199 FXbool bJump = FALSE;
200 FXEvent* e = (FXEvent*)p;
201 if (!(flags & FLAG_PRESSED)) {
204 FXWindow* rootWin = getApp()->getRootWindow();
205 FXint x = e->root_x, y = e->root_y;
206 if (e->root_x >= rootWin->getWidth() - 1) {
210 }
else if (e->root_x <= 10) {
215 if (e->root_y >= rootWin->getHeight() - 1) {
219 }
else if (e->root_y <= 10) {
225 rootWin->setCursorPosition(x, y);
228 return FXDial::onMotion(o, s, p);
247 long onKey(
FXObject*, FXSelector,
void*);
248 long onButtonPress(
FXObject*, FXSelector,
void*);
249 long onButtonRelease(
FXObject*, FXSelector,
void*);
251 ID_AUTOSPIN = FXDial::ID_LAST,
258 FXuint opts = ARROW_NORMAL,
259 FXint x = 0, FXint y = 0, FXint w = 0, FXint h = 0,
260 FXint pl = DEFAULT_PAD, FXint pr = DEFAULT_PAD, FXint pt = DEFAULT_PAD, FXint pb = DEFAULT_PAD):
261 FXArrowButton(p, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb) {}
286 return target->handle(o, s, p);
292 return FXArrowButton::onLeftBtnPress(o, s, p);
296 return FXArrowButton::onLeftBtnRelease(o, s, p);
316 long onCmdSetRealValue(
FXObject*, FXSelector,
void*);
317 long onMotion(
FXObject*, FXSelector,
void*);
319 ID_LAST = FXTextField::ID_LAST
328 FXuint opts = TEXTFIELD_NORMAL,
329 FXint x = 0, FXint y = 0, FXint w = 0, FXint h = 0, FXint
330 pl = DEFAULT_PAD, FXint pr = DEFAULT_PAD, FXint pt = DEFAULT_PAD, FXint pb = DEFAULT_PAD
332 FXTextField(p, ncols, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb),
340 flags &= ~FLAG_FMTSTRING;
350 flags |= FLAG_FMTSTRING;
375 if (target && target->handle(
this, FXSEL(SEL_MOTION, message), ptr)) {
378 return FXTextField::onMotion(o, s, ptr);
382 if (flags & FLAG_FMTSTRING) {
383 setText(FXStringFormat(fmtString.text(), *((FXdouble*)ptr)));
385 setText(FXStringVal(*((FXdouble*)ptr), precision, exponent));
437 flags = (flags | FLAG_ENABLED | FLAG_SHOWN)&~FLAG_UPDATE;
453 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):
454 FXPacker(p, opts&~(FRAME_RIDGE), x, y, w, h, 0, 0, 0, 0, 0, 0) {
455 flags = (flags | FLAG_ENABLED | FLAG_SHOWN)&~FLAG_UPDATE;
458 dial =
new FXRealSpinDialDial(
this,
this,
ID_DIAL, DIAL_VERTICAL, 0, 0, 0, 0, 0, 0, 0, 0);
459 dial->setNotchSpacing(450);
461 upButton =
new FXRealSpinDialBtn(
this,
this,
ID_INCREMENT, FRAME_RAISED | FRAME_THICK | ARROW_UP | ARROW_REPEAT, 0, 0, 0, 0, 0, 0, 0, 0);
462 downButton =
new FXRealSpinDialBtn(
this,
this,
ID_DECREMENT, FRAME_RAISED | FRAME_THICK | ARROW_DOWN | ARROW_REPEAT, 0, 0, 0, 0, 0, 0, 0, 0);
463 textField =
new FXRealSpinDialText(
this, cols,
this,
ID_ENTRY, (opts & FRAME_RIDGE) | TEXTFIELD_REAL | JUSTIFY_RIGHT, 0, 0, 0, 0, pl, pr, pt, pb);
489 return textField->getDefaultHeight() + (border << 1);
501 if (!(flags & FLAG_ENABLED)) {
511 if (flags & FLAG_ENABLED) {
521 FXint dialWidth, dialHeight, buttonWidth, buttonHeight, textHeight;
523 textHeight = height - 2 * border;
524 dialHeight = textHeight;
525 buttonHeight = textHeight >> 1;
528 if ((options & hideOpts) == hideOpts) {
529 flags &= ~FLAG_DIRTY;
533 FXint right = width - border;
542 upButton->position(border, border, bw, buttonHeight);
543 downButton->position(border, height - buttonHeight - border, bw, buttonHeight);
546 dial->position(left, border, right - left, dialHeight);
548 upButton->position(border, border, right - border, buttonHeight);
549 downButton->position(border, height - buttonHeight - border, right - border, buttonHeight);
553 dialWidth = buttonWidth = 0;
556 dial->position(right - w, border, w, dialHeight);
561 upButton->position(right - w, border, w, buttonHeight);
562 downButton->position(right - w, height - buttonHeight - border, w, buttonHeight);
565 textField->position(border, border, right - border, textHeight);
567 flags &= ~FLAG_DIRTY;
574 sender->handle(
this, FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
576 sender->handle(
this, FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
589 if (FXApp::instance()->getKeyState(CONTROLMASK)) {
591 }
else if (FXApp::instance()->getKeyState(SHIFTMASK)) {
604 if (options & SPINDIAL_LOG) {
606 FXdouble lr0 = log(
range[0]), lr1 = log(
range[1]), lnp = log(newpos);
607 newpos = exp(lr0 + fmod(lnp - lr0, lr1 - lr0)) ;
615 if (options & SPINDIAL_LOG) {
617 FXdouble lr0 = log(
range[0]), lr1 = log(
range[1]), lpos = log(
pos);
618 FXdouble span = lr1 - lr0;
619 newpos = exp(lr0 + fmod(lpos - lr0 + 1 + (span - inc), span));
629 target->handle(
this, FXSEL(SEL_COMMAND, message), (
void*)&
pos);
649 if (isEnabled() && ((options & REALSPIN_CYCLIC) || (
pos <
range[1]))) {
650 sender->handle(
this, FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
652 sender->handle(
this, FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
673 target->handle(
this, FXSEL(SEL_COMMAND, message), (
void*)&
pos);
681 if (isEnabled() && ((options & REALSPIN_CYCLIC) || (
range[0] <
pos))) {
682 sender->handle(
this, FXSEL(SEL_COMMAND, ID_ENABLE), NULL);
684 sender->handle(
this, FXSEL(SEL_COMMAND, ID_DISABLE), NULL);
705 target->handle(
this, FXSEL(SEL_COMMAND, message), (
void*)&
pos);
714 return target && target->handle(
this, FXSEL(SEL_UPDATE, message), NULL);
727 if (((FXEvent*)p)->code > 0) {
733 target->handle(
this, FXSEL(SEL_COMMAND, message), (
void*)&
pos);
740 register FXdouble value = FXDoubleVal(
textField->getText());
741 if (value <
range[0]) {
744 if (value >
range[1]) {
750 target->handle(
this, FXSEL(SEL_CHANGED, message), (
void*)&
pos);
761 target->handle(
this, FXSEL(SEL_COMMAND, message), (
void*)&
pos);
769 FXEvent*
event = (FXEvent*)ptr;
774 if (target && target->handle(
this, FXSEL(SEL_KEYPRESS, message), ptr)) {
785 switch (event->code) {
790 target->handle(
this, FXSEL(SEL_COMMAND, message), (
void*)&
pos);
797 target->handle(
this, FXSEL(SEL_COMMAND, message), (
void*)&
pos);
801 return textField->handle(sender, sel, ptr);
809 FXEvent*
event = (FXEvent*)ptr;
814 if (target && target->handle(
this, FXSEL(SEL_KEYRELEASE, message), ptr)) {
817 switch (event->code) {
824 return textField->handle(sender, sel, ptr);
861 FXdouble lo = (FXdouble)((FXint*)ptr)[0];
862 FXdouble hi = (FXdouble)((FXint*)ptr)[1];
870 ((FXdouble*)ptr)[0] =
range[0];
871 ((FXdouble*)ptr)[1] =
range[1];
892 setRange(((FXdouble*)ptr)[0], ((FXdouble*)ptr)[1]);
899 getRange(((FXdouble*)ptr)[0], ((FXdouble*)ptr)[1]);
907 FXdouble inc =
incr[incMode + 1];
914 FXdouble lr0 = log(
range[0]), lr1 = log(
range[1]), lnp = log(newpos);
915 newpos = exp(lr0 + fmod(lnp - lr0, lr1 - lr0)) ;
930 FXdouble inc =
incr[incMode + 1];
937 FXdouble lr0 = log(
range[0]), lr1 = log(
range[1]), lpos = log(
pos);
938 FXdouble span = lr1 - lr0;
939 newpos = exp(lr0 + fmod(lpos - lr0 + 1 + (span - inc), span));
970 fxerror(
"%s::setRange: trying to set negative range.\n", getClassName());
982 if (value <
range[0]) {
985 if (value >
range[1]) {
989 textField->handle(
this, FXSEL(SEL_COMMAND, ID_SETREALVALUE), &value);
998 fxerror(
"%s::setIncrement: negative or zero increment specified.\n", getClassName());
1004 fxerror(
"%s::setIncrement: negative or zero increment specified.\n", getClassName());
1010 fxerror(
"%s::setIncrement: negative or zero increment specified.\n", getClassName());
1016 fxerror(
"%s::setIncrement: negative or zero increment specified.\n", getClassName());
1033 if (options != opts) {
1055 dial->setHelpText(text);
1070 dial->setTipText(text);
1086 if (options != opts) {
1088 range[0] = -DBL_MAX;
1118 dial->setBackColor(clr);
1123 return dial->getBackColor();
1245 FXRealSpinDial::selectAll() {