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:
@@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user