From 2105f203f18ef44e4710fc07148f1a2e5376cc68 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Thu, 11 Nov 2010 09:12:05 +0000 Subject: Fixed menu and shortcut handling (STR #2243). This partly reverts the fix for STR #2199 - for details see STR #2243. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7816 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_Menu.cxx | 52 +++++++++++++++++++++++++++----------------- src/Fl_Menu_Bar.cxx | 2 +- src/fl_shortcut.cxx | 62 ++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 87 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx index e341b868a..7f9df8e1f 100644 --- a/src/Fl_Menu.cxx +++ b/src/Fl_Menu.cxx @@ -956,44 +956,56 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown( } /** - This method is called by widgets that want to display menus. The menu - stays up until the user picks an item or dismisses it. The selected - item (or NULL if none) is returned. This does not do the - callbacks or change the state of check or radio items. -

X,Y is the position of the mouse cursor, relative to the + This method is called by widgets that want to display menus. + + The menu stays up until the user picks an item or dismisses it. + The selected item (or NULL if none) is returned. This does not + do the callbacks or change the state of check or radio items. + + X,Y is the position of the mouse cursor, relative to the window that got the most recent event (usually you can pass - Fl::event_x() and Fl::event_y() unchanged here).

-

title is a character string title for the menu. If - non-zero a small box appears above the menu with the title in it.

-

The menu is positioned so the cursor is centered over the item - picked. This will work even if picked is in a submenu. - If picked is zero or not in the menu item table the menu is - positioned with the cursor in the top-left corner.

-

button is a pointer to an - Fl_Menu_ from which the color and boxtypes for the menu are - pulled. If NULL then defaults are used. + Fl::event_x() and Fl::event_y() unchanged here). + + \p title is a character string title for the menu. If + non-zero a small box appears above the menu with the title in it. + + The menu is positioned so the cursor is centered over the item + picked. This will work even if \p picked is in a submenu. + If \p picked is zero or not in the menu item table the menu is + positioned with the cursor in the top-left corner. + + \p button is a pointer to an Fl_Menu_ from which the color and + boxtypes for the menu are pulled. If NULL then defaults are used. */ const Fl_Menu_Item* Fl_Menu_Item::popup( int X, int Y, const char* title, const Fl_Menu_Item* picked, - const Fl_Menu_* but + const Fl_Menu_* button ) const { static Fl_Menu_Item dummy; // static so it is all zeros dummy.text = title; - return pulldown(X, Y, 0, 0, picked, but, title ? &dummy : 0); + return pulldown(X, Y, 0, 0, picked, button, title ? &dummy : 0); } /** Search only the top level menu for a shortcut. - Either &x in the label or the shortcut fields are used. + Either &x in the label or the shortcut fields are used. + + This tests the current event, which must be an FL_KEYBOARD or + FL_SHORTCUT, against a shortcut value. + + \param ip returns the index of the item, if \p ip is not NULL. + \param require_alt if true: match only if Alt key is pressed. + + \return found Fl_Menu_Item or NULL */ -const Fl_Menu_Item* Fl_Menu_Item::find_shortcut(int* ip) const { +const Fl_Menu_Item* Fl_Menu_Item::find_shortcut(int* ip, const bool require_alt) const { const Fl_Menu_Item* m = first(); if (m) for (int ii = 0; m->text; m = m->next(), ii++) { if (m->activevisible()) { if (Fl::test_shortcut(m->shortcut_) - || Fl_Widget::test_shortcut(m->text)) { + || Fl_Widget::test_shortcut(m->text, require_alt)) { if (ip) *ip=ii; return m; } diff --git a/src/Fl_Menu_Bar.cxx b/src/Fl_Menu_Bar.cxx index 06a0003a2..c178805c2 100644 --- a/src/Fl_Menu_Bar.cxx +++ b/src/Fl_Menu_Bar.cxx @@ -65,7 +65,7 @@ int Fl_Menu_Bar::handle(int event) { return 1; case FL_SHORTCUT: if (visible_r()) { - v = menu()->find_shortcut(); + v = menu()->find_shortcut(0, true); if (v && v->submenu()) goto J1; } return test_shortcut() != 0; diff --git a/src/fl_shortcut.cxx b/src/fl_shortcut.cxx index ecd47f158..dc93450fc 100644 --- a/src/fl_shortcut.cxx +++ b/src/fl_shortcut.cxx @@ -54,9 +54,11 @@ /** Test the current event, which must be an FL_KEYBOARD or FL_SHORTCUT, against a shortcut value (described in - Fl_Button). Returns non-zero if there is a match. Not to - be confused with - Fl_Widget::test_shortcut(). + Fl_Button). + + Not to be confused with Fl_Widget::test_shortcut(). + + \return non-zero if there is a match. */ int Fl::test_shortcut(unsigned int shortcut) { if (!shortcut) return 0; @@ -292,6 +294,18 @@ unsigned int fl_old_shortcut(const char* s) { // Tests for &x shortcuts in button labels: +/** Returns the Unicode value of the '&x' shortcut in a given text. + + The given text \p t (usually a widget's label or a menu text) is + searched for a '&x' shortcut label, and if found, the Unicode + value of the '&x' shortcut is returned. + + \param t text or label to search for '&x' shortcut. + + \return Unicode (UCS-4) value of shortcut in \p t or 0. + + \note Internal use only. +*/ unsigned int Fl_Widget::label_shortcut(const char *t) { if (!t) return 0; for (;;) { @@ -306,12 +320,29 @@ unsigned int Fl_Widget::label_shortcut(const char *t) { } } -int Fl_Widget::test_shortcut(const char *t) { - #ifdef WIN32 - // on MSWindows, users expect shortcuts to work only when the Alt modifier is pressed - if (Fl::event_state(FL_ALT)==0) return 0; - #endif +/** Returns true if the given text \p t contains the entered '&x' shortcut. + + This method must only be called in handle() methods or callbacks after + a keypress event (usually FL_KEYDOWN or FL_SHORTCUT). The given text + \p t (usually a widget's label or menu text) is searched for a '&x' + shortcut, and if found, this is compared with the entered key value. + + Fl::event_text() is used to get the entered key value. + Fl::event_state() is used to get the Alt modifier, if \p require_alt + is true. + + \param t text or label to search for '&x' shortcut. + \param require_alt if true: match only if Alt key is pressed. + + \return true, if the entered text matches the '&x' shortcut in \p t + false (0) otherwise. + + \note Internal use only. +*/ +int Fl_Widget::test_shortcut(const char *t, const bool require_alt) { if (!t) return 0; + // for menubars etc. shortcuts must work only if the Alt modifier is pressed + if (require_alt && Fl::event_state(FL_ALT)==0) return 0; unsigned int c = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); if (!c) return 0; if (c == label_shortcut(t)) @@ -319,6 +350,21 @@ int Fl_Widget::test_shortcut(const char *t) { return 0; } +/** Returns true if the widget's label contains the entered '&x' shortcut. + + This method must only be called in handle() methods or callbacks after + a keypress event (usually FL_KEYDOWN or FL_SHORTCUT). + The widget's label is searched for a '&x' + shortcut, and if found, this is compared with the entered key value. + + Fl::event_text() is used to get the entered key value. + + \return true, if the entered text matches the widget's'&x' shortcut, + false (0) otherwise. + + \note Internal use only. +*/ + int Fl_Widget::test_shortcut() { if (!(flags()&SHORTCUT_LABEL)) return 0; return test_shortcut(label()); -- cgit v1.2.3