diff options
author | Jorge Arellano Cid <jcid@dillo.org> | 2012-10-31 23:43:33 -0300 |
---|---|---|
committer | Jorge Arellano Cid <jcid@dillo.org> | 2012-10-31 23:43:33 -0300 |
commit | 9ff75b2d07160f1eda230de6046271a7bddf70a9 (patch) | |
tree | a3f49d728a56dd3aeb1a2c3b7329d7ada3e7189a | |
parent | 0c62630e68c0d6376ee04f163d48315c725ecf5c (diff) |
Implement some keystrokes as shortcuts to option menuitems
Jump to the next menuitem whose label starts with the pressed key.
If there's more than one item starting with the same letter, go to
the next one, then wrap.
This works when the OPTION menu is focused, not displayed.
FLTK has a hacked way of handling menus which will change in
FLTK3 [1] [2].
Making it work when the menu is displayed would involve copying a lot of
code and dealing with hackish FLTK internals, which is not stable. It
seems wiser to use this workaround until FLTK3 solves the problem.
[1] http://fltk.org/newsgroups.php?s1060+gfltk.general+v1070+T0+Qmenu+scrolling
[2] http://fltk.org/newsgroups.php?s1080+gfltk.general+v1087+T0+Qmenu+scrolling
-rw-r--r-- | dw/fltkui.cc | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/dw/fltkui.cc b/dw/fltkui.cc index 7d2f6cc5..5e4f3c56 100644 --- a/dw/fltkui.cc +++ b/dw/fltkui.cc @@ -75,6 +75,49 @@ int CustInput2::handle(int e) return Fl_Input::handle(e); } + +/* + * Used to handle some keystrokes as shortcuts to option menuitems + * (i.e. jump to the next menuitem whose label starts with the pressed key) + */ +class CustChoice : public Fl_Choice { +public: + CustChoice (int x, int y, int w, int h, const char* l=0) : + Fl_Choice(x,y,w,h,l) {}; + int handle(int e); +}; + +int CustChoice::handle(int e) +{ + int k = Fl::event_key(); + unsigned modifier = Fl::event_state() & (FL_SHIFT|FL_CTRL|FL_ALT|FL_META); + + _MSG("CustChoice::handle %p e=%d active=%d focus=%d\n", + this, e, active(), (Fl::focus() == this)); + if (Fl::focus() != this) { + ; // Not Focused, let FLTK handle it + } else if (e == FL_KEYDOWN) { + if (modifier == 0 && isalnum(k)) { + int t = value()+1 >= size() ? 0 : value()+1; + while (t != value()) { + const Fl_Menu_Item *mi = &(menu()[t]); + if (mi->submenu()) // submenu? + ; + else if (mi->label() && mi->active()) { // menu item? + if (k == tolower(mi->label()[0])) { + value(mi); + return 1; // Let FLTK know we used this key + } + } + if (++t == size()) + t = 0; + } + } + } + + return Fl_Choice::handle(e); +} + //---------------------------------------------------------------------------- namespace dw { @@ -995,9 +1038,9 @@ Fl_Widget *FltkOptionMenuResource::createNewWidget (core::Allocation *allocation) { Fl_Choice *choice = - new Fl_Choice (allocation->x, allocation->y, - allocation->width, - allocation->ascent + allocation->descent); + new CustChoice (allocation->x, allocation->y, + allocation->width, + allocation->ascent + allocation->descent); choice->menu(menu); return choice; } |