FLTK 1.3.2
|
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. Distribution and use rights are outlined in 00014 // the file "COPYING" which should have been included with this file. If this 00015 // file is missing or damaged, see the license at: 00016 // 00017 // http://www.fltk.org/COPYING.php 00018 // 00019 // Please report all bugs and problems on the following page: 00020 // 00021 // http://www.fltk.org/str.php 00022 // 00023 00024 /* \file 00025 Fl_Input_Choice widget . */ 00026 00027 #ifndef Fl_Input_Choice_H 00028 #define Fl_Input_Choice_H 00029 00030 #include <FL/Fl.H> 00031 #include <FL/Fl_Group.H> 00032 #include <FL/Fl_Input.H> 00033 #include <FL/Fl_Menu_Button.H> 00034 #include <FL/fl_draw.H> 00035 #include <string.h> 00036 00051 class FL_EXPORT Fl_Input_Choice : public Fl_Group { 00052 // Private class to handle slightly 'special' behavior of menu button 00053 class InputMenuButton : public Fl_Menu_Button { 00054 void draw() { 00055 draw_box(FL_UP_BOX, color()); 00056 fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); 00057 int xc = x()+w()/2, yc=y()+h()/2; 00058 fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3); 00059 if (Fl::focus() == this) draw_focus(); 00060 } 00061 public: 00062 InputMenuButton(int X,int Y,int W,int H,const char*L=0) : 00063 Fl_Menu_Button(X, Y, W, H, L) { box(FL_UP_BOX); } 00064 }; 00065 00066 Fl_Input *inp_; 00067 InputMenuButton *menu_; 00068 00069 static void menu_cb(Fl_Widget*, void *data) { 00070 Fl_Input_Choice *o=(Fl_Input_Choice *)data; 00071 Fl_Widget_Tracker wp(o); 00072 const Fl_Menu_Item *item = o->menubutton()->mvalue(); 00073 if (item && item->flags & (FL_SUBMENU|FL_SUBMENU_POINTER)) return; // ignore submenus 00074 if (!strcmp(o->inp_->value(), o->menu_->text())) 00075 { 00076 o->Fl_Widget::clear_changed(); 00077 if (o->when() & FL_WHEN_NOT_CHANGED) 00078 o->do_callback(); 00079 } 00080 else 00081 { 00082 o->inp_->value(o->menu_->text()); 00083 o->inp_->set_changed(); 00084 o->Fl_Widget::set_changed(); 00085 if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) 00086 o->do_callback(); 00087 } 00088 00089 if (wp.deleted()) return; 00090 00091 if (o->callback() != default_callback) 00092 { 00093 o->Fl_Widget::clear_changed(); 00094 o->inp_->clear_changed(); 00095 } 00096 } 00097 00098 static void inp_cb(Fl_Widget*, void *data) { 00099 Fl_Input_Choice *o=(Fl_Input_Choice *)data; 00100 Fl_Widget_Tracker wp(o); 00101 if (o->inp_->changed()) { 00102 o->Fl_Widget::set_changed(); 00103 if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) 00104 o->do_callback(); 00105 } else { 00106 o->Fl_Widget::clear_changed(); 00107 if (o->when() & FL_WHEN_NOT_CHANGED) 00108 o->do_callback(); 00109 } 00110 00111 if (wp.deleted()) return; 00112 00113 if (o->callback() != default_callback) 00114 o->Fl_Widget::clear_changed(); 00115 } 00116 00117 // Custom resize behavior -- input stretches, menu button doesn't 00118 inline int inp_x() { return(x() + Fl::box_dx(box())); } 00119 inline int inp_y() { return(y() + Fl::box_dy(box())); } 00120 inline int inp_w() { return(w() - Fl::box_dw(box()) - 20); } 00121 inline int inp_h() { return(h() - Fl::box_dh(box())); } 00122 00123 inline int menu_x() { return(x() + w() - 20 - Fl::box_dx(box())); } 00124 inline int menu_y() { return(y() + Fl::box_dy(box())); } 00125 inline int menu_w() { return(20); } 00126 inline int menu_h() { return(h() - Fl::box_dh(box())); } 00127 00128 public: 00134 Fl_Input_Choice(int X,int Y,int W,int H,const char*L=0); 00135 00147 void add(const char *s) { menu_->add(s); } 00149 int changed() const { return inp_->changed() | Fl_Widget::changed(); } 00151 void clear_changed() { 00152 inp_->clear_changed(); 00153 Fl_Widget::clear_changed(); 00154 } 00157 void set_changed() { 00158 inp_->set_changed(); 00159 // no need to call Fl_Widget::set_changed() 00160 } 00162 void clear() { menu_->clear(); } 00164 Fl_Boxtype down_box() const { return (menu_->down_box()); } 00166 void down_box(Fl_Boxtype b) { menu_->down_box(b); } 00168 const Fl_Menu_Item *menu() { return (menu_->menu()); } 00170 void menu(const Fl_Menu_Item *m) { menu_->menu(m); } 00171 void resize(int X, int Y, int W, int H) { 00172 Fl_Group::resize(X,Y,W,H); 00173 inp_->resize(inp_x(), inp_y(), inp_w(), inp_h()); 00174 menu_->resize(menu_x(), menu_y(), menu_w(), menu_h()); 00175 } 00177 Fl_Color textcolor() const { return (inp_->textcolor());} 00179 void textcolor(Fl_Color c) { inp_->textcolor(c);} 00181 Fl_Font textfont() const { return (inp_->textfont());} 00183 void textfont(Fl_Font f) { inp_->textfont(f);} 00185 Fl_Fontsize textsize() const { return (inp_->textsize()); } 00187 void textsize(Fl_Fontsize s) { inp_->textsize(s); } 00189 const char* value() const { return (inp_->value()); } 00192 void value(const char *val) { inp_->value(val); } 00195 void value(int val) { 00196 menu_->value(val); 00197 inp_->value(menu_->text(val)); 00198 } 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 //