Menu bar navigation without menu drop down

This commit is contained in:
Markus Gans 2015-11-05 23:25:21 +01:00
parent cf9bac4809
commit a41de9496f
12 changed files with 136 additions and 65 deletions

View File

@ -1,3 +1,6 @@
2015-11-05 Markus Gans <guru.mail@muenster.de>
* Menu bar navigation without menu drop down
2015-11-03 Markus Gans <guru.mail@muenster.de> 2015-11-03 Markus Gans <guru.mail@muenster.de>
* Improve keyboard shortcut handling in menus * Improve keyboard shortcut handling in menus

View File

@ -10,7 +10,6 @@ EXTRA_DIST = \
console_codes-manual.sh \ console_codes-manual.sh \
console_ioctl-manual.sh \ console_ioctl-manual.sh \
fileopen-dialog.png \ fileopen-dialog.png \
menu-draft.png \
ncurses.supp \ ncurses.supp \
newfont1.png \ newfont1.png \
newfont2.png \ newfont2.png \
@ -30,7 +29,6 @@ doc_DATA = \
console_codes-manual.sh \ console_codes-manual.sh \
console_ioctl-manual.sh \ console_ioctl-manual.sh \
fileopen-dialog.png \ fileopen-dialog.png \
menu-draft.png \
ncurses.supp \ ncurses.supp \
newfont1.png \ newfont1.png \
newfont2.png \ newfont2.png \

View File

@ -272,7 +272,6 @@ EXTRA_DIST = \
console_codes-manual.sh \ console_codes-manual.sh \
console_ioctl-manual.sh \ console_ioctl-manual.sh \
fileopen-dialog.png \ fileopen-dialog.png \
menu-draft.png \
ncurses.supp \ ncurses.supp \
newfont1.png \ newfont1.png \
newfont2.png \ newfont2.png \
@ -292,7 +291,6 @@ doc_DATA = \
console_codes-manual.sh \ console_codes-manual.sh \
console_ioctl-manual.sh \ console_ioctl-manual.sh \
fileopen-dialog.png \ fileopen-dialog.png \
menu-draft.png \
ncurses.supp \ ncurses.supp \
newfont1.png \ newfont1.png \
newfont2.png \ newfont2.png \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -54,7 +54,7 @@ FApplication::FApplication (int &_argc, char* _argv[])
rootObj = this; rootObj = this;
static char* empty = const_cast<char*>(""); static char* empty = const_cast<char*>("");
if ( _argc == 0 || _argv == 0 ) if ( ! _argc || ! _argv )
{ {
_argc = 0; _argc = 0;
_argv = &empty; _argv = &empty;
@ -962,6 +962,7 @@ void FApplication::processMouseEvent()
} }
} }
// close open menu
if ( open_menu && ! b_state.mouse_moved ) if ( open_menu && ! b_state.mouse_moved )
{ {
FMenu* menu = static_cast<FMenu*>(open_menu); FMenu* menu = static_cast<FMenu*>(open_menu);
@ -975,6 +976,17 @@ void FApplication::processMouseEvent()
} }
} }
if ( ! open_menu && menuBar()
&& menuBar()->hasSelectedMenuItem()
&& ! b_state.mouse_moved )
{
if ( ! menuBar()->getGeometryGlobal().contains(*mouse) )
{
menuBar()->resetMenu();
menuBar()->redraw();
}
}
if ( clicked_widget ) if ( clicked_widget )
{ {
FPoint localMousePos; FPoint localMousePos;
@ -1155,8 +1167,8 @@ int FApplication::processTimerEvent()
while ( iter != end ) while ( iter != end )
{ {
if ( (*iter).id == 0 if ( ! (*iter).id
|| (*iter).object == 0 || ! (*iter).object
|| currentTime < (*iter).timeout ) // no timer expired || currentTime < (*iter).timeout ) // no timer expired
break; break;
@ -1323,7 +1335,7 @@ bool FApplication::sendEvent(FObject* receiver, FEvent* event)
if ( quit_now || app_exit_loop ) if ( quit_now || app_exit_loop )
return false; return false;
if ( receiver == 0 ) if ( ! receiver )
return false; return false;
widget = static_cast<FWidget*>(receiver); widget = static_cast<FWidget*>(receiver);
@ -1373,7 +1385,7 @@ bool FApplication::sendEvent(FObject* receiver, FEvent* event)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FApplication::queueEvent (FObject* receiver, FEvent* event) void FApplication::queueEvent (FObject* receiver, FEvent* event)
{ {
if ( receiver == 0 ) if ( ! receiver )
return; return;
// queue this event // queue this event
@ -1415,7 +1427,7 @@ bool FApplication::removeQueuedEvent(FObject* receiver)
if ( ! eventInQueue() ) if ( ! eventInQueue() )
return false; return false;
if ( receiver == 0 ) if ( ! receiver )
return false; return false;
retval = false; retval = false;

View File

@ -187,13 +187,13 @@ char* FFileDialog::getHomeDir()
struct passwd* pwd; struct passwd* pwd;
pwd = getpwuid( geteuid() ); pwd = getpwuid( geteuid() );
if ( pwd == 0 ) if ( ! pwd )
return const_cast<char*>(""); return const_cast<char*>("");
else else
{ {
pwd = getpwnam(pwd->pw_name); pwd = getpwnam(pwd->pw_name);
if ( pwd == 0 ) if ( ! pwd )
return const_cast<char*>(""); return const_cast<char*>("");
else else
return pwd->pw_dir; return pwd->pw_dir;

View File

@ -14,6 +14,7 @@
FMenuBar::FMenuBar(FWidget* parent) FMenuBar::FMenuBar(FWidget* parent)
: FWindow(parent) : FWindow(parent)
, mouse_down(false) , mouse_down(false)
, drop_down(false)
, selectedMenuItem() , selectedMenuItem()
{ {
init(); init();
@ -119,10 +120,11 @@ bool FMenuBar::selectNextItem()
unselectItemInMenu(); unselectItemInMenu();
next->setSelected(); next->setSelected();
next->setFocus(); next->setFocus();
if ( next->hasMenu() ) if ( drop_down && next->hasMenu() )
{ {
FMenuItem* first_item; FMenuItem* first_item;
FMenu* menu = next->getMenu(); FMenu* menu = next->getMenu();
next->openMenu();
menu->selectFirstItemInList(); menu->selectFirstItemInList();
first_item = menu->getSelectedListItem(); first_item = menu->getSelectedListItem();
if ( first_item ) if ( first_item )
@ -171,10 +173,11 @@ bool FMenuBar::selectPrevItem()
unselectItemInMenu(); unselectItemInMenu();
prev->setSelected(); prev->setSelected();
prev->setFocus(); prev->setFocus();
if ( prev->hasMenu() ) if ( drop_down && prev->hasMenu() )
{ {
FMenuItem* first_item; FMenuItem* first_item;
FMenu* menu = prev->getMenu(); FMenu* menu = prev->getMenu();
prev->openMenu();
menu->selectFirstItemInList(); menu->selectFirstItemInList();
first_item = menu->getSelectedListItem(); first_item = menu->getSelectedListItem();
if ( first_item ) if ( first_item )
@ -205,7 +208,7 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
{ {
int hotkey = (*iter)->getHotkey(); int hotkey = (*iter)->getHotkey();
int key = ev->key(); int key = ev->key();
if ( 0x20000e0+tolower(hotkey) == key ) if ( 0x20000e0+tolower(hotkey) == key )
{ {
FMenuItem* sel_item = getSelectedMenuItem(); FMenuItem* sel_item = getSelectedMenuItem();
@ -221,6 +224,7 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
FMenu* menu = (*iter)->getMenu(); FMenu* menu = (*iter)->getMenu();
(*iter)->setSelected(); (*iter)->setSelected();
(*iter)->setFocus(); (*iter)->setFocus();
(*iter)->openMenu();
menu->selectFirstItemInList(); menu->selectFirstItemInList();
first_item = menu->getSelectedListItem(); first_item = menu->getSelectedListItem();
if ( first_item ) if ( first_item )
@ -230,11 +234,13 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev)
statusBar()->drawMessage(); statusBar()->drawMessage();
selectedMenuItem = *iter; selectedMenuItem = *iter;
redraw(); redraw();
drop_down = true;
} }
else else
{ {
selectedMenuItem = 0; selectedMenuItem = 0;
redraw(); redraw();
drop_down = false;
(*iter)->processClicked(); (*iter)->processClicked();
} }
ev->accept(); ev->accept();
@ -445,25 +451,39 @@ void FMenuBar::onKeyPress (FKeyEvent* ev)
{ {
case fc::Fkey_return: case fc::Fkey_return:
case fc::Fkey_enter: case fc::Fkey_enter:
case fc::Fkey_up:
case fc::Fkey_down:
if ( hasSelectedMenuItem() ) if ( hasSelectedMenuItem() )
{ {
FMenuItem* sel_menu = getSelectedMenuItem(); FMenuItem* sel_item = getSelectedMenuItem();
if ( ! sel_menu->hasMenu() )
if ( sel_item->hasMenu() )
{ {
sel_menu->unsetSelected(); FMenuItem* first_item;
FMenu* menu = sel_item->getMenu();
sel_item->openMenu();
menu->selectFirstItemInList();
first_item = menu->getSelectedListItem();
if ( first_item )
first_item->setFocus();
menu->redraw();
if ( statusBar() )
statusBar()->drawMessage();
redraw();
drop_down = true;
}
else if ( ev->key() == fc::Fkey_return
|| ev->key() == fc::Fkey_enter )
{
sel_item->unsetSelected();
selectedMenuItem = 0; selectedMenuItem = 0;
redraw(); redraw();
sel_menu->processClicked(); sel_item->processClicked();
} }
} }
ev->accept(); ev->accept();
break; break;
case fc::Fkey_up: // avoid focusNextChild() or focusPrevChild()
case fc::Fkey_down:
ev->accept();
break;
case fc::Fkey_left: case fc::Fkey_left:
selectPrevItem(); selectPrevItem();
ev->accept(); ev->accept();
@ -474,6 +494,13 @@ void FMenuBar::onKeyPress (FKeyEvent* ev)
ev->accept(); ev->accept();
break; break;
case fc::Fkey_escape:
case fc::Fkey_escape_mintty:
resetMenu();
redraw();
ev->accept();
break;
default: default:
break; break;
} }
@ -489,6 +516,7 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
{ {
unselectItemInMenu(); unselectItemInMenu();
redraw(); redraw();
drop_down = false;
} }
return; return;
} }
@ -530,6 +558,7 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
FApplication::queueEvent(focused_widget, &out); FApplication::queueEvent(focused_widget, &out);
(*iter)->setSelected(); (*iter)->setSelected();
(*iter)->setFocus(); (*iter)->setFocus();
(*iter)->openMenu();
selectedMenuItem = *iter; selectedMenuItem = *iter;
focus_changed = true; focus_changed = true;
if ( focused_widget ) if ( focused_widget )
@ -541,9 +570,9 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
if ( menu->hasSelectedListItem() ) if ( menu->hasSelectedListItem() )
{ {
menu->unselectItemInList(); menu->unselectItemInList();
(*iter)->setFocus();
menu->redraw(); menu->redraw();
focus_changed = true; focus_changed = true;
drop_down = true;
} }
} }
@ -615,6 +644,7 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
redraw(); redraw();
drop_down = true;
} }
} }
else else
@ -624,6 +654,7 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
selectedMenuItem = 0; selectedMenuItem = 0;
redraw(); redraw();
(*iter)->processClicked(); (*iter)->processClicked();
drop_down = false;
} }
} }
++iter; ++iter;
@ -670,6 +701,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
FApplication::queueEvent(focused_widget, &out); FApplication::queueEvent(focused_widget, &out);
(*iter)->setSelected(); (*iter)->setSelected();
(*iter)->setFocus(); (*iter)->setFocus();
(*iter)->openMenu();
selectedMenuItem = *iter; selectedMenuItem = *iter;
focus_changed = true; focus_changed = true;
if ( focused_widget ) if ( focused_widget )
@ -682,6 +714,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
{ {
menu->unselectItemInList(); menu->unselectItemInList();
menu->redraw(); menu->redraw();
drop_down = true;
} }
} }
} }
@ -698,6 +731,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
if ( selectedMenuItem == *iter ) if ( selectedMenuItem == *iter )
selectedMenuItem = 0; selectedMenuItem = 0;
focus_changed = true; focus_changed = true;
drop_down = false;
} }
else if ( hasSelectedMenuItem() && selectedMenuItem->hasMenu() ) else if ( hasSelectedMenuItem() && selectedMenuItem->hasMenu() )
{ {
@ -795,6 +829,13 @@ void FMenuBar::unselectItemInMenu()
selectedMenuItem = 0; selectedMenuItem = 0;
} }
//----------------------------------------------------------------------
void FMenuBar::resetMenu()
{
unselectItemInMenu();
drop_down = false;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuBar::setGeometry (int xx, int yy, int ww, int hh, bool adjust) void FMenuBar::setGeometry (int xx, int yy, int ww, int hh, bool adjust)
{ {
@ -806,28 +847,8 @@ void FMenuBar::setGeometry (int xx, int yy, int ww, int hh, bool adjust)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuBar::cb_item_activated (FWidget* widget, void*) void FMenuBar::cb_item_activated (FWidget*, void*)
{ {
FMenuItem* menuitem = static_cast<FMenuItem*>(widget);
if ( menuitem->hasMenu() )
{
FMenu* menu = menuitem->getMenu();
if ( ! menu->isVisible() )
{
FMenu* open_menu = static_cast<FMenu*>(getOpenMenu());
if ( open_menu && open_menu != menu )
open_menu->hide();
setOpenMenu(menu);
menu->setVisible();
menu->show();
raiseWindow(menu);
menu->redraw();
updateTerminal();
flush_out();
}
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@ -46,21 +46,22 @@ class FMenuBar : public FWindow, public FMenuList
{ {
private: private:
bool mouse_down; bool mouse_down;
bool drop_down;
FMenuItem* selectedMenuItem; FMenuItem* selectedMenuItem;
private: private:
FMenuBar (const FMenuBar&); FMenuBar (const FMenuBar&);
FMenuBar& operator = (const FMenuBar&); FMenuBar& operator = (const FMenuBar&);
void init(); void init();
void menu_dimension(); void menu_dimension();
bool isMenu (FMenuItem*) const; bool isMenu (FMenuItem*) const;
bool selectNextItem(); bool selectNextItem();
bool selectPrevItem(); bool selectPrevItem();
bool hotkeyMenu (FKeyEvent*&); bool hotkeyMenu (FKeyEvent*&);
int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); int getHotkeyPos (wchar_t*&, wchar_t*&, uInt);
void draw(); void draw();
void drawItems(); void drawItems();
void adjustSize(); void adjustSize();
public: public:
explicit FMenuBar (FWidget* = 0); // constructor explicit FMenuBar (FWidget* = 0); // constructor
@ -75,6 +76,7 @@ class FMenuBar : public FWindow, public FMenuList
void hide(); void hide();
void selectFirstItemInMenu(); void selectFirstItemInMenu();
void unselectItemInMenu(); void unselectItemInMenu();
void resetMenu();
FMenuItem* getSelectedMenuItem() const; FMenuItem* getSelectedMenuItem() const;
bool hasSelectedMenuItem() const; bool hasSelectedMenuItem() const;
// make every setGeometry from FWidget available // make every setGeometry from FWidget available

View File

@ -350,7 +350,7 @@ void FMenuItem::onAccel (FAccelEvent* ev)
mbar->getSelectedMenuItem()->unsetSelected(); mbar->getSelectedMenuItem()->unsetSelected();
setSelected(); setSelected();
mbar->selectedMenuItem = this; mbar->selectedMenuItem = this;
openMenu();
focused_widget = static_cast<FWidget*>(ev->focusedWidget()); focused_widget = static_cast<FWidget*>(ev->focusedWidget());
FFocusEvent out (FocusOut_Event); FFocusEvent out (FocusOut_Event);
@ -363,6 +363,7 @@ void FMenuItem::onAccel (FAccelEvent* ev)
if ( statusBar() ) if ( statusBar() )
statusBar()->drawMessage(); statusBar()->drawMessage();
mbar->redraw(); mbar->redraw();
mbar->drop_down = true;
} }
else else
{ {
@ -370,6 +371,7 @@ void FMenuItem::onAccel (FAccelEvent* ev)
mbar->selectedMenuItem = 0; mbar->selectedMenuItem = 0;
mbar->redraw(); mbar->redraw();
processClicked(); processClicked();
mbar->drop_down = false;
} }
ev->accept(); ev->accept();
} }
@ -387,6 +389,13 @@ void FMenuItem::onFocusIn (FFocusEvent*)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuItem::onFocusOut (FFocusEvent*) void FMenuItem::onFocusOut (FFocusEvent*)
{ {
unsetSelected();
if ( super_menu && isMenuBar(super_menu) )
{
FMenuBar* mbar = dynamic_cast<FMenuBar*>(super_menu);
if ( mbar )
mbar->redraw();
}
if ( statusBar() ) if ( statusBar() )
{ {
statusBar()->clearMessage(); statusBar()->clearMessage();
@ -468,6 +477,33 @@ void FMenuItem::unsetSelected()
processDeactivate(); processDeactivate();
} }
//----------------------------------------------------------------------
void FMenuItem::openMenu()
{
FMenu* menu;
FMenu* open_menu;
if ( hasMenu() )
{
menu = getMenu();
if ( ! menu->isVisible() )
{
open_menu = static_cast<FMenu*>(getOpenMenu());
if ( open_menu && open_menu != menu )
open_menu->hide();
setOpenMenu(menu);
menu->setVisible();
menu->show();
menu->raiseWindow(menu);
menu->redraw();
updateTerminal();
flush_out();
}
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuItem::setText (FString& txt) void FMenuItem::setText (FString& txt)
{ {

View File

@ -101,6 +101,7 @@ class FMenuItem : public FWidget
FMenu* getMenu() const; FMenu* getMenu() const;
void setMenu(FMenu*); void setMenu(FMenu*);
bool hasMenu() const; bool hasMenu() const;
void openMenu();
uInt getTextLength() const; uInt getTextLength() const;
void setText (FString&); void setText (FString&);
void setText (const std::string&); void setText (const std::string&);

View File

@ -1776,7 +1776,7 @@ void FTerm::resizeArea (term_area* area)
char_data default_char; char_data default_char;
line_changes unchanged; line_changes unchanged;
if ( area == 0 ) if ( ! area )
return; return;
if ( term_object == this ) if ( term_object == this )
@ -1939,7 +1939,7 @@ bool FTerm::isCovered(int x, int y, FTerm::term_area* area) const
bool covered, found; bool covered, found;
FWidget* w; FWidget* w;
if ( area == 0 ) if ( ! area )
return false; return false;
covered = false; covered = false;
@ -2014,7 +2014,7 @@ void FTerm::updateVTerm (FTerm::term_area* area)
return; return;
} }
if ( area == 0 ) if ( ! area )
return; return;
if ( ! area->visible ) if ( ! area->visible )
@ -2096,7 +2096,7 @@ void FTerm::getArea (int ax, int ay, FTerm::term_area* area)
FTerm::char_data* tc; // terminal character FTerm::char_data* tc; // terminal character
FTerm::char_data* ac; // area character FTerm::char_data* ac; // area character
if ( area == 0 ) if ( ! area )
return; return;
ax--; ax--;
ay--; ay--;
@ -2131,7 +2131,7 @@ void FTerm::getArea (int x, int y, int w, int h, FTerm::term_area* area)
FTerm::char_data* tc; // terminal character FTerm::char_data* tc; // terminal character
FTerm::char_data* ac; // area character FTerm::char_data* ac; // area character
if ( area == 0 ) if ( ! area )
return; return;
dx = x - area->widget->getGlobalX(); dx = x - area->widget->getGlobalX();
@ -2170,7 +2170,7 @@ void FTerm::getArea (int x, int y, int w, int h, FTerm::term_area* area)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTerm::putArea (const FPoint& pos, FTerm::term_area* area) void FTerm::putArea (const FPoint& pos, FTerm::term_area* area)
{ {
if ( area == 0 ) if ( ! area )
return; return;
if ( ! area->visible ) if ( ! area->visible )
return; return;
@ -2184,7 +2184,7 @@ void FTerm::putArea (int ax, int ay, FTerm::term_area* area)
FTerm::char_data* tc; // terminal character FTerm::char_data* tc; // terminal character
FTerm::char_data* ac; // area character FTerm::char_data* ac; // area character
if ( area == 0 ) if ( ! area )
return; return;
if ( ! area->visible ) if ( ! area->visible )
return; return;

View File

@ -72,7 +72,7 @@ FWidget::FWidget (FWidget* parent)
{ {
resize_term = false; resize_term = false;
if ( parent == 0 ) if ( ! parent )
{ {
assert ( ! rootObject assert ( ! rootObject
&& "FTerm: There should be only one root object" ); && "FTerm: There should be only one root object" );