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:
Stefano Ceccherini 2006-08-17 06:12:48 +00:00
parent 5591ec214e
commit 4e338ac6df
2 changed files with 47 additions and 61 deletions

View File

@ -781,68 +781,35 @@ BMenu::MessageReceived(BMessage *msg)
void void
BMenu::KeyDown(const char *bytes, int32 numBytes) BMenu::KeyDown(const char *bytes, int32 numBytes)
{ {
// TODO: Test how it works on beos and implement it correctly
switch (bytes[0]) { switch (bytes[0]) {
/*case B_UP_ARROW: case B_UP_ARROW:
{ if (fLayout == B_ITEMS_IN_COLUMN)
if (fSelected) { SelectNextItem(fSelected, false);
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;
break; break;
}
case B_DOWN_ARROW: case B_DOWN_ARROW:
{ if (fLayout == B_ITEMS_IN_COLUMN)
if (fSelected) { SelectNextItem(fSelected, true);
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;
break; 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; 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; break;
}
case B_ENTER: case B_ENTER:
case B_SPACE: case B_SPACE:
{
if (fSelected) if (fSelected)
InvokeItem(fSelected); InvokeItem(fSelected);
break; break;
}
*/
case B_ESCAPE: case B_ESCAPE:
QuitTracking(); QuitTracking();
break; break;
@ -1330,6 +1297,7 @@ BMenu::_track(int *action, bigtime_t trackTime, long start)
if (IsStickyMode()) if (IsStickyMode())
submenu->SetStickyMode(true); submenu->SetStickyMode(true);
BMenuItem *submenuItem = submenu->_track(&submenuAction, trackTime); BMenuItem *submenuItem = submenu->_track(&submenuAction, trackTime);
//submenu->Window()->Activate();
if (submenuAction == MENU_STATE_CLOSED) { if (submenuAction == MENU_STATE_CLOSED) {
item = submenuItem; item = submenuItem;
fState = submenuAction; fState = submenuAction;
@ -1910,9 +1878,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 "selectFirstItem"
// Avoid deselecting and then reselecting the same item // Avoid deselecting and then reselecting the same item
// which would cause flickering // which would cause flickering
if (menuItem != fSelected) { if (menuItem != fSelected) {
@ -1930,8 +1896,10 @@ BMenu::SelectItem(BMenuItem *menuItem, uint32 showSubmenu, bool selectFirstItem)
if (fSelected != NULL && showSubmenu == 0) { if (fSelected != NULL && showSubmenu == 0) {
BMenu *subMenu = fSelected->Submenu(); BMenu *subMenu = fSelected->Submenu();
if (subMenu != NULL && subMenu->Window() == NULL) if (subMenu != NULL && subMenu->Window() == NULL) {
subMenu->_show(); subMenu->_show(selectFirstItem);
subMenu->Window()->Activate();
}
} }
} }
@ -1958,6 +1926,13 @@ BMenu::SelectNextItem(BMenuItem *item, bool forward)
BMenuItem * BMenuItem *
BMenu::NextItem(BMenuItem *item, bool forward) const 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); int32 index = fItems.IndexOf(item);
if (forward) if (forward)
index++; index++;
@ -2133,6 +2108,7 @@ BMenu::QuitTracking()
if (BMenuBar *menuBar = dynamic_cast<BMenuBar *>(this)) if (BMenuBar *menuBar = dynamic_cast<BMenuBar *>(this))
menuBar->RestoreFocus(); menuBar->RestoreFocus();
fChosenItem = NULL;
fState = MENU_STATE_CLOSED; fState = MENU_STATE_CLOSED;
} }

View File

@ -391,7 +391,14 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
// TODO: Cleanup, merge some "if" blocks if possible // TODO: Cleanup, merge some "if" blocks if possible
BMenuItem *resultItem = NULL; BMenuItem *resultItem = NULL;
BWindow *window = Window(); 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) { while (true) {
bigtime_t snoozeAmount = 40000; bigtime_t snoozeAmount = 40000;
bool locked = window->Lock();//WithTimeout(200000) bool locked = window->Lock();//WithTimeout(200000)
@ -421,7 +428,7 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
} else { } else {
// Menu was already opened, close it and bail // Menu was already opened, close it and bail
SelectItem(NULL); SelectItem(NULL);
localAction = MENU_STATE_CLOSED; fState = MENU_STATE_CLOSED;
resultItem = NULL; resultItem = NULL;
} }
} else { } else {
@ -441,9 +448,14 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
snoozeAmount = 30000; snoozeAmount = 30000;
if (IsStickyMode()) if (IsStickyMode())
menu->SetStickyMode(true); menu->SetStickyMode(true);
int localAction;
resultItem = menu->_track(&localAction, system_time()); 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); SelectItem(NULL);
fState = MENU_STATE_TRACKING; fState = MENU_STATE_TRACKING;
} }
@ -451,10 +463,8 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
if (locked) if (locked)
window->Unlock(); window->Unlock();
if (fState == MENU_STATE_CLOSED) if (fState == MENU_STATE_CLOSED
break; || (buttons != 0 && IsStickyMode() && menuItem == NULL))
if (localAction == MENU_STATE_CLOSED || (buttons != 0 && IsStickyMode() && menuItem == NULL))
break; break;
else if (buttons == 0 && !IsStickyMode()) { else if (buttons == 0 && !IsStickyMode()) {
// On an item without a submenu // On an item without a submenu
@ -484,7 +494,7 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
DeleteMenuWindow(); DeleteMenuWindow();
if (action != NULL) if (action != NULL)
*action = static_cast<int32>(localAction); *action = fState;
return resultItem; return resultItem;
} }