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
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;
}

View File

@ -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;
}