diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index a8e6e2d5a3..b15a933da4 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005, Haiku, Inc. + * Copyright 2001-2006, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -7,6 +7,7 @@ * Stefano Ceccherini (burton666@libero.it) */ + #include #include @@ -1110,22 +1111,23 @@ BMenu::_track(int *action, long start) ulong buttons; BMenuItem *item = NULL; int localAction = MENU_ACT_NONE; - + bigtime_t startTime = system_time(); bigtime_t clickTime = 0; get_click_speed(&clickTime); - + // TODO: Test and reduce the timeout if needed. clickTime /= 2; - + do { if (!LockLooper()) break; - + bigtime_t snoozeAmount = 50000; BPoint location; GetMouse(&location, &buttons, true); - + BPoint screenLocation = ConvertToScreen(location); + item = HitTestItems(location, B_ORIGIN); if (item != NULL) { if (item != fSelected) { @@ -1140,18 +1142,18 @@ BMenu::_track(int *action, long start) SelectItem(item); } } else { - if (OverSuper(location)) { + if (OverSuper(screenLocation)) { UnlockLooper(); break; } - if (fSelected != NULL && !OverSubmenu(fSelected, ConvertToScreen(location))) + if (fSelected != NULL && !OverSubmenu(fSelected, screenLocation)) SelectItem(NULL); } - - if (fSelected != NULL && fSelected->Submenu() != NULL + + if (item != NULL && fSelected != NULL && OverSubmenu(fSelected, screenLocation) && fSelected->Submenu()->Window() != NULL) { UnlockLooper(); - + int submenuAction = MENU_ACT_NONE; BMenuItem *submenuItem = fSelected->Submenu()->_track(&submenuAction); if (submenuAction == MENU_ACT_CLOSE) { @@ -1159,31 +1161,31 @@ BMenu::_track(int *action, long start) localAction = submenuAction; break; } - + if (!LockLooper()) break; } - + UnlockLooper(); snooze(snoozeAmount); } while (buttons != 0); - + if (localAction == MENU_ACT_NONE) { if (buttons != 0) localAction = MENU_ACT_NONE; else localAction = MENU_ACT_CLOSE; } - + if (action != NULL) *action = localAction; - + if (LockLooper()) { SelectItem(NULL); UnlockLooper(); } - + // delete the menu window recycled for all the child menus DeleteMenuWindow(); @@ -1543,9 +1545,7 @@ BMenu::OverSuper(BPoint location) { if (!Supermenu()) return false; - - ConvertToScreen(&location); - + return fSuperbounds.Contains(location); } @@ -1557,7 +1557,7 @@ BMenu::OverSubmenu(BMenuItem *item, BPoint loc) BMenu *subMenu = item->Submenu(); if (subMenu == NULL || subMenu->Window() == NULL) return false; - + if (subMenu->Window()->Frame().Contains(loc)) return true; diff --git a/src/kits/interface/MenuBar.cpp b/src/kits/interface/MenuBar.cpp index ac6e724b11..f1171fa59f 100644 --- a/src/kits/interface/MenuBar.cpp +++ b/src/kits/interface/MenuBar.cpp @@ -1,29 +1,12 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Menubar.cpp -// Authors: Marc Flerackers (mflerackers@androme.be) -// Stefano Ceccherini (burton666@libero.it) -// Description: BMenuBar is a menu that's at the root of a menu hierarchy. -//------------------------------------------------------------------------------ +/* + * Copyright 2001-2006, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marc Flerackers (mflerackers@androme.be) + * Stefano Ceccherini (burton666@libero.it) + */ + // TODO: Finish this class #include @@ -36,8 +19,8 @@ #include #include -struct menubar_data -{ + +struct menubar_data { BMenuBar *menuBar; int32 menuIndex; @@ -50,28 +33,28 @@ struct menubar_data BMenuBar::BMenuBar(BRect frame, const char *title, uint32 resizeMask, - menu_layout layout, bool resizeToFit) - : BMenu(frame, title, resizeMask, + menu_layout layout, bool resizeToFit) + : BMenu(frame, title, resizeMask, B_WILL_DRAW | B_FRAME_EVENTS, layout, resizeToFit), - fBorder(B_BORDER_FRAME), - fTrackingPID(-1), - fPrevFocusToken(-1), - fMenuSem(-1), - fLastBounds(NULL), - fTracking(false) + fBorder(B_BORDER_FRAME), + fTrackingPID(-1), + fPrevFocusToken(-1), + fMenuSem(-1), + fLastBounds(NULL), + fTracking(false) { InitData(layout); } BMenuBar::BMenuBar(BMessage *data) - : BMenu(data), - fBorder(B_BORDER_FRAME), - fTrackingPID(-1), - fPrevFocusToken(-1), - fMenuSem(-1), - fLastBounds(NULL), - fTracking(false) + : BMenu(data), + fBorder(B_BORDER_FRAME), + fTrackingPID(-1), + fPrevFocusToken(-1), + fMenuSem(-1), + fLastBounds(NULL), + fTracking(false) { int32 border; @@ -412,7 +395,9 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu) } } - if (fSelected != NULL) { + if (fSelected != NULL && OverSubmenu(fSelected, ConvertToScreen(where))) { + // call _track() from the selected sub-menu when the mouse cursor + // is over its window BMenu *menu = fSelected->Submenu(); if (menu != NULL) { window->Unlock(); @@ -423,7 +408,8 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu) if (!window->Lock())//WithTimeout(200000) < B_OK) break; } - } + } else if (menuItem == NULL) + SelectItem(NULL); window->Unlock();