FLTK 1.3.2
Fl_Spinner.H
00001 //
00002 // "$Id$"
00003 //
00004 // Spinner widget for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software. Distribution and use rights are outlined in
00009 // the file "COPYING" which should have been included with this file.  If this
00010 // file is missing or damaged, see the license at:
00011 //
00012 //     http://www.fltk.org/COPYING.php
00013 //
00014 // Please report all bugs and problems on the following page:
00015 //
00016 //     http://www.fltk.org/str.php
00017 //
00018 
00019 /* \file
00020    Fl_Spinner widget . */
00021 
00022 #ifndef Fl_Spinner_H
00023 #  define Fl_Spinner_H
00024 
00025 //
00026 // Include necessary headers...
00027 //
00028 
00029 #  include <FL/Enumerations.H>
00030 #  include <FL/Fl_Group.H>
00031 #  include <FL/Fl_Input.H>
00032 #  include <FL/Fl_Repeat_Button.H>
00033 #  include <stdio.h>
00034 #  include <stdlib.h>
00035 
00036 
00045 class FL_EXPORT Fl_Spinner : public Fl_Group {
00046   
00047   double        value_;                 // Current value
00048   double        minimum_;               // Minimum value
00049   double        maximum_;               // Maximum value
00050   double        step_;                  // Amount to add/subtract for up/down
00051   const char    *format_;               // Format string
00052 
00053 #if FLTK_ABI_VERSION >= 10301
00054 // NEW
00055 protected:
00056 #endif
00057   Fl_Input      input_;                 // Input field for the value
00058   Fl_Repeat_Button
00059                 up_button_,             // Up button
00060                 down_button_;           // Down button
00061 
00062 private:
00063   static void   sb_cb(Fl_Widget *w, Fl_Spinner *sb) {
00064                   double v;             // New value
00065 
00066                   if (w == &(sb->input_)) {
00067                     // Something changed in the input field...
00068                     v = atof(sb->input_.value());
00069 
00070                     if (v < sb->minimum_) {
00071                       sb->value_ = sb->minimum_;
00072                       sb->update();
00073                     } else if (v > sb->maximum_) {
00074                       sb->value_ = sb->maximum_;
00075                       sb->update();
00076                     } else sb->value_ = v;
00077                   } else if (w == &(sb->up_button_)) {
00078                     // Up button pressed...
00079                     v = sb->value_ + sb->step_;
00080 
00081                     if (v > sb->maximum_) sb->value_ = sb->minimum_;
00082                     else sb->value_ = v;
00083 
00084                     sb->update();
00085                   } else if (w == &(sb->down_button_)) {
00086                     // Down button pressed...
00087                     v = sb->value_ - sb->step_;
00088 
00089                     if (v < sb->minimum_) sb->value_ = sb->maximum_;
00090                     else sb->value_ = v;
00091 
00092                     sb->update();
00093                   }
00094 
00095                   sb->do_callback();
00096                 }
00097   void          update() {
00098                   char s[255];          // Value string
00099 
00100                   if (format_[0]=='%'&&format_[1]=='.'&&format_[2]=='*') {  // precision argument
00101                     // this code block is a simplified version of
00102                     // Fl_Valuator::format() and works well (but looks ugly)
00103                     int c = 0;
00104                     char temp[64], *sp = temp;
00105                     sprintf(temp, "%.12f", step_);
00106                     while (*sp) sp++;
00107                     sp--;
00108                     while (sp>temp && *sp=='0') sp--;
00109                     while (sp>temp && (*sp>='0' && *sp<='9')) { sp--; c++; }
00110                     sprintf(s, format_, c, value_);
00111                   } else {
00112                     sprintf(s, format_, value_);
00113                   }
00114                   input_.value(s);
00115                 }
00116 
00117   public:
00118 
00124   Fl_Spinner(int X, int Y, int W, int H, const char *L = 0);
00125 
00127   const char    *format() { return (format_); }
00129   void          format(const char *f) { format_ = f; update(); }
00130 
00131   int           handle(int event) {
00132                   switch (event) {
00133                     case FL_KEYDOWN :
00134                     case FL_SHORTCUT :
00135                       if (Fl::event_key() == FL_Up) {
00136                         up_button_.do_callback();
00137                         return 1;
00138                       } else if (Fl::event_key() == FL_Down) {
00139                         down_button_.do_callback();
00140                         return 1;
00141                       } else return 0;
00142 
00143                     case FL_FOCUS :
00144                       if (input_.take_focus()) return 1;
00145                       else return 0;
00146                   }
00147 
00148                   return Fl_Group::handle(event);
00149                 }
00150 
00152   double        maxinum() const { return (maximum_); }
00154   double        maximum() const { return (maximum_); }
00156   void          maximum(double m) { maximum_ = m; }
00158   double        mininum() const { return (minimum_); }
00160   double        minimum() const { return (minimum_); }
00162   void          minimum(double m) { minimum_ = m; }
00164   void          range(double a, double b) { minimum_ = a; maximum_ = b; }
00165   void          resize(int X, int Y, int W, int H) {
00166                   Fl_Group::resize(X,Y,W,H);
00167 
00168                   input_.resize(X, Y, W - H / 2 - 2, H);
00169                   up_button_.resize(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2);
00170                   down_button_.resize(X + W - H / 2 - 2, Y + H - H / 2,
00171                                       H / 2 + 2, H / 2);
00172                 }
00178   double        step() const { return (step_); }
00180   void          step(double s) {
00181                   step_ = s;
00182                   if (step_ != (int)step_) input_.type(FL_FLOAT_INPUT);
00183                   else input_.type(FL_INT_INPUT);
00184                   update();
00185                 }
00187   Fl_Color      textcolor() const {
00188                   return (input_.textcolor());
00189                 }
00191   void          textcolor(Fl_Color c) {
00192                   input_.textcolor(c);
00193                 }
00195   Fl_Font       textfont() const {
00196                   return (input_.textfont());
00197                 }
00199   void          textfont(Fl_Font f) {
00200                   input_.textfont(f);
00201                 }
00203   Fl_Fontsize  textsize() const {
00204                   return (input_.textsize());
00205                 }
00207   void          textsize(Fl_Fontsize s) {
00208                   input_.textsize(s);
00209                 }
00213   uchar         type() const { return (input_.type()); }
00220   void          type(uchar v) { 
00221                   if (v==FL_FLOAT_INPUT) {
00222                     format("%.*f");
00223                   } else {
00224                     format("%.0f");
00225                   }
00226                   input_.type(v); 
00227                 }
00229   double        value() const { return (value_); }
00235   void          value(double v) { value_ = v; update(); }
00239   void          color(Fl_Color v) { input_.color(v); }
00243   Fl_Color      color() const { return(input_.color()); }
00244 };
00245 
00246 #endif // !Fl_Spinner_H
00247 
00248 //
00249 // End of "$Id$".
00250 //