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();
} }
+23 -37
View File
@@ -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) {
// only select the item
SelectItem(menuItem, -1);
if (menuItem->Submenu() != NULL) {
// open the menu
SelectItem(menuItem); SelectItem(menuItem);
BMenu *menu = menuItem->Submenu(); }
// TODO: Actually, this test shouldn't be needed, as }
// all BMenuBar's BMenuItems are BMenus.
if (fSelected != NULL) {
BMenu *menu = fSelected->Submenu();
if (menu != NULL) { 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(); window->Unlock();
snoozeAmount = 0;
resultItem = menu->_track(&localAction, startIndex); resultItem = menu->_track(&localAction);
if (window->LockWithTimeout(200000) < B_OK) if (window->LockWithTimeout(200000) < B_OK)
break; break;
} while (localAction != MENU_ACT_CLOSE);
}
if (window->IsLocked()) {
SelectItem(NULL);
Invalidate();
} }
} }
if (window->IsLocked())
window->Unlock(); window->Unlock();
if (buttons == 0 || localAction == MENU_ACT_CLOSE)
break;
snooze(40000); if (snoozeAmount > 0)
if (buttons == 0) snooze(snoozeAmount);
exitLoop = true;
} while (!exitLoop); } while (true);
if (action != NULL) if (fSelected != NULL) {
*action = static_cast<int>(localAction); window->Lock();
SelectItem(NULL);
window->Unlock();
}
if (resultItem != NULL) if (resultItem != NULL)
resultItem->Invoke(); resultItem->Invoke();