DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2752
Version: 1.3-feature
Option to enable Alt-Down when focus is on input field and Alt-Down or Down
arrow on button. Combo boxes in Windows also use down arrow to open.
Note, this also splits the Fl_Input_Choice.H in to a new
Fl_Input_Choice.cxx file to prevent potential inline functions, reducing
code bloat. It adds a convenence inline function maximum_size() to set on
input widget.
It will be hard to see the changes if the .H file is updated before using
the new split version.
Link: http://www.fltk.org/str.php?L2752
Version: 1.3-feature
Index: FL/Fl_Input_Choice.H
===================================================================
--- FL/Fl_Input_Choice.H (revision 9157)
+++ FL/Fl_Input_Choice.H (working copy)
@@ -24,6 +24,8 @@
/* \file
Fl_Input_Choice widget . */
+
+
#ifndef Fl_Input_Choice_H
#define Fl_Input_Choice_H
@@ -31,6 +33,9 @@
#include <FL/Fl_Group.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Menu_Button.H>
+
+// leaving these so builds don't break if user includes this header
+// and uses items from fl_draw or string (but dosen't include in src)
#include <FL/fl_draw.H>
#include <string.h>
@@ -48,69 +53,28 @@
class FL_EXPORT Fl_Input_Choice : public Fl_Group {
// Private class to handle slightly 'special' behavior of menu button
class InputMenuButton : public Fl_Menu_Button {
- void 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();
- }
+ void draw();
+
+ protected:
+ static const int FLAG_EX_ARROW_SHORTCUT=1; // allow arrow down to open
menu
+ int flags_ex_;
+
public:
- InputMenuButton(int X,int Y,int W,int H,const char*L=0) :
- Fl_Menu_Button(X, Y, W, H, L) { box(FL_UP_BOX); }
+ InputMenuButton(int X,int Y,int W,int H,const char*L=0);
+ int handle(int event);
+
+ void enable_arrow_shortcut(void) { flags_ex_ |= FLAG_EX_ARROW_SHORTCUT; };
+ void disable_arrow_shortcut(void) { flags_ex_ &= ~FLAG_EX_ARROW_SHORTCUT;
};
+ bool using_arrow_shortcut(void) { return (flags_ex_ &
FLAG_EX_ARROW_SHORTCUT)!=0; };
};
Fl_Input *inp_;
InputMenuButton *menu_;
- static void 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;
+ static void menu_cb(Fl_Widget*, void *data);
- if (o->callback() != default_callback)
- {
- o->Fl_Widget::clear_changed();
- o->inp_->clear_changed();
- }
- }
+ static void inp_cb(Fl_Widget*, void *data);
- static void 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();
- }
-
// Custom resize behavior -- input stretches, menu button doesn't
inline int inp_x() { return(x() + Fl::box_dx(box())); }
inline int inp_y() { return(y() + Fl::box_dy(box())); }
@@ -128,28 +92,14 @@
and label string.
<P> Inherited destructor Destroys the widget and any value associated with
it.
*/
- Fl_Input_Choice (int X,int Y,int W,int H,const char*L=0) :
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();
- }
+ Fl_Input_Choice (int X,int Y,int W,int H,const char*L=0);
+
+ int handle(int event);
/** Adds an item to the menu.*/
void add(const char *s) { menu_->add(s); }
int changed() const { return inp_->changed() | Fl_Widget::changed();}
- void clear_changed() {
- inp_->clear_changed();
- Fl_Widget::clear_changed();
- }
+ void clear_changed();
void set_changed() {
inp_->set_changed();
// no need to call Fl_Widget::set_changed()
@@ -164,11 +114,7 @@
const Fl_Menu_Item *menu() { return (menu_->menu()); }
/** Sets the Fl_Menu_Item array used for the menu. */
void menu(const Fl_Menu_Item *m) { menu_->menu(m); }
- void 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());
- }
+ void resize(int X, int Y, int W, int H);
/** Gets the encapsulated input text color attributes */
Fl_Color textcolor() const { return (inp_->textcolor());}
/** Sets the encapsulated input text color attributes */
@@ -192,16 +138,26 @@
*/
void value(const char *val) { inp_->value(val); }
/** See void Fl_Input_Choice::value(const char *s) */
- void value(int val) {
- menu_->value(val);
- inp_->value(menu_->text(val));
- }
+ void value(int val);
/** Returns a reference to the internal Fl_Menu_Button widget. */
Fl_Menu_Button *menubutton() { return menu_; }
/**
Returns a reference to the internal Fl_Input widget.</p>
*/
Fl_Input *input() { return inp_; }
+ /**
+ sets the maximum input size
+ */
+ void maximum_size(int size)
+ {
+ if (inp_)
+ inp_->maximum_size(size);
+ };
+
+ void enable_arrow_shortcut(void) { menu_->enable_arrow_shortcut(); };
+ void disable_arrow_shortcut(void) { menu_->disable_arrow_shortcut(); };
+ bool using_arrow_shortcut(void) { return menu_->using_arrow_shortcut(); };
+
};
#endif // !Fl_Input_Choice_H
Index: src/Fl_Input_Choice.cxx
===================================================================
--- src/Fl_Input_Choice.cxx (revision 0)
+++ src/Fl_Input_Choice.cxx (working copy)
@@ -0,0 +1,184 @@
+//
+// "$Id: Fl_Input_Choice.cxx "
+//
+// An input/chooser widget.
+// ______________ ____
+// | || __ |
+// | input area || \/ |
+// |______________||____|
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 2004 by Greg Ercolano.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// 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>
+
+/** Constructor for private 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)
+{
+ flags_ex_=0;
+ box(FL_UP_BOX);
+};
+
+/** Handle down arrow to open button */
+
+int Fl_Input_Choice::InputMenuButton::handle(int event)
+{
+ if (using_arrow_shortcut()) {
+ // captures all forms of down arrow to open menu.
+ if (event==FL_KEYBOARD && Fl::focus()==this && Fl::event_key()==FL_Down) {
+ popup();
+ return 1;
+ }
+ }
+
+ return Fl_Menu_Button::handle(event);
+}
+
+/** draw the 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 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();
+ }
+}
+
+/** call back for 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();
+}
+
+/** Constructor for Fl_Input_Choice widget using the given position, size,
+ and label string.
+ Inherited destructor Destroys the widget and any value 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();
+}
+
+/** Adds an item to the menu.*/
+void Fl_Input_Choice::clear_changed() {
+ inp_->clear_changed();
+ Fl_Widget::clear_changed();
+}
+
+/** resize the 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());
+}
+
+/** See void Fl_Input_Choice::value(const char *s) */
+void Fl_Input_Choice::value(int val) {
+ menu_->value(val);
+ inp_->value(menu_->text(val));
+}
+
+/** Handle down arrow to open button */
+
+int Fl_Input_Choice::handle(int event)
+{
+ // this captures Alt-Down arrow when input field has kb focus
+ // because a normal down arrow is already eaten by the Fl_Input
+ // object (receives handle first when it has focus). If you want
+ // the down arrow to work too, you'd need to subclass Fl_Input
+ // and override handle()
+ if (using_arrow_shortcut()) {
+ if (event==FL_KEYBOARD && Fl::focus()==inp_ && Fl::event_key()==FL_Down) {
+ menu_->popup();
+ return 1;
+ }
+ }
+ return Fl_Group::handle(event);
+}
+
Index: src/Makefile
===================================================================
--- src/Makefile (revision 9157)
+++ src/Makefile (working copy)
@@ -45,6 +45,7 @@
Fl_Image.cxx \
Fl_Input.cxx \
Fl_Input_.cxx \
+ Fl_Input_Choice.cxx \
Fl_Light_Button.cxx \
Fl_Menu.cxx \
Fl_Menu_.cxx \
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev