2 // "$Id: Fl_Input_Choice.H 8022 2010-12-12 23:21:03Z AlbrechtS $"
4 // An input/chooser widget.
7 // | input area || \/ |
8 // |______________||____|
10 // Copyright 1998-2010 by Bill Spitzak and others.
11 // Copyright 2004 by Greg Ercolano.
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Library General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Library General Public License for more details.
23 // You should have received a copy of the GNU Library General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 // Please report all bugs and problems on the following page:
30 // http://www.fltk.org/str.php
34 Fl_Input_Choice widget . */
38 #ifndef Fl_Input_Choice_H
39 #define Fl_Input_Choice_H
42 #include <FL/Fl_Group.H>
43 #include <FL/Fl_Input.H>
44 #include <FL/Fl_Menu_Button.H>
45 #include <FL/fl_draw.H>
49 A combination of the input widget and a menu button.
50 The user can either type into the input area, or use the
51 menu button chooser on the right, which loads the input area
52 with predefined text. Normally it is drawn with an inset box
53 and a white background.
55 The application can directly access both the input and menu
56 widgets directly, using the menubutton()
57 and input() accessor methods.
59 class FL_EXPORT Fl_Input_Choice : public Fl_Group {
60 // Private class to handle slightly 'special' behavior of menu button
61 class InputMenuButton : public Fl_Menu_Button {
63 draw_box(FL_UP_BOX, color());
64 fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor()));
65 int xc = x()+w()/2, yc=y()+h()/2;
66 fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3);
67 if (Fl::focus() == this) draw_focus();
70 InputMenuButton(int x,int y,int w,int h,const char*l=0) :
71 Fl_Menu_Button(x,y,w,h,l) { box(FL_UP_BOX); }
75 InputMenuButton *menu_;
77 static void menu_cb(Fl_Widget*, void *data) {
78 Fl_Input_Choice *o=(Fl_Input_Choice *)data;
79 Fl_Widget_Tracker wp(o);
80 const Fl_Menu_Item *item = o->menubutton()->mvalue();
81 if (item && item->flags & (FL_SUBMENU|FL_SUBMENU_POINTER)) return; // ignore submenus
82 if (!strcmp(o->inp_->value(), o->menu_->text()))
84 o->Fl_Widget::clear_changed();
85 if (o->when() & FL_WHEN_NOT_CHANGED)
90 o->inp_->value(o->menu_->text());
91 o->inp_->set_changed();
92 o->Fl_Widget::set_changed();
93 if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE))
97 if (wp.deleted()) return;
99 if (o->callback() != default_callback)
101 o->Fl_Widget::clear_changed();
102 o->inp_->clear_changed();
106 static void inp_cb(Fl_Widget*, void *data) {
107 Fl_Input_Choice *o=(Fl_Input_Choice *)data;
108 Fl_Widget_Tracker wp(o);
109 if (o->inp_->changed()) {
110 o->Fl_Widget::set_changed();
111 if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE))
114 o->Fl_Widget::clear_changed();
115 if (o->when() & FL_WHEN_NOT_CHANGED)
119 if (wp.deleted()) return;
121 if (o->callback() != default_callback)
122 o->Fl_Widget::clear_changed();
125 // Custom resize behavior -- input stretches, menu button doesn't
126 inline int inp_x() { return(x() + Fl::box_dx(box())); }
127 inline int inp_y() { return(y() + Fl::box_dy(box())); }
128 inline int inp_w() { return(w() - Fl::box_dw(box()) - 20); }
129 inline int inp_h() { return(h() - Fl::box_dh(box())); }
131 inline int menu_x() { return(x() + w() - 20 - Fl::box_dx(box())); }
132 inline int menu_y() { return(y() + Fl::box_dy(box())); }
133 inline int menu_w() { return(20); }
134 inline int menu_h() { return(h() - Fl::box_dh(box())); }
138 Creates a new Fl_Input_Choice widget using the given position, size,
140 <P> Inherited destructor Destroys the widget and any value associated with it.
142 Fl_Input_Choice (int x,int y,int w,int h,const char*l=0) : Fl_Group(x,y,w,h,l) {
143 Fl_Group::box(FL_DOWN_BOX);
144 align(FL_ALIGN_LEFT); // default like Fl_Input
145 inp_ = new Fl_Input(inp_x(), inp_y(),
147 inp_->callback(inp_cb, (void*)this);
148 inp_->box(FL_FLAT_BOX); // cosmetic
149 inp_->when(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED);
150 menu_ = new InputMenuButton(menu_x(), menu_y(),
152 menu_->callback(menu_cb, (void*)this);
153 menu_->box(FL_FLAT_BOX); // cosmetic
157 /** Adds an item to the menu.*/
158 void add(const char *s) { menu_->add(s); }
159 int changed() const { return inp_->changed() | Fl_Widget::changed();}
160 void clear_changed() {
161 inp_->clear_changed();
162 Fl_Widget::clear_changed();
166 // no need to call Fl_Widget::set_changed()
168 /** Removes all items from the menu. */
169 void clear() { menu_->clear(); }
170 /** Gets the box type of the menu button */
171 Fl_Boxtype down_box() const { return (menu_->down_box()); }
172 /** Sets the box type of the menu button */
173 void down_box(Fl_Boxtype b) { menu_->down_box(b); }
174 /** Gets the Fl_Menu_Item array used for the menu. */
175 const Fl_Menu_Item *menu() { return (menu_->menu()); }
176 /** Sets the Fl_Menu_Item array used for the menu. */
177 void menu(const Fl_Menu_Item *m) { menu_->menu(m); }
178 void resize(int X, int Y, int W, int H) {
179 Fl_Group::resize(X,Y,W,H);
180 inp_->resize(inp_x(), inp_y(), inp_w(), inp_h());
181 menu_->resize(menu_x(), menu_y(), menu_w(), menu_h());
183 /** Gets the encapsulated input text color attributes */
184 Fl_Color textcolor() const { return (inp_->textcolor());}
185 /** Sets the encapsulated input text color attributes */
186 void textcolor(Fl_Color c) { inp_->textcolor(c);}
187 /** Gets the encapsulated input text font attributes */
188 Fl_Font textfont() const { return (inp_->textfont());}
189 /** Sets the encapsulated input text font attributes */
190 void textfont(Fl_Font f) { inp_->textfont(f);}
191 /** Gets the encapsulated input size attributes */
192 Fl_Fontsize textsize() const { return (inp_->textsize()); }
193 /** Sets the encapsulated input size attributes */
194 void textsize(Fl_Fontsize s) { inp_->textsize(s); }
195 /** See void Fl_Input_Choice::value(const char *s) */
196 const char* value() const { return (inp_->value()); }
198 Sets or returns the input widget's current contents. The
199 second form sets the contents using the index into the menu
200 which you can set as an integer. Setting the value effectively
201 'chooses' this menu item, and sets it as the new input text,
202 deleting the previous text.
204 void value(const char *val) { inp_->value(val); }
205 /** See void Fl_Input_Choice::value(const char *s) */
206 void value(int val) {
208 inp_->value(menu_->text(val));
210 /** Returns a reference to the internal Fl_Menu_Button widget. */
211 Fl_Menu_Button *menubutton() { return menu_; }
213 Returns a reference to the internal Fl_Input widget.</p>
215 Fl_Input *input() { return inp_; }
218 #endif // !Fl_Input_Choice_H
221 // End of "$Id: Fl_Input_Choice.H 8022 2010-12-12 23:21:03Z AlbrechtS $".