FLTK 1.3.0
|
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; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 /* \file 00029 Fl_Spinner widget . */ 00030 00031 #ifndef Fl_Spinner_H 00032 # define Fl_Spinner_H 00033 00034 // 00035 // Include necessary headers... 00036 // 00037 00038 # include <FL/Enumerations.H> 00039 # include <FL/Fl_Group.H> 00040 # include <FL/Fl_Input.H> 00041 # include <FL/Fl_Repeat_Button.H> 00042 # include <stdio.h> 00043 # include <stdlib.h> 00044 00045 00051 class FL_EXPORT Fl_Spinner : public Fl_Group { 00052 00053 double value_; // Current value 00054 double minimum_; // Minimum value 00055 double maximum_; // Maximum value 00056 double step_; // Amount to add/subtract for up/down 00057 const char *format_; // Format string 00058 00059 Fl_Input input_; // Input field for the value 00060 Fl_Repeat_Button 00061 up_button_, // Up button 00062 down_button_; // Down button 00063 00064 00065 static void sb_cb(Fl_Widget *w, Fl_Spinner *sb) { 00066 double v; // New value 00067 00068 if (w == &(sb->input_)) { 00069 // Something changed in the input field... 00070 v = atof(sb->input_.value()); 00071 00072 if (v < sb->minimum_) { 00073 sb->value_ = sb->minimum_; 00074 sb->update(); 00075 } else if (v > sb->maximum_) { 00076 sb->value_ = sb->maximum_; 00077 sb->update(); 00078 } else sb->value_ = v; 00079 } else if (w == &(sb->up_button_)) { 00080 // Up button pressed... 00081 v = sb->value_ + sb->step_; 00082 00083 if (v > sb->maximum_) sb->value_ = sb->minimum_; 00084 else sb->value_ = v; 00085 00086 sb->update(); 00087 } else if (w == &(sb->down_button_)) { 00088 // Down button pressed... 00089 v = sb->value_ - sb->step_; 00090 00091 if (v < sb->minimum_) sb->value_ = sb->maximum_; 00092 else sb->value_ = v; 00093 00094 sb->update(); 00095 } 00096 00097 sb->do_callback(); 00098 } 00099 void update() { 00100 char s[255]; // Value string 00101 00102 if (format_[0]=='%'&&format_[1]=='.'&&format_[2]=='*') { // precision argument 00103 // this code block is a simplified version of 00104 // Fl_Valuator::format() and works well (but looks ugly) 00105 int c = 0; 00106 char temp[64], *sp = temp; 00107 sprintf(temp, "%.12f", step_); 00108 while (*sp) sp++; 00109 sp--; 00110 while (sp>temp && *sp=='0') sp--; 00111 while (sp>temp && (*sp>='0' && *sp<='9')) { sp--; c++; } 00112 sprintf(s, format_, c, value_); 00113 } else { 00114 sprintf(s, format_, value_); 00115 } 00116 input_.value(s); 00117 } 00118 00119 public: 00120 00126 Fl_Spinner(int X, int Y, int W, int H, const char *L = 0) 00127 : Fl_Group(X, Y, W, H, L), 00128 input_(X, Y, W - H / 2 - 2, H), 00129 up_button_(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2, "@-42<"), 00130 down_button_(X + W - H / 2 - 2, Y + H - H / 2, 00131 H / 2 + 2, H / 2, "@-42>") { 00132 end(); 00133 00134 value_ = 1.0; 00135 minimum_ = 1.0; 00136 maximum_ = 100.0; 00137 step_ = 1.0; 00138 format_ = "%g"; 00139 00140 align(FL_ALIGN_LEFT); 00141 00142 input_.value("1"); 00143 input_.type(FL_INT_INPUT); 00144 input_.when(FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE); 00145 input_.callback((Fl_Callback *)sb_cb, this); 00146 00147 up_button_.callback((Fl_Callback *)sb_cb, this); 00148 00149 down_button_.callback((Fl_Callback *)sb_cb, this); 00150 } 00151 00153 const char *format() { return (format_); } 00155 void format(const char *f) { format_ = f; update(); } 00156 00157 int handle(int event) { 00158 switch (event) { 00159 case FL_KEYDOWN : 00160 case FL_SHORTCUT : 00161 if (Fl::event_key() == FL_Up) { 00162 up_button_.do_callback(); 00163 return 1; 00164 } else if (Fl::event_key() == FL_Down) { 00165 down_button_.do_callback(); 00166 return 1; 00167 } else return 0; 00168 00169 case FL_FOCUS : 00170 if (input_.take_focus()) return 1; 00171 else return 0; 00172 } 00173 00174 return Fl_Group::handle(event); 00175 } 00176 00178 double maxinum() const { return (maximum_); } 00180 double maximum() const { return (maximum_); } 00182 void maximum(double m) { maximum_ = m; } 00184 double mininum() const { return (minimum_); } 00186 double minimum() const { return (minimum_); } 00188 void minimum(double m) { minimum_ = m; } 00190 void range(double a, double b) { minimum_ = a; maximum_ = b; } 00191 void resize(int X, int Y, int W, int H) { 00192 Fl_Group::resize(X,Y,W,H); 00193 00194 input_.resize(X, Y, W - H / 2 - 2, H); 00195 up_button_.resize(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2); 00196 down_button_.resize(X + W - H / 2 - 2, Y + H - H / 2, 00197 H / 2 + 2, H / 2); 00198 } 00204 double step() const { return (step_); } 00206 void step(double s) { 00207 step_ = s; 00208 if (step_ != (int)step_) input_.type(FL_FLOAT_INPUT); 00209 else input_.type(FL_INT_INPUT); 00210 update(); 00211 } 00213 Fl_Color textcolor() const { 00214 return (input_.textcolor()); 00215 } 00217 void textcolor(Fl_Color c) { 00218 input_.textcolor(c); 00219 } 00221 Fl_Font textfont() const { 00222 return (input_.textfont()); 00223 } 00225 void textfont(Fl_Font f) { 00226 input_.textfont(f); 00227 } 00229 Fl_Fontsize textsize() const { 00230 return (input_.textsize()); 00231 } 00233 void textsize(Fl_Fontsize s) { 00234 input_.textsize(s); 00235 } 00239 uchar type() const { return (input_.type()); } 00246 void type(uchar v) { 00247 if (v==FL_FLOAT_INPUT) { 00248 format("%.*f"); 00249 } else { 00250 format("%.0f"); 00251 } 00252 input_.type(v); 00253 } 00255 double value() const { return (value_); } 00261 void value(double v) { value_ = v; update(); } 00262 }; 00263 00264 #endif // !Fl_Spinner_H 00265 00266 // 00267 // End of "$Id$". 00268 //