Greatly improved BMenuBar::Track(). Now it uses a simple tracking loop instad of two nested loops. BMenu will follow, someday.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13150 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2005-06-15 11:37:05 +00:00
parent b497352618
commit 757ce6e540
2 changed files with 35 additions and 49 deletions
+2 -2
View File
@@ -1525,7 +1525,7 @@ BMenu::Uninstall()
void void
BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem) BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem)
{ {
// TODO: make use of "showSubmenu" and "selectFirstItem". // TODO: make use of "selectFirstItem".
if (fSelected != NULL) { if (fSelected != NULL) {
fSelected->Select(false); fSelected->Select(false);
if (fSelected->Submenu() != NULL) if (fSelected->Submenu() != NULL)
@@ -1536,7 +1536,7 @@ BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem)
menuItem->Select(true); menuItem->Select(true);
fSelected = menuItem; fSelected = menuItem;
if (fSelected != NULL && fSelected->Submenu() != NULL) if (fSelected != NULL && showSubmenu == 0 && fSelected->Submenu() != NULL)
fSelected->Submenu()->_show(); fSelected->Submenu()->_show();
} }
+30 -44
View File
@@ -1,4 +1,4 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2005, Haiku, Inc. // Copyright (c) 2001-2005, Haiku, Inc.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
@@ -395,13 +395,11 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
{ {
// TODO: This function is very incomplete and just partially working: // TODO: This function is very incomplete and just partially working:
// For example, it doesn't respect the "sticky mode" setting. // For example, it doesn't respect the "sticky mode" setting.
// Cleanup: We shouldn't use two nested loops. This simplifies the code
// but doesn't work well
BMenuItem *resultItem = NULL; BMenuItem *resultItem = NULL;
BWindow *window = Window(); BWindow *window = Window();
int localAction = MENU_ACT_NONE; int localAction = MENU_ACT_NONE;
bool exitLoop = false;
do { do {
bigtime_t snoozeAmount = 30000;
if (window->LockWithTimeout(200000) < B_OK) if (window->LockWithTimeout(200000) < B_OK)
break; break;
@@ -410,52 +408,40 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
GetMouse(&where, &buttons); GetMouse(&where, &buttons);
BMenuItem *menuItem = HitTestItems(where, B_ORIGIN); BMenuItem *menuItem = HitTestItems(where, B_ORIGIN);
if (menuItem != NULL) { if (menuItem != NULL && menuItem != fSelected) {
SelectItem(menuItem); // only select the item
BMenu *menu = menuItem->Submenu(); SelectItem(menuItem, -1);
// TODO: Actually, this test shouldn't be needed, as if (menuItem->Submenu() != NULL) {
// all BMenuBar's BMenuItems are BMenus. // open the menu
if (menu != NULL) { SelectItem(menuItem);
if (IsStickyPrefOn())
menu->SetStickyMode(true);
do {
snooze(40000);
GetMouse(&where, &buttons);
// If we aren't over this BMenu anymore, exit the tracking loop.
BMenuItem *testItem = HitTestItems(where, B_ORIGIN);
if (testItem != NULL && testItem != menuItem)
break;
// No need to keep the window locked for the
// whole time, as BMenu::_track() does its own locking.
window->Unlock();
resultItem = menu->_track(&localAction, startIndex);
if (window->LockWithTimeout(200000) < B_OK)
break;
} while (localAction != MENU_ACT_CLOSE);
}
if (window->IsLocked()) {
SelectItem(NULL);
Invalidate();
} }
} }
if (window->IsLocked()) if (fSelected != NULL) {
window->Unlock(); BMenu *menu = fSelected->Submenu();
if (menu != NULL) {
window->Unlock();
snoozeAmount = 0;
resultItem = menu->_track(&localAction);
if (window->LockWithTimeout(200000) < B_OK)
break;
}
}
snooze(40000); window->Unlock();
if (buttons == 0) if (buttons == 0 || localAction == MENU_ACT_CLOSE)
exitLoop = true; break;
} while (!exitLoop); if (snoozeAmount > 0)
snooze(snoozeAmount);
if (action != NULL) } while (true);
*action = static_cast<int>(localAction);
if (fSelected != NULL) {
window->Lock();
SelectItem(NULL);
window->Unlock();
}
if (resultItem != NULL) if (resultItem != NULL)
resultItem->Invoke(); resultItem->Invoke();