Started implementing menu keyboard navigation. Does only work for menubars because menu windows never get keyboard focus. Any idea how to solve this, since menu windows are B_AVOID_FOCUS both in beos and haiku?
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18517 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5591ec214e
commit
4e338ac6df
@ -781,68 +781,35 @@ BMenu::MessageReceived(BMessage *msg)
|
||||
void
|
||||
BMenu::KeyDown(const char *bytes, int32 numBytes)
|
||||
{
|
||||
// TODO: Test how it works on beos and implement it correctly
|
||||
switch (bytes[0]) {
|
||||
/*case B_UP_ARROW:
|
||||
{
|
||||
if (fSelected) {
|
||||
fSelected->fSelected = false;
|
||||
|
||||
if (fSelected == fItems.FirstItem())
|
||||
fSelected = static_cast<BMenuItem *>(fItems.LastItem());
|
||||
else
|
||||
fSelected = ItemAt(IndexOf(fSelected) - 1);
|
||||
} else
|
||||
fSelected = static_cast<BMenuItem *>(fItems.LastItem());
|
||||
|
||||
fSelected->fSelected = true;
|
||||
|
||||
case B_UP_ARROW:
|
||||
if (fLayout == B_ITEMS_IN_COLUMN)
|
||||
SelectNextItem(fSelected, false);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_DOWN_ARROW:
|
||||
{
|
||||
if (fSelected) {
|
||||
fSelected->fSelected = false;
|
||||
|
||||
if (fSelected == fItems.LastItem())
|
||||
fSelected = static_cast<BMenuItem *>(fItems.FirstItem());
|
||||
else
|
||||
fSelected = ItemAt(IndexOf(fSelected) + 1);
|
||||
} else
|
||||
fSelected = static_cast<BMenuItem *>(fItems.FirstItem());
|
||||
|
||||
fSelected->fSelected = true;
|
||||
|
||||
if (fLayout == B_ITEMS_IN_COLUMN)
|
||||
SelectNextItem(fSelected, true);
|
||||
break;
|
||||
}
|
||||
case B_HOME:
|
||||
{
|
||||
if (fSelected)
|
||||
fSelected->fSelected = false;
|
||||
|
||||
fSelected = static_cast<BMenuItem *>(fItems.FirstItem());
|
||||
fSelected->fSelected = true;
|
||||
|
||||
case B_LEFT_ARROW:
|
||||
if (fLayout == B_ITEMS_IN_ROW)
|
||||
SelectNextItem(fSelected, false);
|
||||
break;
|
||||
}
|
||||
case B_END:
|
||||
{
|
||||
if (fSelected)
|
||||
fSelected->fSelected = false;
|
||||
|
||||
fSelected = static_cast<BMenuItem *>(fItems.LastItem());
|
||||
fSelected->fSelected = true;
|
||||
|
||||
case B_RIGHT_ARROW:
|
||||
if (fLayout == B_ITEMS_IN_ROW)
|
||||
SelectNextItem(fSelected, true);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_ENTER:
|
||||
case B_SPACE:
|
||||
{
|
||||
if (fSelected)
|
||||
InvokeItem(fSelected);
|
||||
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case B_ESCAPE:
|
||||
QuitTracking();
|
||||
break;
|
||||
@ -1330,6 +1297,7 @@ BMenu::_track(int *action, bigtime_t trackTime, long start)
|
||||
if (IsStickyMode())
|
||||
submenu->SetStickyMode(true);
|
||||
BMenuItem *submenuItem = submenu->_track(&submenuAction, trackTime);
|
||||
//submenu->Window()->Activate();
|
||||
if (submenuAction == MENU_STATE_CLOSED) {
|
||||
item = submenuItem;
|
||||
fState = submenuAction;
|
||||
@ -1910,9 +1878,7 @@ BMenu::Uninstall()
|
||||
|
||||
void
|
||||
BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem)
|
||||
{
|
||||
// TODO: make use of "selectFirstItem"
|
||||
|
||||
{
|
||||
// Avoid deselecting and then reselecting the same item
|
||||
// which would cause flickering
|
||||
if (menuItem != fSelected) {
|
||||
@ -1930,8 +1896,10 @@ BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem)
|
||||
|
||||
if (fSelected != NULL && showSubmenu == 0) {
|
||||
BMenu *subMenu = fSelected->Submenu();
|
||||
if (subMenu != NULL && subMenu->Window() == NULL)
|
||||
subMenu->_show();
|
||||
if (subMenu != NULL && subMenu->Window() == NULL) {
|
||||
subMenu->_show(selectFirstItem);
|
||||
subMenu->Window()->Activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1958,6 +1926,13 @@ BMenu::SelectNextItem(BMenuItem *item, bool forward)
|
||||
BMenuItem *
|
||||
BMenu::NextItem(BMenuItem *item, bool forward) const
|
||||
{
|
||||
if (item == NULL) {
|
||||
if (forward)
|
||||
return ItemAt(CountItems() - 1);
|
||||
else
|
||||
return ItemAt(0);
|
||||
}
|
||||
|
||||
int32 index = fItems.IndexOf(item);
|
||||
if (forward)
|
||||
index++;
|
||||
@ -2133,6 +2108,7 @@ BMenu::QuitTracking()
|
||||
if (BMenuBar *menuBar = dynamic_cast<BMenuBar *>(this))
|
||||
menuBar->RestoreFocus();
|
||||
|
||||
fChosenItem = NULL;
|
||||
fState = MENU_STATE_CLOSED;
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,14 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
||||
// TODO: Cleanup, merge some "if" blocks if possible
|
||||
BMenuItem *resultItem = NULL;
|
||||
BWindow *window = Window();
|
||||
int localAction = fState = MENU_STATE_TRACKING;
|
||||
fState = MENU_STATE_TRACKING;
|
||||
|
||||
if (startIndex != -1) {
|
||||
be_app->ObscureCursor();
|
||||
window->Lock();
|
||||
SelectItem(ItemAt(startIndex), 0, true);
|
||||
window->Unlock();
|
||||
}
|
||||
while (true) {
|
||||
bigtime_t snoozeAmount = 40000;
|
||||
bool locked = window->Lock();//WithTimeout(200000)
|
||||
@ -421,7 +428,7 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
||||
} else {
|
||||
// Menu was already opened, close it and bail
|
||||
SelectItem(NULL);
|
||||
localAction = MENU_STATE_CLOSED;
|
||||
fState = MENU_STATE_CLOSED;
|
||||
resultItem = NULL;
|
||||
}
|
||||
} else {
|
||||
@ -441,9 +448,14 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
||||
snoozeAmount = 30000;
|
||||
if (IsStickyMode())
|
||||
menu->SetStickyMode(true);
|
||||
int localAction;
|
||||
resultItem = menu->_track(&localAction, system_time());
|
||||
//menu->Window()->Activate();
|
||||
if (localAction == MENU_STATE_CLOSED)
|
||||
fState = MENU_STATE_CLOSED;
|
||||
}
|
||||
} else if (menuItem == NULL && !IsStickyMode() && fState != MENU_STATE_TRACKING_SUBMENU) {
|
||||
} else if (menuItem == NULL && !IsStickyMode()
|
||||
&& fState != MENU_STATE_TRACKING_SUBMENU) {
|
||||
SelectItem(NULL);
|
||||
fState = MENU_STATE_TRACKING;
|
||||
}
|
||||
@ -451,10 +463,8 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
||||
if (locked)
|
||||
window->Unlock();
|
||||
|
||||
if (fState == MENU_STATE_CLOSED)
|
||||
break;
|
||||
|
||||
if (localAction == MENU_STATE_CLOSED || (buttons != 0 && IsStickyMode() && menuItem == NULL))
|
||||
if (fState == MENU_STATE_CLOSED
|
||||
|| (buttons != 0 && IsStickyMode() && menuItem == NULL))
|
||||
break;
|
||||
else if (buttons == 0 && !IsStickyMode()) {
|
||||
// On an item without a submenu
|
||||
@ -484,7 +494,7 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
||||
DeleteMenuWindow();
|
||||
|
||||
if (action != NULL)
|
||||
*action = static_cast<int32>(localAction);
|
||||
*action = fState;
|
||||
|
||||
return resultItem;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user