Improved menu focus handling

This commit is contained in:
Markus Gans 2015-11-07 23:16:09 +01:00
parent a41de9496f
commit b05a20943a
12 changed files with 224 additions and 208 deletions

View File

@ -1,3 +1,6 @@
2015-11-05 Markus Gans <guru.mail@muenster.de>
* Improved menu focus handling
2015-11-05 Markus Gans <guru.mail@muenster.de> 2015-11-05 Markus Gans <guru.mail@muenster.de>
* Menu bar navigation without menu drop down * Menu bar navigation without menu drop down

View File

@ -969,7 +969,7 @@ void FApplication::processMouseEvent()
if ( ! menu->containsMenuStructure(*mouse) ) if ( ! menu->containsMenuStructure(*mouse) )
{ {
menu->unselectItemInList(); menu->unselectItem();
menu->hide(); menu->hide();
menu->hideSubMenus(); menu->hideSubMenus();
menu->hideSuperMenus(); menu->hideSuperMenus();
@ -977,7 +977,7 @@ void FApplication::processMouseEvent()
} }
if ( ! open_menu && menuBar() if ( ! open_menu && menuBar()
&& menuBar()->hasSelectedMenuItem() && menuBar()->hasSelectedItem()
&& ! b_state.mouse_moved ) && ! b_state.mouse_moved )
{ {
if ( ! menuBar()->getGeometryGlobal().contains(*mouse) ) if ( ! menuBar()->getGeometryGlobal().contains(*mouse) )

View File

@ -14,7 +14,6 @@
FMenu::FMenu(FWidget* parent) FMenu::FMenu(FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(0) , item(0)
, selectedListItem(0)
, super_menu(0) , super_menu(0)
, maxItemWidth(0) , maxItemWidth(0)
, mouse_down(false) , mouse_down(false)
@ -26,7 +25,6 @@ FMenu::FMenu(FWidget* parent)
FMenu::FMenu (FString& txt, FWidget* parent) FMenu::FMenu (FString& txt, FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(0) , item(0)
, selectedListItem(0)
, super_menu(0) , super_menu(0)
, maxItemWidth(0) , maxItemWidth(0)
, mouse_down(false) , mouse_down(false)
@ -39,7 +37,6 @@ FMenu::FMenu (FString& txt, FWidget* parent)
FMenu::FMenu (const std::string& txt, FWidget* parent) FMenu::FMenu (const std::string& txt, FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(0) , item(0)
, selectedListItem(0)
, super_menu(0) , super_menu(0)
, maxItemWidth(0) , maxItemWidth(0)
, mouse_down(false) , mouse_down(false)
@ -52,7 +49,6 @@ FMenu::FMenu (const std::string& txt, FWidget* parent)
FMenu::FMenu (const char* txt, FWidget* parent) FMenu::FMenu (const char* txt, FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(0) , item(0)
, selectedListItem(0)
, super_menu(0) , super_menu(0)
, maxItemWidth(0) , maxItemWidth(0)
, mouse_down(false) , mouse_down(false)
@ -179,16 +175,15 @@ bool FMenu::isMenu (FWidget* w) const
void FMenu::hideSubMenus() void FMenu::hideSubMenus()
{ {
// hide all sub-menus // hide all sub-menus
if ( selectedListItem ) if ( hasSelectedItem() )
{ {
if ( selectedListItem->hasMenu() ) if ( getSelectedItem()->hasMenu() )
{ {
FMenu* m = selectedListItem->getMenu(); FMenu* m = getSelectedItem()->getMenu();
m->hideSubMenus(); m->hideSubMenus();
m->hide(); m->hide();
} }
selectedListItem->unsetSelected(); unselectItem();
selectedListItem = 0;
} }
} }
@ -202,13 +197,14 @@ void FMenu::hideSuperMenus()
if ( isMenuBar(super) ) if ( isMenuBar(super) )
{ {
FMenuBar* mbar = reinterpret_cast<FMenuBar*>(super); FMenuBar* mbar = reinterpret_cast<FMenuBar*>(super);
FMenuItem* selectedMenuItem = mbar->selectedMenuItem; FMenuItem* selectedMenuItem = mbar->getSelectedItem();
if ( selectedMenuItem ) if ( selectedMenuItem )
{ {
selectedMenuItem->unsetSelected(); selectedMenuItem->unsetSelected();
selectedMenuItem = 0; selectedMenuItem = 0;
mbar->mouse_down = false; mbar->mouse_down = false;
mbar->drop_down = false;
mbar->redraw(); mbar->redraw();
} }
} }
@ -225,7 +221,7 @@ void FMenu::hideSuperMenus()
bool FMenu::containsMenuStructure (int x, int y) const bool FMenu::containsMenuStructure (int x, int y) const
{ {
// Check mouse click position for item, menu and all sub menus // Check mouse click position for item, menu and all sub menus
FMenuItem* si = selectedListItem; FMenuItem* si = getSelectedItem();
if ( getGeometryGlobal().contains(x,y) ) if ( getGeometryGlobal().contains(x,y) )
return true; return true;
@ -264,12 +260,12 @@ bool FMenu::selectNextItem()
|| next->isSeparator() ); || next->isSeparator() );
if ( next == *iter ) if ( next == *iter )
return false; return false;
unselectItemInList(); unselectItem();
next->setSelected(); next->setSelected();
setSelectedItem(next);
next->setFocus(); next->setFocus();
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
selectedListItem = next;
redraw(); redraw();
break; break;
} }
@ -306,12 +302,12 @@ bool FMenu::selectPrevItem()
|| prev->isSeparator() ); || prev->isSeparator() );
if ( prev == *iter ) if ( prev == *iter )
return false; return false;
unselectItemInList(); unselectItem();
prev->setSelected(); prev->setSelected();
setSelectedItem(prev);
prev->setFocus(); prev->setFocus();
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
selectedListItem = prev;
redraw(); redraw();
break; break;
} }
@ -359,7 +355,7 @@ bool FMenu::hotkeyMenu (FKeyEvent*& ev)
if ( found ) if ( found )
{ {
unselectItemInList(); unselectItem();
hide(); hide();
hideSuperMenus(); hideSuperMenus();
ev->accept(); ev->accept();
@ -642,10 +638,10 @@ void FMenu::onKeyPress (FKeyEvent* ev)
{ {
case fc::Fkey_return: case fc::Fkey_return:
case fc::Fkey_enter: case fc::Fkey_enter:
if ( hasSelectedListItem() ) if ( hasSelectedItem() )
{ {
FMenuItem* sel_item = selectedListItem; FMenuItem* sel_item = getSelectedItem();
unselectItemInList(); unselectItem();
hide(); hide();
hideSuperMenus(); hideSuperMenus();
sel_item->processClicked(); sel_item->processClicked();
@ -664,9 +660,9 @@ void FMenu::onKeyPress (FKeyEvent* ev)
break; break;
case fc::Fkey_left: case fc::Fkey_left:
if ( hasSelectedListItem() && selectedListItem->hasMenu() ) if ( hasSelectedItem() && getSelectedItem()->hasMenu() )
{ {
FMenu* sub_menu = selectedListItem->getMenu(); FMenu* sub_menu = getSelectedItem()->getMenu();
if ( sub_menu->isVisible() ) if ( sub_menu->isVisible() )
hideSubMenus(); hideSubMenus();
else else
@ -678,14 +674,14 @@ void FMenu::onKeyPress (FKeyEvent* ev)
break; break;
case fc::Fkey_right: case fc::Fkey_right:
if ( hasSelectedListItem() && selectedListItem->hasMenu() ) if ( hasSelectedItem() && getSelectedItem()->hasMenu() )
{ {
FMenu* sub_menu = selectedListItem->getMenu(); FMenu* sub_menu = getSelectedItem()->getMenu();
if ( ! sub_menu->isVisible() ) if ( ! sub_menu->isVisible() )
{ {
// open sub menu // open sub menu
sub_menu->selectFirstItemInList(); sub_menu->selectFirstItem();
sub_menu->getSelectedListItem()->setFocus();; sub_menu->getSelectedItem()->setFocus();;
sub_menu->setVisible(); sub_menu->setVisible();
sub_menu->show(); sub_menu->show();
raiseWindow (sub_menu); raiseWindow (sub_menu);
@ -703,10 +699,17 @@ void FMenu::onKeyPress (FKeyEvent* ev)
case fc::Fkey_escape: case fc::Fkey_escape:
case fc::Fkey_escape_mintty: case fc::Fkey_escape_mintty:
unselectItemInList(); unselectItem();
hide(); hide();
hideSubMenus(); hideSubMenus();
hideSuperMenus(); hideSuperMenus();
activatePrevWindow();
getActiveWindow()->getFocusWidget()->setFocus();
getActiveWindow()->redraw();
if ( statusBar() )
statusBar()->drawMessage();
updateTerminal();
flush_out();
ev->accept(); ev->accept();
break; break;
@ -758,15 +761,15 @@ void FMenu::onMouseDown (FMouseEvent* ev)
FWidget* focused_widget = getFocusWidget(); FWidget* focused_widget = getFocusWidget();
FFocusEvent out (FocusOut_Event); FFocusEvent out (FocusOut_Event);
FApplication::queueEvent(focused_widget, &out); FApplication::queueEvent(focused_widget, &out);
if ( hasSelectedListItem() ) if ( hasSelectedItem() )
unselectItemInList(); unselectItem();
(*iter)->setSelected(); (*iter)->setSelected();
setSelectedItem(*iter);
(*iter)->setFocus(); (*iter)->setFocus();
if ( focused_widget ) if ( focused_widget )
focused_widget->redraw(); focused_widget->redraw();
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
selectedListItem = *iter;
focus_changed = true; focus_changed = true;
} }
++iter; ++iter;
@ -812,7 +815,7 @@ void FMenu::onMouseUp (FMouseEvent* ev)
&& mouse_x <= x2 && mouse_x <= x2
&& mouse_y == y ) && mouse_y == y )
{ {
unselectItemInList(); unselectItem();
hide(); hide();
hideSuperMenus(); hideSuperMenus();
(*iter)->processClicked(); (*iter)->processClicked();
@ -821,7 +824,7 @@ void FMenu::onMouseUp (FMouseEvent* ev)
++iter; ++iter;
} }
// Click on a non-FMenuItem (border or separator line) // Click on a non-FMenuItem (border or separator line)
unselectItemInList(); unselectItem();
hide(); hide();
hideSuperMenus(); hideSuperMenus();
} }
@ -870,12 +873,12 @@ void FMenu::onMouseMove (FMouseEvent* ev)
FFocusEvent out (FocusOut_Event); FFocusEvent out (FocusOut_Event);
FApplication::queueEvent(focused_widget, &out); FApplication::queueEvent(focused_widget, &out);
(*iter)->setSelected(); (*iter)->setSelected();
setSelectedItem(*iter);
(*iter)->setFocus(); (*iter)->setFocus();
if ( focused_widget ) if ( focused_widget )
focused_widget->redraw(); focused_widget->redraw();
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
selectedListItem = *iter;
focus_changed = true; focus_changed = true;
} }
} }
@ -886,8 +889,8 @@ void FMenu::onMouseMove (FMouseEvent* ev)
&& (*iter)->isSelected() ) && (*iter)->isSelected() )
{ {
(*iter)->unsetSelected(); (*iter)->unsetSelected();
if ( selectedListItem == *iter ) if ( getSelectedItem() == *iter )
selectedListItem = 0; setSelectedItem(0);
focus_changed = true; focus_changed = true;
} }
} }
@ -895,7 +898,7 @@ void FMenu::onMouseMove (FMouseEvent* ev)
} }
// Mouse is over border or separator // Mouse is over border or separator
if ( ! selectedListItem && statusBar() if ( ! hasSelectedItem() && statusBar()
&& getGeometryGlobal().contains(ev->getGlobalPos()) ) && getGeometryGlobal().contains(ev->getGlobalPos()) )
{ {
FString msg = getStatusbarMessage(); FString msg = getStatusbarMessage();
@ -919,7 +922,7 @@ void FMenu::onMouseMove (FMouseEvent* ev)
ev = new FMouseEvent (MouseMove_Event, p, g, b); ev = new FMouseEvent (MouseMove_Event, p, g, b);
setClickedWidget(menubar); setClickedWidget(menubar);
FMenuBar* mbar = reinterpret_cast<FMenuBar*>(menubar); FMenuBar* mbar = reinterpret_cast<FMenuBar*>(menubar);
mbar->onMouseDown(ev); mbar->onMouseMove(ev);
delete ev; delete ev;
} }
@ -984,40 +987,6 @@ void FMenu::setStatusbarMessage(FString msg)
item->setStatusbarMessage(msg); item->setStatusbarMessage(msg);
} }
//----------------------------------------------------------------------
void FMenu::selectFirstItemInList()
{
std::vector<FMenuItem*>::const_iterator iter, end;
iter = itemlist.begin();
end = itemlist.end();
if ( itemlist.empty() )
return;
if ( hasSelectedListItem() )
unselectItemInList();
while ( iter != end )
{
if ( (*iter)->isEnabled() && ! (*iter)->isSeparator() )
{
// select first enabled item
(*iter)->setSelected();
selectedListItem = *iter;
break;
}
++iter;
}
}
//----------------------------------------------------------------------
void FMenu::unselectItemInList()
{
if ( hasSelectedListItem() )
selectedListItem->unsetSelected();
selectedListItem = 0;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::cb_menuitem_activated (FWidget* widget, void*) void FMenu::cb_menuitem_activated (FWidget* widget, void*)
{ {

View File

@ -47,7 +47,6 @@ class FMenu : public FWindow, public FMenuList
{ {
private: private:
FMenuItem* item; FMenuItem* item;
FMenuItem* selectedListItem;
FWidget* super_menu; FWidget* super_menu;
uInt maxItemWidth; uInt maxItemWidth;
bool mouse_down; bool mouse_down;
@ -106,10 +105,6 @@ class FMenu : public FWindow, public FMenuList
void setSelected(); void setSelected();
void unsetSelected(); void unsetSelected();
bool isSelected() const; bool isSelected() const;
void selectFirstItemInList();
void unselectItemInList();
FMenuItem* getSelectedListItem() const;
bool hasSelectedListItem() const;
bool hasHotkey() const; bool hasHotkey() const;
void setMenu (FMenu*); void setMenu (FMenu*);
bool hasMenu() const; bool hasMenu() const;
@ -125,6 +120,7 @@ class FMenu : public FWindow, public FMenuList
private: private:
friend class FApplication; friend class FApplication;
friend class FMenuBar;
friend class FMenuItem; friend class FMenuItem;
}; };
#pragma pack(pop) #pragma pack(pop)
@ -191,14 +187,6 @@ inline void FMenu::unsetSelected()
inline bool FMenu::isSelected() const inline bool FMenu::isSelected() const
{ return item->isSelected(); } { return item->isSelected(); }
//----------------------------------------------------------------------
inline FMenuItem* FMenu::getSelectedListItem() const
{ return selectedListItem; }
//----------------------------------------------------------------------
inline bool FMenu::hasSelectedListItem() const
{ return selectedListItem; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::hasHotkey() const inline bool FMenu::hasHotkey() const
{ return item->hasHotkey(); } { return item->hasHotkey(); }

View File

@ -15,7 +15,6 @@ FMenuBar::FMenuBar(FWidget* parent)
: FWindow(parent) : FWindow(parent)
, mouse_down(false) , mouse_down(false)
, drop_down(false) , drop_down(false)
, selectedMenuItem()
{ {
init(); init();
} }
@ -117,23 +116,23 @@ bool FMenuBar::selectNextItem()
|| next->isSeparator() ); || next->isSeparator() );
if ( next == *iter ) if ( next == *iter )
return false; return false;
unselectItemInMenu(); unselectItem();
next->setSelected(); next->setSelected();
setSelectedItem(next);
next->setFocus(); next->setFocus();
if ( drop_down && next->hasMenu() ) if ( drop_down && next->hasMenu() )
{ {
FMenuItem* first_item; FMenuItem* first_item;
FMenu* menu = next->getMenu(); FMenu* menu = next->getMenu();
next->openMenu(); next->openMenu();
menu->selectFirstItemInList(); menu->selectFirstItem();
first_item = menu->getSelectedListItem(); first_item = menu->getSelectedItem();
if ( first_item ) if ( first_item )
first_item->setFocus(); first_item->setFocus();
menu->redraw(); menu->redraw();
} }
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
selectedMenuItem = next;
redraw(); redraw();
break; break;
} }
@ -170,23 +169,23 @@ bool FMenuBar::selectPrevItem()
|| prev->isSeparator() ); || prev->isSeparator() );
if ( prev == *iter ) if ( prev == *iter )
return false; return false;
unselectItemInMenu(); unselectItem();
prev->setSelected(); prev->setSelected();
prev->setFocus(); prev->setFocus();
if ( drop_down && prev->hasMenu() ) if ( drop_down && prev->hasMenu() )
{ {
FMenuItem* first_item; FMenuItem* first_item;
FMenu* menu = prev->getMenu(); FMenu* menu = prev->getMenu();
prev->openMenu(); prev->openMenu();
menu->selectFirstItemInList(); menu->selectFirstItem();
first_item = menu->getSelectedListItem(); first_item = menu->getSelectedItem();
if ( first_item ) if ( first_item )
first_item->setFocus(); first_item->setFocus();
menu->redraw(); menu->redraw();
} }
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
selectedMenuItem = prev; setSelectedItem(prev);
redraw(); redraw();
break; break;
} }
@ -211,34 +210,34 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
if ( 0x20000e0+tolower(hotkey) == key ) if ( 0x20000e0+tolower(hotkey) == key )
{ {
FMenuItem* sel_item = getSelectedMenuItem(); FMenuItem* sel_item = getSelectedItem();
if ( sel_item && sel_item->hasMenu() ) if ( sel_item && sel_item->hasMenu() )
sel_item->getMenu()->unselectItemInList(); sel_item->getMenu()->unselectItem();
unselectItemInMenu(); unselectItem();
if ( (*iter)->hasMenu() ) if ( (*iter)->hasMenu() )
{ {
FMenuItem* first_item; FMenuItem* first_item;
FMenu* menu = (*iter)->getMenu(); FMenu* menu = (*iter)->getMenu();
(*iter)->setSelected(); (*iter)->setSelected();
setSelectedItem(*iter);
(*iter)->setFocus(); (*iter)->setFocus();
(*iter)->openMenu(); (*iter)->openMenu();
menu->selectFirstItemInList(); menu->selectFirstItem();
first_item = menu->getSelectedListItem(); first_item = menu->getSelectedItem();
if ( first_item ) if ( first_item )
first_item->setFocus(); first_item->setFocus();
menu->redraw(); menu->redraw();
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
selectedMenuItem = *iter;
redraw(); redraw();
drop_down = true; drop_down = true;
} }
else else
{ {
selectedMenuItem = 0; setSelectedItem(0);
redraw(); redraw();
drop_down = false; drop_down = false;
(*iter)->processClicked(); (*iter)->processClicked();
@ -453,17 +452,17 @@ void FMenuBar::onKeyPress (FKeyEvent* ev)
case fc::Fkey_enter: case fc::Fkey_enter:
case fc::Fkey_up: case fc::Fkey_up:
case fc::Fkey_down: case fc::Fkey_down:
if ( hasSelectedMenuItem() ) if ( hasSelectedItem() )
{ {
FMenuItem* sel_item = getSelectedMenuItem(); FMenuItem* sel_item = getSelectedItem();
if ( sel_item->hasMenu() ) if ( sel_item->hasMenu() )
{ {
FMenuItem* first_item; FMenuItem* first_item;
FMenu* menu = sel_item->getMenu(); FMenu* menu = sel_item->getMenu();
sel_item->openMenu(); sel_item->openMenu();
menu->selectFirstItemInList(); menu->selectFirstItem();
first_item = menu->getSelectedListItem(); first_item = menu->getSelectedItem();
if ( first_item ) if ( first_item )
first_item->setFocus(); first_item->setFocus();
menu->redraw(); menu->redraw();
@ -475,8 +474,7 @@ void FMenuBar::onKeyPress (FKeyEvent* ev)
else if ( ev->key() == fc::Fkey_return else if ( ev->key() == fc::Fkey_return
|| ev->key() == fc::Fkey_enter ) || ev->key() == fc::Fkey_enter )
{ {
sel_item->unsetSelected(); unselectItem();
selectedMenuItem = 0;
redraw(); redraw();
sel_item->processClicked(); sel_item->processClicked();
} }
@ -498,6 +496,14 @@ void FMenuBar::onKeyPress (FKeyEvent* ev)
case fc::Fkey_escape_mintty: case fc::Fkey_escape_mintty:
resetMenu(); resetMenu();
redraw(); redraw();
activatePrevWindow();
getActiveWindow()->getFocusWidget()->setFocus();
getActiveWindow()->redraw();
if ( statusBar() )
statusBar()->drawMessage();
updateTerminal();
flush_out();
drop_down = false;
ev->accept(); ev->accept();
break; break;
@ -514,7 +520,7 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
mouse_down = false; mouse_down = false;
if ( ! itemlist.empty() ) if ( ! itemlist.empty() )
{ {
unselectItemInMenu(); unselectItem();
redraw(); redraw();
drop_down = false; drop_down = false;
} }
@ -543,7 +549,6 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
while ( iter != end ) while ( iter != end )
{ {
int x1, x2; int x1, x2;
x1 = (*iter)->getX(); x1 = (*iter)->getX();
x2 = (*iter)->getX() + (*iter)->getWidth() - 1; x2 = (*iter)->getX() + (*iter)->getWidth() - 1;
@ -559,7 +564,7 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
(*iter)->setSelected(); (*iter)->setSelected();
(*iter)->setFocus(); (*iter)->setFocus();
(*iter)->openMenu(); (*iter)->openMenu();
selectedMenuItem = *iter; setSelectedItem(*iter);
focus_changed = true; focus_changed = true;
if ( focused_widget ) if ( focused_widget )
focused_widget->redraw(); focused_widget->redraw();
@ -567,15 +572,14 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
if ( (*iter)->hasMenu() ) if ( (*iter)->hasMenu() )
{ {
FMenu* menu = (*iter)->getMenu(); FMenu* menu = (*iter)->getMenu();
if ( menu->hasSelectedListItem() ) if ( menu->hasSelectedItem() )
{ {
menu->unselectItemInList(); menu->unselectItem();
menu->redraw(); menu->redraw();
focus_changed = true; focus_changed = true;
drop_down = true; drop_down = true;
} }
} }
} }
else else
{ {
@ -584,8 +588,8 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
&& (*iter)->isSelected() ) && (*iter)->isSelected() )
{ {
(*iter)->unsetSelected(); (*iter)->unsetSelected();
if ( selectedMenuItem == *iter ) if ( getSelectedItem() == *iter )
selectedMenuItem = 0; setSelectedItem(0);
focus_changed = true; focus_changed = true;
} }
} }
@ -633,11 +637,11 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
if ( (*iter)->hasMenu() ) if ( (*iter)->hasMenu() )
{ {
FMenu* menu = (*iter)->getMenu(); FMenu* menu = (*iter)->getMenu();
if ( ! menu->hasSelectedListItem() ) if ( ! menu->hasSelectedItem() )
{ {
FMenuItem* first_item; FMenuItem* first_item;
menu->selectFirstItemInList(); menu->selectFirstItem();
first_item = menu->getSelectedListItem(); first_item = menu->getSelectedItem();
if ( first_item ) if ( first_item )
first_item->setFocus(); first_item->setFocus();
menu->redraw(); menu->redraw();
@ -650,13 +654,25 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
else else
{ {
(*iter)->unsetSelected(); (*iter)->unsetSelected();
if ( selectedMenuItem == *iter ) if ( getSelectedItem() == *iter )
selectedMenuItem = 0; setSelectedItem(0);
redraw(); redraw();
(*iter)->processClicked(); (*iter)->processClicked();
drop_down = false; drop_down = false;
} }
} }
else
{
if ( mouse_y == 1
&& (*iter)->isEnabled()
&& (*iter)->isSelected() )
{
(*iter)->unsetSelected();
if ( getSelectedItem() == *iter )
setSelectedItem(0);
redraw();
}
}
++iter; ++iter;
} }
} }
@ -702,7 +718,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
(*iter)->setSelected(); (*iter)->setSelected();
(*iter)->setFocus(); (*iter)->setFocus();
(*iter)->openMenu(); (*iter)->openMenu();
selectedMenuItem = *iter; setSelectedItem(*iter);
focus_changed = true; focus_changed = true;
if ( focused_widget ) if ( focused_widget )
focused_widget->redraw(); focused_widget->redraw();
@ -710,9 +726,9 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
if ( (*iter)->hasMenu() ) if ( (*iter)->hasMenu() )
{ {
FMenu* menu = (*iter)->getMenu(); FMenu* menu = (*iter)->getMenu();
if ( menu->hasSelectedListItem() ) if ( menu->hasSelectedItem() )
{ {
menu->unselectItemInList(); menu->unselectItem();
menu->redraw(); menu->redraw();
drop_down = true; drop_down = true;
} }
@ -728,15 +744,15 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
&& (*iter)->isSelected() ) && (*iter)->isSelected() )
{ {
(*iter)->unsetSelected(); (*iter)->unsetSelected();
if ( selectedMenuItem == *iter ) if ( getSelectedItem() == *iter )
selectedMenuItem = 0; setSelectedItem(0);
focus_changed = true; focus_changed = true;
drop_down = false; drop_down = false;
} }
else if ( hasSelectedMenuItem() && selectedMenuItem->hasMenu() ) else if ( hasSelectedItem() && getSelectedItem()->hasMenu() )
{ {
// Mouse event handover to the menu // Mouse event handover to the menu
FMenu* menu = selectedMenuItem->getMenu(); FMenu* menu = getSelectedItem()->getMenu();
const FRect& menu_geometry = menu->getGeometryGlobal(); const FRect& menu_geometry = menu->getGeometryGlobal();
if ( menu_geometry.contains(ev->getGlobalPos()) ) if ( menu_geometry.contains(ev->getGlobalPos()) )
@ -745,8 +761,9 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
const FPoint& p = menu->globalToLocalPos(g); const FPoint& p = menu->globalToLocalPos(g);
int b = ev->getButton(); int b = ev->getButton();
ev = new FMouseEvent (MouseMove_Event, p, g, b); ev = new FMouseEvent (MouseMove_Event, p, g, b);
menu->mouse_down = true;
setClickedWidget(menu); setClickedWidget(menu);
menu->onMouseDown(ev); menu->onMouseMove(ev);
} }
} }
} }
@ -762,14 +779,12 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuBar::onAccel (FAccelEvent* ev) void FMenuBar::onAccel (FAccelEvent* ev)
{ {
if ( ! hasSelectedMenuItem() ) unselectItem();
{ selectFirstItem();
selectFirstItemInMenu(); getSelectedItem()->setFocus();
getSelectedMenuItem()->setFocus(); if ( statusBar() )
if ( statusBar() ) statusBar()->drawMessage();
statusBar()->drawMessage(); redraw();
redraw();
}
ev->accept(); ev->accept();
} }
@ -795,44 +810,10 @@ void FMenuBar::hide()
delete[] blank; delete[] blank;
} }
//----------------------------------------------------------------------
void FMenuBar::selectFirstItemInMenu()
{
std::vector<FMenuItem*>::const_iterator iter, end;
iter = itemlist.begin();
end = itemlist.end();
if ( itemlist.empty() )
return;
if ( hasSelectedMenuItem() )
unselectItemInMenu();
while ( iter != end )
{
if ( (*iter)->isEnabled() && ! (*iter)->isSeparator() )
{
// select first enabled item
(*iter)->setSelected();
selectedMenuItem = *iter;
break;
}
++iter;
}
}
//----------------------------------------------------------------------
void FMenuBar::unselectItemInMenu()
{
if ( hasSelectedMenuItem() )
selectedMenuItem->unsetSelected();
selectedMenuItem = 0;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuBar::resetMenu() void FMenuBar::resetMenu()
{ {
unselectItemInMenu(); unselectItem();
drop_down = false; drop_down = false;
} }

View File

@ -47,7 +47,6 @@ class FMenuBar : public FWindow, public FMenuList
private: private:
bool mouse_down; bool mouse_down;
bool drop_down; bool drop_down;
FMenuItem* selectedMenuItem;
private: private:
FMenuBar (const FMenuBar&); FMenuBar (const FMenuBar&);
@ -74,11 +73,7 @@ class FMenuBar : public FWindow, public FMenuList
void onMouseMove (FMouseEvent*); void onMouseMove (FMouseEvent*);
void onAccel (FAccelEvent*); void onAccel (FAccelEvent*);
void hide(); void hide();
void selectFirstItemInMenu();
void unselectItemInMenu();
void resetMenu(); void resetMenu();
FMenuItem* getSelectedMenuItem() const;
bool hasSelectedMenuItem() const;
// make every setGeometry from FWidget available // make every setGeometry from FWidget available
using FWidget::setGeometry; using FWidget::setGeometry;
void setGeometry (int, int, int, int, bool = true); void setGeometry (int, int, int, int, bool = true);
@ -97,12 +92,4 @@ class FMenuBar : public FWindow, public FMenuList
inline const char* FMenuBar::getClassName() const inline const char* FMenuBar::getClassName() const
{ return "FMenuBar"; } { return "FMenuBar"; }
//----------------------------------------------------------------------
inline FMenuItem* FMenuBar::getSelectedMenuItem() const
{ return selectedMenuItem; }
//----------------------------------------------------------------------
inline bool FMenuBar::hasSelectedMenuItem() const
{ return selectedMenuItem; }
#endif // _FMENUBAR_H #endif // _FMENUBAR_H

View File

@ -95,9 +95,9 @@ void FMenuItem::init (FWidget* parent)
if ( parent ) if ( parent )
{ {
setSuperMenu(parent); setSuperMenu(parent);
FMenuList* sm_list = dynamic_cast<FMenuList*>(parent); FMenuList* menu_list = dynamic_cast<FMenuList*>(parent);
if ( sm_list ) if ( menu_list )
sm_list->insert(this); menu_list->insert(this);
if ( isMenuBar(parent) ) // Parent is menubar if ( isMenuBar(parent) ) // Parent is menubar
{ {
@ -121,9 +121,9 @@ void FMenuItem::init (FWidget* parent)
} }
else if ( isMenu(parent) ) // Parent is menu else if ( isMenu(parent) ) // Parent is menu
{ {
FMenu* super_menu_ptr = dynamic_cast<FMenu*>(parent); FMenu* menu_ptr = dynamic_cast<FMenu*>(parent);
if ( super_menu_ptr ) if ( menu_ptr )
super_menu_ptr->menu_dimension(); menu_ptr->menu_dimension();
//addAccelerator (accel_key, this); //addAccelerator (accel_key, this);
@ -342,21 +342,22 @@ void FMenuItem::onAccel (FAccelEvent* ev)
FMenuBar* mbar = dynamic_cast<FMenuBar*>(super_menu); FMenuBar* mbar = dynamic_cast<FMenuBar*>(super_menu);
if ( mbar ) if ( mbar )
{ {
if ( menu && ! menu->hasSelectedListItem() ) if ( menu )
{ {
FWidget* focused_widget; FWidget* focused_widget;
if ( mbar->getSelectedMenuItem() ) if ( mbar->getSelectedItem() )
mbar->getSelectedMenuItem()->unsetSelected(); mbar->getSelectedItem()->unsetSelected();
setSelected(); setSelected();
mbar->selectedMenuItem = this; mbar->selectedItem = this;
openMenu(); openMenu();
focused_widget = static_cast<FWidget*>(ev->focusedWidget()); focused_widget = static_cast<FWidget*>(ev->focusedWidget());
FFocusEvent out (FocusOut_Event); FFocusEvent out (FocusOut_Event);
FApplication::queueEvent(focused_widget, &out); FApplication::queueEvent(focused_widget, &out);
menu->selectFirstItemInList(); menu->unselectItem();
menu->selectedListItem->setFocus(); menu->selectFirstItem();
menu->getSelectedItem()->setFocus();
if ( focused_widget ) if ( focused_widget )
focused_widget->redraw(); focused_widget->redraw();
menu->redraw(); menu->redraw();
@ -368,7 +369,7 @@ void FMenuItem::onAccel (FAccelEvent* ev)
else else
{ {
unsetSelected(); unsetSelected();
mbar->selectedMenuItem = 0; mbar->selectedItem = 0;
mbar->redraw(); mbar->redraw();
processClicked(); processClicked();
mbar->drop_down = false; mbar->drop_down = false;
@ -441,6 +442,31 @@ bool FMenuItem::setFocus (bool on)
if ( isEnabled() ) if ( isEnabled() )
{ {
if ( ! selected )
{
FMenuList* menu_list = dynamic_cast<FMenuList*>(getSuperMenu());
menu_list->unselectItem();
setSelected();
menu_list->setSelectedItem(this);
if ( statusBar() )
statusBar()->drawMessage();
FWidget* parent = getSuperMenu();
if ( isMenuBar(parent) )
{
FMenuBar* menubar_ptr = dynamic_cast<FMenuBar*>(parent);
if ( menubar_ptr )
menubar_ptr->redraw();
}
else if ( isMenu(parent) )
{
FMenu* menu_ptr = dynamic_cast<FMenu*>(parent);
if ( menu_ptr )
menu_ptr->redraw();
}
}
if ( statusBar() ) if ( statusBar() )
{ {
FString msg = getStatusbarMessage(); FString msg = getStatusbarMessage();

View File

@ -142,11 +142,17 @@ inline bool FMenuItem::isSelected() const
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenuItem::setSeparator() inline void FMenuItem::setSeparator()
{ separator = true; } {
separator = true;
unsetFocusable();
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenuItem::unsetSeparator() inline void FMenuItem::unsetSeparator()
{ separator = false; } {
separator = false;
setFocusable();
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenuItem::isSeparator() const inline bool FMenuItem::isSeparator() const

View File

@ -10,7 +10,8 @@
// constructor and destructor // constructor and destructor
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FMenuList::FMenuList() FMenuList::FMenuList()
: itemlist() : selectedItem()
, itemlist()
{ } { }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -32,6 +33,40 @@ FMenuList::~FMenuList() // destructor
// public methods of FMenuList // public methods of FMenuList
//----------------------------------------------------------------------
void FMenuList::selectFirstItem()
{
std::vector<FMenuItem*>::const_iterator iter, end;
iter = itemlist.begin();
end = itemlist.end();
if ( itemlist.empty() )
return;
if ( hasSelectedItem() )
unselectItem();
while ( iter != end )
{
if ( (*iter)->isEnabled() && ! (*iter)->isSeparator() )
{
// select first enabled item
(*iter)->setSelected();
setSelectedItem(*iter);
break;
}
++iter;
}
}
//----------------------------------------------------------------------
void FMenuList::unselectItem()
{
if ( hasSelectedItem() )
getSelectedItem()->unsetSelected();
setSelectedItem(0);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenuList::hasSelectedItem() bool FMenuList::hasSelectedItem()
{ {

View File

@ -38,6 +38,7 @@
class FMenuList class FMenuList
{ {
protected: protected:
FMenuItem* selectedItem;
std::vector<FMenuItem*> itemlist; std::vector<FMenuItem*> itemlist;
private: private:
@ -54,7 +55,12 @@ class FMenuList
void enableItem (int); void enableItem (int);
void disableItem (int); void disableItem (int);
bool isSelected (int) const; bool isSelected (int) const;
void selectFirstItem();
void unselectItem();
bool hasSelectedItem(); bool hasSelectedItem();
FMenuItem* getSelectedItem() const;
void setSelectedItem (FMenuItem*);
bool hasSelectedItem() const;
virtual void insert (FMenuItem*); virtual void insert (FMenuItem*);
virtual void remove (FMenuItem*); virtual void remove (FMenuItem*);
@ -89,5 +95,16 @@ inline void FMenuList::disableItem (int index)
inline bool FMenuList::isSelected(int index) const inline bool FMenuList::isSelected(int index) const
{ return itemlist[uInt(index-1)]->isSelected(); } { return itemlist[uInt(index-1)]->isSelected(); }
//----------------------------------------------------------------------
inline FMenuItem* FMenuList::getSelectedItem() const
{ return selectedItem; }
//----------------------------------------------------------------------
inline void FMenuList::setSelectedItem (FMenuItem* item)
{ selectedItem = item; }
//----------------------------------------------------------------------
inline bool FMenuList::hasSelectedItem() const
{ return selectedItem; }
#endif // _FMENULIST_H #endif // _FMENULIST_H

View File

@ -1548,14 +1548,18 @@ void FTerm::init()
setPalette (fc::Black, 0x00, 0x00, 0x00); setPalette (fc::Black, 0x00, 0x00, 0x00);
setPalette (fc::Blue, 0x22, 0x22, 0xb2); setPalette (fc::Blue, 0x22, 0x22, 0xb2);
setPalette (fc::Green, 0x18, 0xb2, 0x18);
setPalette (fc::Cyan, 0x4a, 0x4a, 0xe4); setPalette (fc::Cyan, 0x4a, 0x4a, 0xe4);
setPalette (fc::Red, 0xb2, 0x18, 0x18); setPalette (fc::Red, 0xb2, 0x18, 0x18);
setPalette (fc::Magenta, 0xb2, 0x18, 0xb2);
setPalette (fc::Brown, 0xe8, 0x87, 0x1f);
setPalette (fc::LightGray, 0xbc, 0xbc, 0xbc); setPalette (fc::LightGray, 0xbc, 0xbc, 0xbc);
setPalette (fc::DarkGray, 0x50, 0x50, 0x50); setPalette (fc::DarkGray, 0x50, 0x50, 0x50);
setPalette (fc::LightBlue, 0x80, 0xa4, 0xec); setPalette (fc::LightBlue, 0x80, 0xa4, 0xec);
setPalette (fc::LightGreen, 0xd4, 0xd4, 0xd4); setPalette (fc::LightGreen, 0x54, 0xff, 0x54);
setPalette (fc::LightCyan, 0x49, 0xc9, 0xe3); setPalette (fc::LightCyan, 0x49, 0xc9, 0xe3);
setPalette (fc::LightRed, 0xff, 0x54, 0x54); setPalette (fc::LightRed, 0xff, 0x54, 0x54);
setPalette (fc::LightMagenta, 0xff, 0x54, 0xff);
setPalette (fc::Yellow, 0xff, 0xff, 0x54); setPalette (fc::Yellow, 0xff, 0xff, 0x54);
setPalette (fc::White, 0xff, 0xff, 0xff); setPalette (fc::White, 0xff, 0xff, 0xff);
} }

View File

@ -347,7 +347,7 @@ bool FWindow::activatePrevWindow()
{ {
--iter; --iter;
FWindow* w = static_cast<FWindow*>(*iter); FWindow* w = static_cast<FWindow*>(*iter);
if ( w && ! w->isActiveWindow() ) if ( w && ! w->isHiddenWindow() && ! w->isActiveWindow() )
{ {
setActiveWindow(w); setActiveWindow(w);
return true; return true;