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
BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem)
{
// TODO: make use of "showSubmenu" and "selectFirstItem".
// TODO: make use of "selectFirstItem".
if (fSelected != NULL) {
fSelected->Select(false);
if (fSelected->Submenu() != NULL)
@@ -1536,7 +1536,7 @@ BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem)
menuItem->Select(true);
fSelected = menuItem;
if (fSelected != NULL && fSelected->Submenu() != NULL)
if (fSelected != NULL && showSubmenu == 0 && fSelected->Submenu() != NULL)
fSelected->Submenu()->_show();
}
+33 -47
View File
@@ -1,4 +1,4 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Copyright (c) 2001-2005, Haiku, Inc.
//
// 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:
// 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;
BWindow *window = Window();
int localAction = MENU_ACT_NONE;
bool exitLoop = false;
do {
bigtime_t snoozeAmount = 30000;
if (window->LockWithTimeout(200000) < B_OK)
break;
@@ -410,53 +408,41 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
GetMouse(&where, &buttons);
BMenuItem *menuItem = HitTestItems(where, B_ORIGIN);
if (menuItem != NULL) {
SelectItem(menuItem);
BMenu *menu = menuItem->Submenu();
// TODO: Actually, this test shouldn't be needed, as
// all BMenuBar's BMenuItems are BMenus.
if (menu != NULL) {
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 (menuItem != NULL && menuItem != fSelected) {
// only select the item
SelectItem(menuItem, -1);
if (menuItem->Submenu() != NULL) {
// open the menu
SelectItem(menuItem);
}
}
if (window->IsLocked())
window->Unlock();
snooze(40000);
if (buttons == 0)
exitLoop = true;
} while (!exitLoop);
if (action != NULL)
*action = static_cast<int>(localAction);
if (fSelected != NULL) {
BMenu *menu = fSelected->Submenu();
if (menu != NULL) {
window->Unlock();
snoozeAmount = 0;
resultItem = menu->_track(&localAction);
if (window->LockWithTimeout(200000) < B_OK)
break;
}
}
window->Unlock();
if (buttons == 0 || localAction == MENU_ACT_CLOSE)
break;
if (snoozeAmount > 0)
snooze(snoozeAmount);
} while (true);
if (fSelected != NULL) {
window->Lock();
SelectItem(NULL);
window->Unlock();
}
if (resultItem != NULL)
resultItem->Invoke();