summaryrefslogtreecommitdiff
path: root/src/Fl_Input_Choice.cxx
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2017-03-11 23:26:32 +0000
committerAlbrecht Schlosser <albrechts.fltk@online.de>2017-03-11 23:26:32 +0000
commita1d555bd8014679843e6f9c53f33d301b49326b8 (patch)
treeb7a337af4658795945f247e33815c8559dab49ad /src/Fl_Input_Choice.cxx
parent5544404f7a89a3d7e781f5e57d1271076485c91c (diff)
Separated Fl_Input_Choice.H and Fl_Input_Choice.cxx (STR #2750).
As proposed in STR #2750 and #2752: only status quo, i.e.: - no new method Fl_Input_Choice::maximum_size(int) (STR #2750 and #2752) - no handling of FL_Down key to open menu (STR #2752) git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12192 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Input_Choice.cxx')
-rw-r--r--src/Fl_Input_Choice.cxx220
1 files changed, 220 insertions, 0 deletions
diff --git a/src/Fl_Input_Choice.cxx b/src/Fl_Input_Choice.cxx
new file mode 100644
index 000000000..0735d869d
--- /dev/null
+++ b/src/Fl_Input_Choice.cxx
@@ -0,0 +1,220 @@
+//
+// "$Id$"
+//
+// An input/chooser widget.
+// ______________ ____
+// | || __ |
+// | input area || \/ |
+// |______________||____|
+//
+// Copyright 1998-2017 by Bill Spitzak and others.
+// Copyright 2004 by Greg Ercolano.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+/* \file
+ Fl_Input_Choice widget . */
+
+#include <FL/Fl_Input_Choice.H>
+
+#include <FL/fl_draw.H>
+#include <string.h>
+
+/**
+ \class Fl_Input_Choice
+
+ \brief A combination of the input widget and a menu button.
+
+ \image html input_choice.jpg
+ \image latex input_choice.jpg "Fl_Input_Choice widget" width=6cm
+
+ The user can either type into the input area, or use the
+ menu button chooser on the right to choose an item which loads
+ the input area with the selected text.
+
+ The application can directly access both the internal Fl_Input
+ and Fl_Menu_Button widgets respectively using the input() and menubutton()
+ accessor methods.
+
+ The default behavior is to invoke the Fl_Input_Choice::callback()
+ if the user changes the input field's contents, either by typing,
+ pasting, or clicking a different item in the choice menu.
+
+ The callback can determine if an item was picked vs. typing
+ into the input field by checking the value of menubutton()->changed(),
+ which will be:
+
+ - 1: the user picked a different item in the choice menu
+ - 0: the user typed or pasted directly into the input field
+
+ Example use:
+ \code
+ #include <stdio.h>
+ #include <FL/Fl.H>
+ #include <FL/Fl_Double_Window.H>
+ #include <FL/Fl_Input_Choice.H>
+ void choice_cb(Fl_Widget *w, void *userdata) {
+ // Show info about the picked item
+ Fl_Input_Choice *choice = (Fl_Input_Choice*)w;
+ const Fl_Menu_Item *item = choice->menubutton()->mvalue();
+ printf("*** Choice Callback:\n");
+ printf(" item label()='%s'\n", item ? item->label() : "(No item)");
+ printf(" item value()=%d\n", choice->menubutton()->value());
+ printf(" input value()='%s'\n", choice->input()->value());
+ printf(" The user %s\n", choice->menubutton()->changed()
+ ? "picked a menu item"
+ : "typed text");
+ }
+ int main() {
+ Fl_Double_Window win(200,100,"Input Choice");
+ win.begin();
+ Fl_Input_Choice choice(10,10,100,30);
+ choice.callback(choice_cb, 0);
+ choice.add("Red");
+ choice.add("Orange");
+ choice.add("Yellow");
+ //choice.value("Red"); // uncomment to make "Red" default
+ win.end();
+ win.show();
+ return Fl::run();
+ }
+ \endcode
+*/
+
+/** Constructor for private menu button. */
+
+Fl_Input_Choice::InputMenuButton::InputMenuButton(int x,int y,int w,int h,const char*l)
+ :Fl_Menu_Button(x,y,w,h,l)
+{
+ box(FL_UP_BOX);
+};
+
+/** Draws the private menu button. */
+
+void Fl_Input_Choice::InputMenuButton::draw() {
+ draw_box(FL_UP_BOX, color());
+ fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor()));
+ int xc = x()+w()/2, yc=y()+h()/2;
+ fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3);
+ if (Fl::focus() == this) draw_focus();
+}
+
+
+/** Callback for the Fl_Input_Choice menu. */
+
+void Fl_Input_Choice::menu_cb(Fl_Widget*, void *data) {
+ Fl_Input_Choice *o=(Fl_Input_Choice *)data;
+ Fl_Widget_Tracker wp(o);
+ const Fl_Menu_Item *item = o->menubutton()->mvalue();
+ if (item && item->flags & (FL_SUBMENU|FL_SUBMENU_POINTER)) return; // ignore submenus
+ if (!strcmp(o->inp_->value(), o->menu_->text()))
+ {
+ o->Fl_Widget::clear_changed();
+ if (o->when() & FL_WHEN_NOT_CHANGED)
+ o->do_callback();
+ }
+ else
+ {
+ o->inp_->value(o->menu_->text());
+ o->inp_->set_changed();
+ o->Fl_Widget::set_changed();
+ if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE))
+ o->do_callback();
+ }
+
+ if (wp.deleted()) return;
+
+ if (o->callback() != default_callback)
+ {
+ o->Fl_Widget::clear_changed();
+ o->inp_->clear_changed();
+ }
+}
+
+/** Callback for the Fl_Input_Choice input field. */
+
+void Fl_Input_Choice::inp_cb(Fl_Widget*, void *data) {
+ Fl_Input_Choice *o=(Fl_Input_Choice *)data;
+ Fl_Widget_Tracker wp(o);
+ if (o->inp_->changed()) {
+ o->Fl_Widget::set_changed();
+ if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE))
+ o->do_callback();
+ } else {
+ o->Fl_Widget::clear_changed();
+ if (o->when() & FL_WHEN_NOT_CHANGED)
+ o->do_callback();
+ }
+
+ if (wp.deleted()) return;
+
+ if (o->callback() != default_callback)
+ o->Fl_Widget::clear_changed();
+}
+
+/**
+ Creates a new Fl_Input_Choice widget using the given position, size,
+ and label string.
+
+ Inherited destructor destroys the widget and any values associated with it.
+*/
+Fl_Input_Choice::Fl_Input_Choice (int X, int Y, int W, int H, const char *L)
+: Fl_Group(X,Y,W,H,L) {
+ Fl_Group::box(FL_DOWN_BOX);
+ align(FL_ALIGN_LEFT); // default like Fl_Input
+ inp_ = new Fl_Input(inp_x(), inp_y(),
+ inp_w(), inp_h());
+ inp_->callback(inp_cb, (void*)this);
+ inp_->box(FL_FLAT_BOX); // cosmetic
+ inp_->when(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED);
+ menu_ = new InputMenuButton(menu_x(), menu_y(),
+ menu_w(), menu_h());
+ menu_->callback(menu_cb, (void*)this);
+ menu_->box(FL_FLAT_BOX); // cosmetic
+ end();
+}
+
+/** Resizes the Fl_Input_Choice widget.
+*/
+void Fl_Input_Choice::resize(int X, int Y, int W, int H) {
+ Fl_Group::resize(X,Y,W,H);
+ inp_->resize(inp_x(), inp_y(), inp_w(), inp_h());
+ menu_->resize(menu_x(), menu_y(), menu_w(), menu_h());
+}
+
+/** Chooses item# \p val in the menu, and sets the Fl_Input text field
+ to that value. Any previous text is cleared.
+ \see void value(const char *val)
+*/
+void Fl_Input_Choice::value(int val) {
+ menu_->value(val);
+ inp_->value(menu_->text(val));
+}
+
+/** Sets the changed() state of both input and menu button widgets
+ to the specified value.
+*/
+void Fl_Input_Choice::set_changed() {
+ inp_->set_changed();
+ // no need to call Fl_Widget::set_changed()
+}
+
+/** Clears the changed() state of both input and menu button widgets. */
+void Fl_Input_Choice::clear_changed() {
+ inp_->clear_changed();
+ Fl_Widget::clear_changed();
+}
+
+
+//
+// End of "$Id$".
+//