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

Reply via email to