Ticket #7182: menu.diff

File menu.diff, 7.6 KB (added by Pete, 8 years ago)

Style fix of previous

  • headers/private/interface/MenuPrivate.h

     
    11/*
    2  * Copyright 2006-2008, Haiku, Inc.
     2 * Copyright 2006-2011, Haiku, Inc.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    1414enum menu_states {
    1515    MENU_STATE_TRACKING = 0,
    1616    MENU_STATE_TRACKING_SUBMENU = 1,
     17    MENU_STATE_KEY_TO_SUBMENU = 2,
     18    MENU_STATE_KEY_LEAVE_SUBMENU = 3,
    1719    MENU_STATE_CLOSED = 5
    1820};
    1921
  • src/kits/interface/Menu.cpp

     
    11/*
    2  * Copyright 2001-2009, Haiku Inc. All rights reserved.
     2 * Copyright 2001-2011, Haiku Inc. All rights reserved.
    33 * Distributed under the terms of the MIT license.
    44 *
    55 * Authors:
     
    477477            break;
    478478
    479479        case B_DOWN_ARROW:
     480            {
     481                BMenuBar* bar = dynamic_cast<BMenuBar*>(Supermenu());
     482                if (bar != NULL && fState == MENU_STATE_CLOSED) {
     483                    // tell MenuBar's _Track:
     484                    bar->fState = MENU_STATE_KEY_TO_SUBMENU;
     485                }
     486            }
    480487            if (fLayout == B_ITEMS_IN_COLUMN)
    481488                _SelectNextItem(fSelected, true);
    482489            break;
     
    494501                        // another top level menu.
    495502                        BMessenger msgr(Supermenu());
    496503                        msgr.SendMessage(Window()->CurrentMessage());
    497                     } else
    498                         _QuitTracking();
     504                    } else {
     505                        // tell _Track
     506                        fState = MENU_STATE_KEY_LEAVE_SUBMENU;
     507                    }
    499508                }
    500509            }
    501510            break;
     
    505514                _SelectNextItem(fSelected, true);
    506515            else {
    507516                if (fSelected && fSelected->Submenu()) {
    508                     fSelected->Submenu()->_SetStickyMode(true); 
     517                    fSelected->Submenu()->_SetStickyMode(true);
    509518                        // fix me: this shouldn't be needed but dynamic menus
    510519                        // aren't getting it set correctly when keyboard
    511520                        // navigating, which aborts the attach
     521                    fState = MENU_STATE_KEY_TO_SUBMENU;
    512522                    _SelectItem(fSelected, true, true, true);
    513523                } else if (dynamic_cast<BMenuBar*>(Supermenu())) {
    514524                    // if we have no submenu and we're an
     
    539549        case B_ENTER:
    540550        case B_SPACE:
    541551            if (fSelected) {
    542                 _InvokeItem(fSelected);
     552                // preserve for exit handling
     553                fChosenItem = fSelected;
    543554                _QuitTracking(false);
    544555            }
    545556            break;
    546557
    547558        case B_ESCAPE:
    548             _QuitTracking();
     559            _SelectItem(NULL);
     560            if (fState == MENU_STATE_CLOSED && dynamic_cast<BMenuBar*>(Supermenu())) {
     561                // Keyboard may show menu without tracking it
     562                BMessenger msgr(Supermenu());
     563                msgr.SendMessage(Window()->CurrentMessage());
     564            } else
     565                _QuitTracking(false);
    549566            break;
    550567
    551568        default:
     
    15801597    bigtime_t navigationAreaTime = 0;
    15811598
    15821599    fState = MENU_STATE_TRACKING;
    1583     if (fSuper != NULL)
    1584         fSuper->fState = MENU_STATE_TRACKING_SUBMENU;
     1600    // we will use this for keyboard selection:
     1601    fChosenItem = NULL;
    15851602
    15861603    BPoint location;
    15871604    uint32 buttons = 0;
     
    16081625        // The order of the checks is important
    16091626        // to be able to handle overlapping menus:
    16101627        // first we check if mouse is inside a submenu,
    1611         // then if the menu is inside this menu,
     1628        // then if the mouse is inside this menu,
    16121629        // then if it's over a super menu.
    16131630        bool overSub = _OverSubmenu(fSelected, screenLocation);
    16141631        item = _HitTestItems(location, B_ORIGIN);
    1615         if (overSub) {
     1632        if (overSub || fState == MENU_STATE_KEY_TO_SUBMENU) {
     1633            if (fState == MENU_STATE_TRACKING) {
     1634                // not if from R.Arrow
     1635                fState = MENU_STATE_TRACKING_SUBMENU;
     1636            }
    16161637            navAreaRectAbove = BRect();
    16171638            navAreaRectBelow = BRect();
    16181639
     
    16331654            if (submenuAction == MENU_STATE_CLOSED) {
    16341655                item = submenuItem;
    16351656                fState = MENU_STATE_CLOSED;
    1636             }
     1657            } else if (submenuAction == MENU_STATE_KEY_LEAVE_SUBMENU) {
     1658                if (LockLooper()) {
     1659                    BMenuItem *temp = fSelected;
     1660                    // close the submenu:
     1661                    _SelectItem(NULL);
     1662                    // but reselect the item itself for user:
     1663                    _SelectItem(temp, false);
     1664                    UnlockLooper();
     1665                }
     1666                // cancel  key-nav state
     1667                fState = MENU_STATE_TRACKING;
     1668            } else
     1669                fState = MENU_STATE_TRACKING;
    16371670            if (!LockLooper())
    16381671                break;
    16391672        } else if (item != NULL) {
     
    16411674                navAreaRectBelow, selectedTime, navigationAreaTime);
    16421675            if (!releasedOnce)
    16431676                releasedOnce = true;
    1644         } else if (_OverSuper(screenLocation)) {
     1677        } else if (_OverSuper(screenLocation) && fSuper->fState != MENU_STATE_KEY_TO_SUBMENU) {
    16451678            fState = MENU_STATE_TRACKING;
    16461679            UnlockLooper();
    16471680            break;
    1648         } else {
     1681        } else if (fState == MENU_STATE_KEY_LEAVE_SUBMENU) {
     1682            UnlockLooper();
     1683            break;
     1684        } else  if (fSuper == NULL || fSuper->fState != MENU_STATE_KEY_TO_SUBMENU) {
    16491685            // Mouse pointer outside menu:
    16501686            // If there's no other submenu opened,
    16511687            // deselect the current selected item
     
    16761712            uint32 newButtons = buttons;
    16771713
    16781714            // If user doesn't move the mouse, loop here,
    1679             // so we don't interfer with keyboard menu navigation
     1715            // so we don't interfere with keyboard menu navigation
    16801716            do {
    16811717                snooze(snoozeAmount);
    16821718                if (!LockLooper())
     
    16841720                GetMouse(&newLocation, &newButtons, true);
    16851721                UnlockLooper();
    16861722            } while (newLocation == location && newButtons == buttons
    1687                 && !(item && item->Submenu() != NULL));
     1723                && !(item && item->Submenu() != NULL)
     1724                && fState == MENU_STATE_TRACKING);
    16881725
    16891726            if (newLocation != location || newButtons != buttons) {
    16901727                if (!releasedOnce && newButtons == 0 && buttons != 0)
     
    17001737
    17011738    if (action != NULL)
    17021739        *action = fState;
     1740       
     1741    // keyboard Enter will set this
     1742    if (fChosenItem != NULL)
     1743        item = fChosenItem;
     1744    else if (fSelected == NULL)
     1745        // needed to cover (rare) mouse/ESC combination
     1746        item = NULL;
    17031747
    17041748    if (fSelected != NULL && LockLooper()) {
    17051749        _SelectItem(NULL);
    17061750        UnlockLooper();
    17071751    }
    1708 
     1752   
    17091753    // delete the menu window recycled for all the child menus
    17101754    _DeleteMenuWindow();
    17111755
     
    28292873    if (BMenuBar* menuBar = dynamic_cast<BMenuBar*>(this))
    28302874        menuBar->_RestoreFocus();
    28312875
    2832     fChosenItem = NULL;
    28332876    fState = MENU_STATE_CLOSED;
    28342877
    28352878    // Close the whole menu hierarchy
  • src/kits/interface/MenuBar.cpp

     
    566566    if (window->Lock()) {
    567567        if (startIndex != -1) {
    568568            be_app->ObscureCursor();
    569             _SelectItem(ItemAt(startIndex), true, true);
     569            _SelectItem(ItemAt(startIndex), true, false);
    570570        }
    571571        GetMouse(&where, &buttons);
    572572        window->Unlock();
     
    582582            menuItem = ItemAt(0);
    583583        else
    584584            menuItem = _HitTestItems(where, B_ORIGIN);
    585         if (_OverSubmenu(fSelected, ConvertToScreen(where))) {
     585        if (_OverSubmenu(fSelected, ConvertToScreen(where))
     586            || fState == MENU_STATE_KEY_TO_SUBMENU) {
    586587            // call _Track() from the selected sub-menu when the mouse cursor
    587588            // is over its window
    588589            BMenu* menu = fSelected->Submenu();
     
    645646
    646647        if (fState != MENU_STATE_CLOSED) {
    647648            // If user doesn't move the mouse, loop here,
    648             // so we don't interfer with keyboard menu navigation
     649            // so we don't interfere with keyboard menu navigation
    649650            BPoint newLocation = where;
    650651            uint32 newButtons = buttons;
    651652            do {
     
    654655                    break;
    655656                GetMouse(&newLocation, &newButtons, true);
    656657                UnlockLooper();
    657             } while (newLocation == where && newButtons == buttons);
     658            } while (newLocation == where && newButtons == buttons
     659                && fState == MENU_STATE_TRACKING);
    658660
    659661            where = newLocation;
    660662            buttons = newButtons;