DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2776
Version: 1.3-feature
Attached file "spinner-blank-allowed.patch"...
Link: http://www.fltk.org/str.php?L2776
Version: 1.3-feature
Index: FL/Fl_Spinner.H
===================================================================
--- FL/Fl_Spinner.H (revision 9180)
+++ FL/Fl_Spinner.H (working copy)
@@ -30,8 +30,6 @@
# include <FL/Fl_Group.H>
# include <FL/Fl_Input.H>
# include <FL/Fl_Repeat_Button.H>
-# include <stdio.h>
-# include <stdlib.h>
/**
@@ -46,67 +44,20 @@
double maximum_; // Maximum value
double step_; // Amount to add/subtract for up/down
const char *format_; // Format string
+ int flags_ex_; // additional option flags
+ static const int FLAG_EX_BLANK_ALLOWED=1; // allow blank (zero)
(outside of range)
+
+
Fl_Input input_; // Input field for the value
Fl_Repeat_Button
up_button_, // Up button
down_button_; // Down button
- static void sb_cb(Fl_Widget *w, Fl_Spinner *sb) {
- double v; // New value
+ static void sb_cb(Fl_Widget *w, Fl_Spinner *sb);
+ void update();
- if (w == &(sb->input_)) {
- // Something changed in the input field...
- v = atof(sb->input_.value());
-
- if (v < sb->minimum_) {
- sb->value_ = sb->minimum_;
- sb->update();
- } else if (v > sb->maximum_) {
- sb->value_ = sb->maximum_;
- sb->update();
- } else sb->value_ = v;
- } 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;
-
- 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;
-
- sb->update();
- }
-
- sb->do_callback();
- }
- void update() {
- char s[255]; // Value string
-
- if (format_[0]=='%'&&format_[1]=='.'&&format_[2]=='*') { //
precision argument
- // this code block is a simplified version of
- // Fl_Valuator::format() and works well (but looks ugly)
- int c = 0;
- char temp[64], *sp = temp;
- sprintf(temp, "%.12f", step_);
- while (*sp) sp++;
- sp--;
- while (sp>temp && *sp=='0') sp--;
- while (sp>temp && (*sp>='0' && *sp<='9')) { sp--; c++; }
- sprintf(s, format_, c, value_);
- } else {
- sprintf(s, format_, value_);
- }
- input_.value(s);
- }
-
public:
/**
@@ -114,57 +65,15 @@
and label string.
<P>Inherited destructor Destroys the widget and any value
associated with it.
*/
- Fl_Spinner(int X, int Y, int W, int H, const char *L = 0)
- : Fl_Group(X, Y, W, H, L),
- input_(X, Y, W - H / 2 - 2, H),
- up_button_(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2, "@-42<"),
- down_button_(X + W - H / 2 - 2, Y + H - H / 2,
- H / 2 + 2, H / 2, "@-42>") {
- end();
+ Fl_Spinner(int X, int Y, int W, int H, const char *L = 0);
- value_ = 1.0;
- minimum_ = 1.0;
- maximum_ = 100.0;
- step_ = 1.0;
- format_ = "%g";
-
- align(FL_ALIGN_LEFT);
-
- input_.value("1");
- input_.type(FL_INT_INPUT);
- input_.when(FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE);
- input_.callback((Fl_Callback *)sb_cb, this);
-
- up_button_.callback((Fl_Callback *)sb_cb, this);
-
- down_button_.callback((Fl_Callback *)sb_cb, this);
- }
-
/** Sets or returns the format string for the value. */
const char *format() { return (format_); }
/** Sets or returns the format string for the value. */
void format(const char *f) { format_ = f; update(); }
- int handle(int event) {
- switch (event) {
- case FL_KEYDOWN :
- case FL_SHORTCUT :
- if (Fl::event_key() == FL_Up) {
- up_button_.do_callback();
- return 1;
- } else if (Fl::event_key() == FL_Down) {
- down_button_.do_callback();
- return 1;
- } else return 0;
+ int handle(int event);
- case FL_FOCUS :
- if (input_.take_focus()) return 1;
- else return 0;
- }
-
- return Fl_Group::handle(event);
- }
-
/** Speling mistakes retained for source compatibility \deprecated */
double maxinum() const { return (maximum_); }
/** Gets the maximum value of the widget. */
@@ -179,14 +88,7 @@
void minimum(double m) { minimum_ = m; }
/** Sets the minimum and maximum values for the widget. */
void range(double a, double b) { minimum_ = a; maximum_ = b; }
- void resize(int X, int Y, int W, int H) {
- Fl_Group::resize(X,Y,W,H);
-
- input_.resize(X, Y, W - H / 2 - 2, H);
- up_button_.resize(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2);
- down_button_.resize(X + W - H / 2 - 2, Y + H - H / 2,
- H / 2 + 2, H / 2);
- }
+ void resize(int X, int Y, int W, int H);
/**
Sets or returns the amount to change the value when the user clicks a
button.
Before setting step to a non-integer value, the spinner
@@ -194,12 +96,7 @@
*/
double step() const { return (step_); }
/** See double Fl_Spinner::step() const */
- void step(double s) {
- step_ = s;
- if (step_ != (int)step_) input_.type(FL_FLOAT_INPUT);
- else input_.type(FL_INT_INPUT);
- update();
- }
+ void step(double s);
/** Gets the color of the text in the input field. */
Fl_Color textcolor() const {
return (input_.textcolor());
@@ -234,14 +131,8 @@
Setting a new spinner type via a superclass pointer will not work.
\note type is not a virtual function.
*/
- void type(uchar v) {
- if (v==FL_FLOAT_INPUT) {
- format("%.*f");
- } else {
- format("%.0f");
- }
- input_.type(v);
- }
+ void type(uchar v);
+
/** Gets the current value of the widget. */
double value() const { return (value_); }
/**
@@ -250,6 +141,13 @@
type() should be changed to floating point.
*/
void value(double v) { value_ = v; update(); }
+
+/**
+ enable or disable support for making spinner values optional
+ */
+ void enable_blank_allowed() { flags_ex_|=FLAG_EX_BLANK_ALLOWED; };
+ void disable_blank_allowed() { flags_ex_&=~FLAG_EX_BLANK_ALLOWED; };
+ bool using_blank_allowed() { return (flags_ex_ & FLAG_EX_BLANK_ALLOWED)!=0;
};
};
#endif // !Fl_Spinner_H
Index: src/Fl_Spinner.cxx
===================================================================
--- src/Fl_Spinner.cxx (revision 0)
+++ src/Fl_Spinner.cxx (working copy)
@@ -0,0 +1,200 @@
+//
+// Spinner widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2011 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+/* \file
+ Fl_Spinner widget . */
+
+//
+// Include necessary headers...
+//
+
+# include <FL/FL_Spinner.H>
+# include <stdio.h>
+# include <stdlib.h>
+
+
+/**
+ This widget is a combination of the input
+ widget and repeat buttons. The user can either type into the
+ input area or use the buttons to change the value.
+*/
+
+//-------------------------------------------------------------------------
+
+void Fl_Spinner::sb_cb(Fl_Widget *w, Fl_Spinner *sb) {
+ double v; // New value
+
+ if (w == &(sb->input_)) {
+ // Something changed in the input field...
+ v = atof(sb->input_.value());
+
+ if (v < sb->minimum_) {
+ if (v==0 && sb->using_blank_allowed()) {
+ sb->value_=0;
+ }
+ else sb->value_ = sb->minimum_;
+ sb->update();
+ } else if (v > sb->maximum_) {
+ sb->value_ = sb->maximum_;
+ sb->update();
+ } else sb->value_ = v;
+ } else if (w == &(sb->up_button_)) {
+ // Up button pressed...
+ v = sb->value_ + sb->step_;
+
+ // catch up arrow starting at zero/blank
+ if (v < sb->minimum_ && sb->using_blank_allowed()) {
+ sb->value_ = sb->minimum_;
+ }
+ else if (v > sb->maximum_) {
+ if (sb->minimum_>0 && sb->using_blank_allowed()) {
+ sb->value_=0;
+ }
+ else sb->value_ = sb->minimum_;
+ }
+ else sb->value_ = v;
+
+ sb->update();
+ } else if (w == &(sb->down_button_)) {
+ // Down button pressed...
+ v = sb->value_ - sb->step_;
+
+ if (v < sb->minimum_) {
+ if (v>0 && sb->using_blank_allowed()) {
+ sb->value_=0;
+ }
+ else sb->value_ = sb->maximum_;
+ }
+ else sb->value_ = v;
+
+ sb->update();
+ }
+
+ sb->do_callback();
+}
+
+//-------------------------------------------------------------------------
+
+void Fl_Spinner::update() {
+ char s[255]; // Value string
+
+ if (format_[0]=='%'&&format_[1]=='.'&&format_[2]=='*') { // precision
argument
+ // this code block is a simplified version of
+ // Fl_Valuator::format() and works well (but looks ugly)
+ int c = 0;
+ char temp[64], *sp = temp;
+ sprintf(temp, "%.12f", step_);
+ while (*sp) sp++;
+ sp--;
+ while (sp>temp && *sp=='0') sp--;
+ while (sp>temp && (*sp>='0' && *sp<='9')) { sp--; c++; }
+ sprintf(s, format_, c, value_);
+ } else {
+ sprintf(s, format_, value_);
+ }
+ input_.value(s);
+}
+
+//-------------------------------------------------------------------------
+
+Fl_Spinner::Fl_Spinner(int X, int Y, int W, int H, const char *L)
+ : Fl_Group(X, Y, W, H, L),
+ input_(X, Y, W - H / 2 - 2, H),
+ up_button_(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2, FL_UP_ARROW_TX),
+ down_button_(X + W - H / 2 - 2, Y + H - H / 2,
+ H / 2 + 2, H / 2, FL_DN_ARROW_TX) {
+ end();
+
+ flags_ex_=0;
+
+ value_ = 1.0;
+ minimum_ = 1.0;
+ maximum_ = 100.0;
+ step_ = 1.0;
+ format_ = "%g";
+
+ align(FL_ALIGN_LEFT);
+
+ input_.value("1");
+ input_.type(FL_INT_INPUT);
+ input_.when(FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE);
+ input_.callback((Fl_Callback *)sb_cb, this);
+
+ up_button_.callback((Fl_Callback *)sb_cb, this);
+
+ down_button_.callback((Fl_Callback *)sb_cb, this);
+}
+
+//-------------------------------------------------------------------------
+
+int Fl_Spinner::handle(int event) {
+ switch (event) {
+ case FL_KEYDOWN :
+ case FL_SHORTCUT :
+ if (Fl::event_key() == FL_Up) {
+ up_button_.do_callback();
+ return 1;
+ } else if (Fl::event_key() == FL_Down) {
+ down_button_.do_callback();
+ return 1;
+ } else return 0;
+
+ case FL_FOCUS :
+ if (input_.take_focus()) return 1;
+ else return 0;
+ }
+
+ return Fl_Group::handle(event);
+}
+
+//-------------------------------------------------------------------------
+
+void Fl_Spinner::resize(int X, int Y, int W, int H) {
+ Fl_Group::resize(X,Y,W,H);
+
+ input_.resize(X, Y, W - H / 2 - 2, H);
+ up_button_.resize(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2);
+ down_button_.resize(X + W - H / 2 - 2, Y + H - H / 2,
+ H / 2 + 2, H / 2);
+}
+
+//-------------------------------------------------------------------------
+
+ /** See double Fl_Spinner::step() const */
+void Fl_Spinner::step(double s) {
+ step_ = s;
+ if (step_ != (int)step_) input_.type(FL_FLOAT_INPUT);
+ else input_.type(FL_INT_INPUT);
+ update();
+}
+
+//-------------------------------------------------------------------------
+
+/** Sets the numeric representation in the input field.
+ Valid values are FL_INT_INPUT and FL_FLOAT_INPUT.
+ Also changes the format() template.
+ Setting a new spinner type via a superclass pointer will not work.
+ \note type is not a virtual function.
+ */
+void Fl_Spinner::type(uchar v) {
+ if (v==FL_FLOAT_INPUT) {
+ format("%.*f");
+ } else {
+ format("%.0f");
+ }
+ input_.type(v);
+}
+
Index: src/Makefile
===================================================================
--- src/Makefile (revision 9180)
+++ src/Makefile (working copy)
@@ -73,6 +73,7 @@
Fl_Shared_Image.cxx \
Fl_Single_Window.cxx \
Fl_Slider.cxx \
+ Fl_Spinner.cxx \
Fl_Table.cxx \
Fl_Table_Row.cxx \
Fl_Tabs.cxx \
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev