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. 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 >= 10302 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 //