Fl_Input_Choice.H 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. //
  2. // "$Id: Fl_Input_Choice.H 9740 2012-12-09 17:45:24Z manolo $"
  3. //
  4. // An input/chooser widget.
  5. // ______________ ____
  6. // | || __ |
  7. // | input area || \/ |
  8. // |______________||____|
  9. //
  10. // Copyright 1998-2010 by Bill Spitzak and others.
  11. // Copyright 2004 by Greg Ercolano.
  12. //
  13. // This library is free software. Distribution and use rights are outlined in
  14. // the file "COPYING" which should have been included with this file. If this
  15. // file is missing or damaged, see the license at:
  16. //
  17. // http://www.fltk.org/COPYING.php
  18. //
  19. // Please report all bugs and problems on the following page:
  20. //
  21. // http://www.fltk.org/str.php
  22. //
  23. /* \file
  24. Fl_Input_Choice widget . */
  25. #ifndef Fl_Input_Choice_H
  26. #define Fl_Input_Choice_H
  27. #include <FL/Fl.H>
  28. #include <FL/Fl_Group.H>
  29. #include <FL/Fl_Input.H>
  30. #include <FL/Fl_Menu_Button.H>
  31. #include <FL/fl_draw.H>
  32. #include <string.h>
  33. /**
  34. A combination of the input widget and a menu button.
  35. \image html input_choice.jpg
  36. \image latex input_choice.jpg "Fl_Input_Choice widget" width=6cm
  37. The user can either type into the input area, or use the
  38. menu button chooser on the right to choose an item which loads
  39. the input area with the selected text.
  40. <P>
  41. The application can directly access both the internal Fl_Input
  42. and Fl_Menu_Button widgets respectively using the input() and menubutton()
  43. accessor methods.
  44. */
  45. class FL_EXPORT Fl_Input_Choice : public Fl_Group {
  46. // Private class to handle slightly 'special' behavior of menu button
  47. class InputMenuButton : public Fl_Menu_Button {
  48. void draw() {
  49. draw_box(FL_UP_BOX, color());
  50. fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor()));
  51. int xc = x()+w()/2, yc=y()+h()/2;
  52. fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3);
  53. if (Fl::focus() == this) draw_focus();
  54. }
  55. public:
  56. InputMenuButton(int X,int Y,int W,int H,const char*L=0) :
  57. Fl_Menu_Button(X, Y, W, H, L) { box(FL_UP_BOX); }
  58. };
  59. Fl_Input *inp_;
  60. InputMenuButton *menu_;
  61. static void menu_cb(Fl_Widget*, void *data) {
  62. Fl_Input_Choice *o=(Fl_Input_Choice *)data;
  63. Fl_Widget_Tracker wp(o);
  64. const Fl_Menu_Item *item = o->menubutton()->mvalue();
  65. if (item && item->flags & (FL_SUBMENU|FL_SUBMENU_POINTER)) return; // ignore submenus
  66. if (!strcmp(o->inp_->value(), o->menu_->text()))
  67. {
  68. o->Fl_Widget::clear_changed();
  69. if (o->when() & FL_WHEN_NOT_CHANGED)
  70. o->do_callback();
  71. }
  72. else
  73. {
  74. o->inp_->value(o->menu_->text());
  75. o->inp_->set_changed();
  76. o->Fl_Widget::set_changed();
  77. if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE))
  78. o->do_callback();
  79. }
  80. if (wp.deleted()) return;
  81. if (o->callback() != default_callback)
  82. {
  83. o->Fl_Widget::clear_changed();
  84. o->inp_->clear_changed();
  85. }
  86. }
  87. static void inp_cb(Fl_Widget*, void *data) {
  88. Fl_Input_Choice *o=(Fl_Input_Choice *)data;
  89. Fl_Widget_Tracker wp(o);
  90. if (o->inp_->changed()) {
  91. o->Fl_Widget::set_changed();
  92. if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE))
  93. o->do_callback();
  94. } else {
  95. o->Fl_Widget::clear_changed();
  96. if (o->when() & FL_WHEN_NOT_CHANGED)
  97. o->do_callback();
  98. }
  99. if (wp.deleted()) return;
  100. if (o->callback() != default_callback)
  101. o->Fl_Widget::clear_changed();
  102. }
  103. // Custom resize behavior -- input stretches, menu button doesn't
  104. inline int inp_x() { return(x() + Fl::box_dx(box())); }
  105. inline int inp_y() { return(y() + Fl::box_dy(box())); }
  106. inline int inp_w() { return(w() - Fl::box_dw(box()) - 20); }
  107. inline int inp_h() { return(h() - Fl::box_dh(box())); }
  108. inline int menu_x() { return(x() + w() - 20 - Fl::box_dx(box())); }
  109. inline int menu_y() { return(y() + Fl::box_dy(box())); }
  110. inline int menu_w() { return(20); }
  111. inline int menu_h() { return(h() - Fl::box_dh(box())); }
  112. public:
  113. /**
  114. Creates a new Fl_Input_Choice widget using the given position, size,
  115. and label string.
  116. Inherited destructor destroys the widget and any values associated with it.
  117. */
  118. Fl_Input_Choice(int X,int Y,int W,int H,const char*L=0);
  119. /** Adds an item to the menu.
  120. You can access the more complex Fl_Menu_Button::add() methods
  121. (setting callbacks, userdata, etc), via menubutton(). Example:
  122. \code
  123. Fl_Input_Choice *choice = new Fl_Input_Choice(100,10,120,25,"Fonts");
  124. Fl_Menu_Button *mb = choice->menubutton(); // use Fl_Input_Choice's Fl_Menu_Button
  125. mb->add("Helvetica", 0, MyFont_CB, (void*)mydata); // use Fl_Menu_Button's add() methods
  126. mb->add("Courier", 0, MyFont_CB, (void*)mydata);
  127. mb->add("More..", 0, FontDialog_CB, (void*)mydata);
  128. \endcode
  129. */
  130. void add(const char *s) { menu_->add(s); }
  131. /** Returns the combined changed() state of the input and menu button widget. */
  132. int changed() const { return inp_->changed() | Fl_Widget::changed();}
  133. /** Clears the changed() state of both input and menu button widgets. */
  134. void clear_changed() {
  135. inp_->clear_changed();
  136. Fl_Widget::clear_changed();
  137. }
  138. /** Sets the changed() state of both input and menu button widgets
  139. to the specfied value.*/
  140. void set_changed() {
  141. inp_->set_changed();
  142. // no need to call Fl_Widget::set_changed()
  143. }
  144. /** Removes all items from the menu. */
  145. void clear() { menu_->clear(); }
  146. /** Gets the box type of the menu button */
  147. Fl_Boxtype down_box() const { return (menu_->down_box()); }
  148. /** Sets the box type of the menu button */
  149. void down_box(Fl_Boxtype b) { menu_->down_box(b); }
  150. /** Gets the Fl_Menu_Item array used for the menu. */
  151. const Fl_Menu_Item *menu() { return (menu_->menu()); }
  152. /** Sets the Fl_Menu_Item array used for the menu. */
  153. void menu(const Fl_Menu_Item *m) { menu_->menu(m); }
  154. void resize(int X, int Y, int W, int H) {
  155. Fl_Group::resize(X,Y,W,H);
  156. inp_->resize(inp_x(), inp_y(), inp_w(), inp_h());
  157. menu_->resize(menu_x(), menu_y(), menu_w(), menu_h());
  158. }
  159. /// Gets the Fl_Input text field's text color.
  160. Fl_Color textcolor() const { return (inp_->textcolor());}
  161. /// Sets the Fl_Input text field's text color to \p c.
  162. void textcolor(Fl_Color c) { inp_->textcolor(c);}
  163. /// Gets the Fl_Input text field's font style.
  164. Fl_Font textfont() const { return (inp_->textfont());}
  165. /// Sets the Fl_Input text field's font style to \p f.
  166. void textfont(Fl_Font f) { inp_->textfont(f);}
  167. /// Gets the Fl_Input text field's font size
  168. Fl_Fontsize textsize() const { return (inp_->textsize()); }
  169. /// Sets the Fl_Input text field's font size to \p s.
  170. void textsize(Fl_Fontsize s) { inp_->textsize(s); }
  171. /// Returns the Fl_Input text field's current contents.
  172. const char* value() const { return (inp_->value()); }
  173. /** Sets the Fl_Input text field's contents to \p val.
  174. Does not affect the menu selection.*/
  175. void value(const char *val) { inp_->value(val); }
  176. /** Chooses item# \p val in the menu, and sets the Fl_Input text field
  177. to that value. Any previous text is cleared.*/
  178. void value(int val) {
  179. menu_->value(val);
  180. inp_->value(menu_->text(val));
  181. }
  182. /** Returns a pointer to the internal Fl_Menu_Button widget.
  183. This can be used to access any of the methods of the menu button, e.g.
  184. \code
  185. Fl_Input_Choice *choice = new Fl_Input_Choice(100,10,120,25,"Choice:");
  186. [..]
  187. // Print all the items in the choice menu
  188. for ( int t=0; t<choice->menubutton()->size(); t++ ) {
  189. const Fl_Menu_Item &item = choice->menubutton()->menu()[t];
  190. printf("item %d -- label=%s\n", t, item.label() ? item.label() : "(Null)");
  191. }
  192. \endcode
  193. */
  194. Fl_Menu_Button *menubutton() { return menu_; }
  195. /** Returns a pointer to the internal Fl_Input widget.
  196. This can be used to directly access all of the Fl_Input widget's
  197. methods.*/
  198. Fl_Input *input() { return inp_; }
  199. DECLARE_CLASS_CHEAP_RTTI_2(Fl_Input_Choice, Fl_Group)
  200. };
  201. #endif // !Fl_Input_Choice_H
  202. //
  203. // End of "$Id: Fl_Input_Choice.H 9740 2012-12-09 17:45:24Z manolo $".
  204. //