FLTK 1.3.0
|
00001 // 00002 // "$Id$" 00003 // 00004 // An input/chooser widget. 00005 // ______________ ____ 00006 // | || __ | 00007 // | input area || \/ | 00008 // |______________||____| 00009 // 00010 // Copyright 1998-2010 by Bill Spitzak and others. 00011 // Copyright 2004 by Greg Ercolano. 00012 // 00013 // This library is free software; you can redistribute it and/or 00014 // modify it under the terms of the GNU Library General Public 00015 // License as published by the Free Software Foundation; either 00016 // version 2 of the License, or (at your option) any later version. 00017 // 00018 // This library is distributed in the hope that it will be useful, 00019 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00021 // Library General Public License for more details. 00022 // 00023 // You should have received a copy of the GNU Library General Public 00024 // License along with this library; if not, write to the Free Software 00025 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00026 // USA. 00027 // 00028 // Please report all bugs and problems on the following page: 00029 // 00030 // http://www.fltk.org/str.php 00031 // 00032 00033 /* \file 00034 Fl_Input_Choice widget . */ 00035 00036 00037 00038 #ifndef Fl_Input_Choice_H 00039 #define Fl_Input_Choice_H 00040 00041 #include <FL/Fl.H> 00042 #include <FL/Fl_Group.H> 00043 #include <FL/Fl_Input.H> 00044 #include <FL/Fl_Menu_Button.H> 00045 #include <FL/fl_draw.H> 00046 #include <string.h> 00047 00059 class FL_EXPORT Fl_Input_Choice : public Fl_Group { 00060 // Private class to handle slightly 'special' behavior of menu button 00061 class InputMenuButton : public Fl_Menu_Button { 00062 void draw() { 00063 draw_box(FL_UP_BOX, color()); 00064 fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); 00065 int xc = x()+w()/2, yc=y()+h()/2; 00066 fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3); 00067 if (Fl::focus() == this) draw_focus(); 00068 } 00069 public: 00070 InputMenuButton(int x,int y,int w,int h,const char*l=0) : 00071 Fl_Menu_Button(x,y,w,h,l) { box(FL_UP_BOX); } 00072 }; 00073 00074 Fl_Input *inp_; 00075 InputMenuButton *menu_; 00076 00077 static void menu_cb(Fl_Widget*, void *data) { 00078 Fl_Input_Choice *o=(Fl_Input_Choice *)data; 00079 Fl_Widget_Tracker wp(o); 00080 const Fl_Menu_Item *item = o->menubutton()->mvalue(); 00081 if (item && item->flags & (FL_SUBMENU|FL_SUBMENU_POINTER)) return; // ignore submenus 00082 if (!strcmp(o->inp_->value(), o->menu_->text())) 00083 { 00084 o->Fl_Widget::clear_changed(); 00085 if (o->when() & FL_WHEN_NOT_CHANGED) 00086 o->do_callback(); 00087 } 00088 else 00089 { 00090 o->inp_->value(o->menu_->text()); 00091 o->inp_->set_changed(); 00092 o->Fl_Widget::set_changed(); 00093 if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) 00094 o->do_callback(); 00095 } 00096 00097 if (wp.deleted()) return; 00098 00099 if (o->callback() != default_callback) 00100 { 00101 o->Fl_Widget::clear_changed(); 00102 o->inp_->clear_changed(); 00103 } 00104 } 00105 00106 static void inp_cb(Fl_Widget*, void *data) { 00107 Fl_Input_Choice *o=(Fl_Input_Choice *)data; 00108 Fl_Widget_Tracker wp(o); 00109 if (o->inp_->changed()) { 00110 o->Fl_Widget::set_changed(); 00111 if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) 00112 o->do_callback(); 00113 } else { 00114 o->Fl_Widget::clear_changed(); 00115 if (o->when() & FL_WHEN_NOT_CHANGED) 00116 o->do_callback(); 00117 } 00118 00119 if (wp.deleted()) return; 00120 00121 if (o->callback() != default_callback) 00122 o->Fl_Widget::clear_changed(); 00123 } 00124 00125 // Custom resize behavior -- input stretches, menu button doesn't 00126 inline int inp_x() { return(x() + Fl::box_dx(box())); } 00127 inline int inp_y() { return(y() + Fl::box_dy(box())); } 00128 inline int inp_w() { return(w() - Fl::box_dw(box()) - 20); } 00129 inline int inp_h() { return(h() - Fl::box_dh(box())); } 00130 00131 inline int menu_x() { return(x() + w() - 20 - Fl::box_dx(box())); } 00132 inline int menu_y() { return(y() + Fl::box_dy(box())); } 00133 inline int menu_w() { return(20); } 00134 inline int menu_h() { return(h() - Fl::box_dh(box())); } 00135 00136 public: 00142 Fl_Input_Choice (int x,int y,int w,int h,const char*l=0) : Fl_Group(x,y,w,h,l) { 00143 Fl_Group::box(FL_DOWN_BOX); 00144 align(FL_ALIGN_LEFT); // default like Fl_Input 00145 inp_ = new Fl_Input(inp_x(), inp_y(), 00146 inp_w(), inp_h()); 00147 inp_->callback(inp_cb, (void*)this); 00148 inp_->box(FL_FLAT_BOX); // cosmetic 00149 inp_->when(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED); 00150 menu_ = new InputMenuButton(menu_x(), menu_y(), 00151 menu_w(), menu_h()); 00152 menu_->callback(menu_cb, (void*)this); 00153 menu_->box(FL_FLAT_BOX); // cosmetic 00154 end(); 00155 } 00156 00158 void add(const char *s) { menu_->add(s); } 00159 int changed() const { return inp_->changed() | Fl_Widget::changed();} 00160 void clear_changed() { 00161 inp_->clear_changed(); 00162 Fl_Widget::clear_changed(); 00163 } 00164 void set_changed() { 00165 inp_->set_changed(); 00166 // no need to call Fl_Widget::set_changed() 00167 } 00169 void clear() { menu_->clear(); } 00171 Fl_Boxtype down_box() const { return (menu_->down_box()); } 00173 void down_box(Fl_Boxtype b) { menu_->down_box(b); } 00175 const Fl_Menu_Item *menu() { return (menu_->menu()); } 00177 void menu(const Fl_Menu_Item *m) { menu_->menu(m); } 00178 void resize(int X, int Y, int W, int H) { 00179 Fl_Group::resize(X,Y,W,H); 00180 inp_->resize(inp_x(), inp_y(), inp_w(), inp_h()); 00181 menu_->resize(menu_x(), menu_y(), menu_w(), menu_h()); 00182 } 00184 Fl_Color textcolor() const { return (inp_->textcolor());} 00186 void textcolor(Fl_Color c) { inp_->textcolor(c);} 00188 Fl_Font textfont() const { return (inp_->textfont());} 00190 void textfont(Fl_Font f) { inp_->textfont(f);} 00192 Fl_Fontsize textsize() const { return (inp_->textsize()); } 00194 void textsize(Fl_Fontsize s) { inp_->textsize(s); } 00196 const char* value() const { return (inp_->value()); } 00204 void value(const char *val) { inp_->value(val); } 00206 void value(int val) { 00207 menu_->value(val); 00208 inp_->value(menu_->text(val)); 00209 } 00211 Fl_Menu_Button *menubutton() { return menu_; } 00215 Fl_Input *input() { return inp_; } 00216 }; 00217 00218 #endif // !Fl_Input_Choice_H 00219 00220 // 00221 // End of "$Id$". 00222 //