From 9ff75b2d07160f1eda230de6046271a7bddf70a9 Mon Sep 17 00:00:00 2001 From: Jorge Arellano Cid Date: Wed, 31 Oct 2012 23:43:33 -0300 Subject: 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 --- dw/fltkui.cc | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'dw/fltkui.cc') 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; } -- cgit v1.2.3