diff --git a/CHANGES b/CHANGES index d42c83f9c..7425dd90a 100644 --- a/CHANGES +++ b/CHANGES @@ -46,6 +46,8 @@ Changes in FLTK 1.4.0 Released: ??? ?? 2017 - (add new items here) - Separated Fl_Spinner.H and Fl_Spinner.cxx (STR #2776). + - New method Fl_Spinner::wrap(int) allows to set wrap mode at bounds if + value is changed by pressing or holding one of the buttons (STR #3365). - Renamed test/help.cxx demo program to test/help_dialog.cxx to avoid name conflict with CMake auto-generated target 'help'. - Many documentation fixes, clarifications, and enhancements. diff --git a/FL/Fl_Spinner.H b/FL/Fl_Spinner.H index 107bebb3b..bac216e70 100644 --- a/FL/Fl_Spinner.H +++ b/FL/Fl_Spinner.H @@ -43,6 +43,7 @@ class FL_EXPORT Fl_Spinner : public Fl_Group { double maximum_; // Maximum value double step_; // Amount to add/subtract for up/down const char *format_; // Format string for input field + int wrap_; // wrap around at bounds (1/0) private: @@ -96,6 +97,30 @@ public: */ double step() const { return (step_); } + /** Sets whether the spinner wraps around at upper and lower bounds. + + If wrap mode is on (default) the spinner value is set to the minimum() + or maximum() when the value exceeds the upper or lower bounds, resp., + if the value was changed by one of the buttons. + + If wrap mode is off, the spinner value stops at the upper and lower bounds. + \see minimum(), maximum() + + \note This does not apply to the input field. The input value is always + clipped to the allowed range as if wrap mode was off. + + \param[in] set non-zero sets wrap mode, zero resets wrap mode + + \since 1.4.0 + */ + void wrap(int set) { wrap_ = set ? 1 : 0; } + + /** Gets the wrap mode of the Fl_Spinner widget. + \see void wrap(int) + \since 1.4.0 + */ + int wrap() const { return wrap_; } + /** Gets the color of the text in the input field. */ Fl_Color textcolor() const { return (input_.textcolor()); } diff --git a/src/Fl_Spinner.cxx b/src/Fl_Spinner.cxx index b9b08efa8..220ac1698 100644 --- a/src/Fl_Spinner.cxx +++ b/src/Fl_Spinner.cxx @@ -31,7 +31,7 @@ change the value. */ -void Fl_Spinner::sb_cb(Fl_Widget *w, Fl_Spinner *sb) { +void Fl_Spinner::sb_cb(Fl_Widget *w, Fl_Spinner *sb) { double v; // New value if (w == &(sb->input_)) { @@ -48,18 +48,24 @@ void Fl_Spinner::sb_cb(Fl_Widget *w, Fl_Spinner *sb) { } else if (w == &(sb->up_button_)) { // Up button pressed... v = sb->value_ + sb->step_; - - if (v > sb->maximum_) sb->value_ = sb->minimum_; - else sb->value_ = v; - + if (v > sb->maximum_) { + if (sb->wrap_) + v = sb->minimum_; + else + v = sb->maximum_; + } + sb->value_ = v; sb->update(); } else if (w == &(sb->down_button_)) { // Down button pressed... v = sb->value_ - sb->step_; - - if (v < sb->minimum_) sb->value_ = sb->maximum_; - else sb->value_ = v; - + if (v < sb->minimum_) { + if (sb->wrap_) + v = sb->maximum_; + else + v = sb->minimum_; + } + sb->value_ = v; sb->update(); } @@ -110,6 +116,7 @@ Fl_Spinner::Fl_Spinner(int X, int Y, int W, int H, const char *L) minimum_ = 1.0; maximum_ = 100.0; step_ = 1.0; + wrap_ = 1; format_ = "%g"; align(FL_ALIGN_LEFT);