diff --git a/ChangeLog b/ChangeLog index 71cd0124..e47853f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2015-11-05 Markus Gans + * Menu bar navigation without menu drop down + 2015-11-03 Markus Gans * Improve keyboard shortcut handling in menus diff --git a/doc/Makefile.am b/doc/Makefile.am index 1aded08d..dc6cc98f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -10,7 +10,6 @@ EXTRA_DIST = \ console_codes-manual.sh \ console_ioctl-manual.sh \ fileopen-dialog.png \ - menu-draft.png \ ncurses.supp \ newfont1.png \ newfont2.png \ @@ -30,7 +29,6 @@ doc_DATA = \ console_codes-manual.sh \ console_ioctl-manual.sh \ fileopen-dialog.png \ - menu-draft.png \ ncurses.supp \ newfont1.png \ newfont2.png \ diff --git a/doc/Makefile.in b/doc/Makefile.in index acd910ed..85ee7163 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -272,7 +272,6 @@ EXTRA_DIST = \ console_codes-manual.sh \ console_ioctl-manual.sh \ fileopen-dialog.png \ - menu-draft.png \ ncurses.supp \ newfont1.png \ newfont2.png \ @@ -292,7 +291,6 @@ doc_DATA = \ console_codes-manual.sh \ console_ioctl-manual.sh \ fileopen-dialog.png \ - menu-draft.png \ ncurses.supp \ newfont1.png \ newfont2.png \ diff --git a/doc/menu-draft.png b/doc/menu-draft.png deleted file mode 100644 index 6859b611..00000000 Binary files a/doc/menu-draft.png and /dev/null differ diff --git a/src/fapp.cpp b/src/fapp.cpp index afbb47ed..f7218c35 100644 --- a/src/fapp.cpp +++ b/src/fapp.cpp @@ -54,7 +54,7 @@ FApplication::FApplication (int &_argc, char* _argv[]) rootObj = this; static char* empty = const_cast(""); - if ( _argc == 0 || _argv == 0 ) + if ( ! _argc || ! _argv ) { _argc = 0; _argv = ∅ @@ -962,6 +962,7 @@ void FApplication::processMouseEvent() } } + // close open menu if ( open_menu && ! b_state.mouse_moved ) { FMenu* menu = static_cast(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 ) { FPoint localMousePos; @@ -1155,8 +1167,8 @@ int FApplication::processTimerEvent() while ( iter != end ) { - if ( (*iter).id == 0 - || (*iter).object == 0 + if ( ! (*iter).id + || ! (*iter).object || currentTime < (*iter).timeout ) // no timer expired break; @@ -1323,7 +1335,7 @@ bool FApplication::sendEvent(FObject* receiver, FEvent* event) if ( quit_now || app_exit_loop ) return false; - if ( receiver == 0 ) + if ( ! receiver ) return false; widget = static_cast(receiver); @@ -1373,7 +1385,7 @@ bool FApplication::sendEvent(FObject* receiver, FEvent* event) //---------------------------------------------------------------------- void FApplication::queueEvent (FObject* receiver, FEvent* event) { - if ( receiver == 0 ) + if ( ! receiver ) return; // queue this event @@ -1415,7 +1427,7 @@ bool FApplication::removeQueuedEvent(FObject* receiver) if ( ! eventInQueue() ) return false; - if ( receiver == 0 ) + if ( ! receiver ) return false; retval = false; diff --git a/src/ffiledialog.cpp b/src/ffiledialog.cpp index 69eec786..c5814448 100644 --- a/src/ffiledialog.cpp +++ b/src/ffiledialog.cpp @@ -187,13 +187,13 @@ char* FFileDialog::getHomeDir() struct passwd* pwd; pwd = getpwuid( geteuid() ); - if ( pwd == 0 ) + if ( ! pwd ) return const_cast(""); else { pwd = getpwnam(pwd->pw_name); - if ( pwd == 0 ) + if ( ! pwd ) return const_cast(""); else return pwd->pw_dir; diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index 70076845..51ff25af 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -14,6 +14,7 @@ FMenuBar::FMenuBar(FWidget* parent) : FWindow(parent) , mouse_down(false) + , drop_down(false) , selectedMenuItem() { init(); @@ -119,10 +120,11 @@ bool FMenuBar::selectNextItem() unselectItemInMenu(); next->setSelected(); next->setFocus(); - if ( next->hasMenu() ) + if ( drop_down && next->hasMenu() ) { FMenuItem* first_item; FMenu* menu = next->getMenu(); + next->openMenu(); menu->selectFirstItemInList(); first_item = menu->getSelectedListItem(); if ( first_item ) @@ -171,10 +173,11 @@ bool FMenuBar::selectPrevItem() unselectItemInMenu(); prev->setSelected(); prev->setFocus(); - if ( prev->hasMenu() ) + if ( drop_down && prev->hasMenu() ) { FMenuItem* first_item; FMenu* menu = prev->getMenu(); + prev->openMenu(); menu->selectFirstItemInList(); first_item = menu->getSelectedListItem(); if ( first_item ) @@ -205,7 +208,7 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev) { int hotkey = (*iter)->getHotkey(); int key = ev->key(); - + if ( 0x20000e0+tolower(hotkey) == key ) { FMenuItem* sel_item = getSelectedMenuItem(); @@ -221,6 +224,7 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev) FMenu* menu = (*iter)->getMenu(); (*iter)->setSelected(); (*iter)->setFocus(); + (*iter)->openMenu(); menu->selectFirstItemInList(); first_item = menu->getSelectedListItem(); if ( first_item ) @@ -230,11 +234,13 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev) statusBar()->drawMessage(); selectedMenuItem = *iter; redraw(); + drop_down = true; } else { selectedMenuItem = 0; redraw(); + drop_down = false; (*iter)->processClicked(); } ev->accept(); @@ -445,25 +451,39 @@ void FMenuBar::onKeyPress (FKeyEvent* ev) { case fc::Fkey_return: case fc::Fkey_enter: + case fc::Fkey_up: + case fc::Fkey_down: if ( hasSelectedMenuItem() ) { - FMenuItem* sel_menu = getSelectedMenuItem(); - if ( ! sel_menu->hasMenu() ) + FMenuItem* sel_item = getSelectedMenuItem(); + + 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; redraw(); - sel_menu->processClicked(); + sel_item->processClicked(); } } ev->accept(); break; - case fc::Fkey_up: // avoid focusNextChild() or focusPrevChild() - case fc::Fkey_down: - ev->accept(); - break; - case fc::Fkey_left: selectPrevItem(); ev->accept(); @@ -474,6 +494,13 @@ void FMenuBar::onKeyPress (FKeyEvent* ev) ev->accept(); break; + case fc::Fkey_escape: + case fc::Fkey_escape_mintty: + resetMenu(); + redraw(); + ev->accept(); + break; + default: break; } @@ -489,6 +516,7 @@ void FMenuBar::onMouseDown (FMouseEvent* ev) { unselectItemInMenu(); redraw(); + drop_down = false; } return; } @@ -530,6 +558,7 @@ void FMenuBar::onMouseDown (FMouseEvent* ev) FApplication::queueEvent(focused_widget, &out); (*iter)->setSelected(); (*iter)->setFocus(); + (*iter)->openMenu(); selectedMenuItem = *iter; focus_changed = true; if ( focused_widget ) @@ -541,9 +570,9 @@ void FMenuBar::onMouseDown (FMouseEvent* ev) if ( menu->hasSelectedListItem() ) { menu->unselectItemInList(); - (*iter)->setFocus(); menu->redraw(); focus_changed = true; + drop_down = true; } } @@ -615,6 +644,7 @@ void FMenuBar::onMouseUp (FMouseEvent* ev) if ( statusBar() ) statusBar()->drawMessage(); redraw(); + drop_down = true; } } else @@ -624,6 +654,7 @@ void FMenuBar::onMouseUp (FMouseEvent* ev) selectedMenuItem = 0; redraw(); (*iter)->processClicked(); + drop_down = false; } } ++iter; @@ -670,6 +701,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev) FApplication::queueEvent(focused_widget, &out); (*iter)->setSelected(); (*iter)->setFocus(); + (*iter)->openMenu(); selectedMenuItem = *iter; focus_changed = true; if ( focused_widget ) @@ -682,6 +714,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev) { menu->unselectItemInList(); menu->redraw(); + drop_down = true; } } } @@ -698,6 +731,7 @@ void FMenuBar::onMouseMove (FMouseEvent* ev) if ( selectedMenuItem == *iter ) selectedMenuItem = 0; focus_changed = true; + drop_down = false; } else if ( hasSelectedMenuItem() && selectedMenuItem->hasMenu() ) { @@ -795,6 +829,13 @@ void FMenuBar::unselectItemInMenu() selectedMenuItem = 0; } +//---------------------------------------------------------------------- +void FMenuBar::resetMenu() +{ + unselectItemInMenu(); + drop_down = false; +} + //---------------------------------------------------------------------- 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(widget); - - if ( menuitem->hasMenu() ) - { - FMenu* menu = menuitem->getMenu(); - if ( ! menu->isVisible() ) - { - FMenu* open_menu = static_cast(getOpenMenu()); - if ( open_menu && open_menu != menu ) - open_menu->hide(); - setOpenMenu(menu); - - menu->setVisible(); - menu->show(); - raiseWindow(menu); - menu->redraw(); - updateTerminal(); - flush_out(); - } - } } //---------------------------------------------------------------------- diff --git a/src/fmenubar.h b/src/fmenubar.h index e67907c3..661cac29 100644 --- a/src/fmenubar.h +++ b/src/fmenubar.h @@ -46,21 +46,22 @@ class FMenuBar : public FWindow, public FMenuList { private: bool mouse_down; + bool drop_down; FMenuItem* selectedMenuItem; private: FMenuBar (const FMenuBar&); FMenuBar& operator = (const FMenuBar&); - void init(); - void menu_dimension(); - bool isMenu (FMenuItem*) const; - bool selectNextItem(); - bool selectPrevItem(); - bool hotkeyMenu (FKeyEvent*&); - int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); - void draw(); - void drawItems(); - void adjustSize(); + void init(); + void menu_dimension(); + bool isMenu (FMenuItem*) const; + bool selectNextItem(); + bool selectPrevItem(); + bool hotkeyMenu (FKeyEvent*&); + int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); + void draw(); + void drawItems(); + void adjustSize(); public: explicit FMenuBar (FWidget* = 0); // constructor @@ -75,6 +76,7 @@ class FMenuBar : public FWindow, public FMenuList void hide(); void selectFirstItemInMenu(); void unselectItemInMenu(); + void resetMenu(); FMenuItem* getSelectedMenuItem() const; bool hasSelectedMenuItem() const; // make every setGeometry from FWidget available diff --git a/src/fmenuitem.cpp b/src/fmenuitem.cpp index 2ea6c8bf..e4f1a252 100644 --- a/src/fmenuitem.cpp +++ b/src/fmenuitem.cpp @@ -350,7 +350,7 @@ void FMenuItem::onAccel (FAccelEvent* ev) mbar->getSelectedMenuItem()->unsetSelected(); setSelected(); mbar->selectedMenuItem = this; - + openMenu(); focused_widget = static_cast(ev->focusedWidget()); FFocusEvent out (FocusOut_Event); @@ -363,6 +363,7 @@ void FMenuItem::onAccel (FAccelEvent* ev) if ( statusBar() ) statusBar()->drawMessage(); mbar->redraw(); + mbar->drop_down = true; } else { @@ -370,6 +371,7 @@ void FMenuItem::onAccel (FAccelEvent* ev) mbar->selectedMenuItem = 0; mbar->redraw(); processClicked(); + mbar->drop_down = false; } ev->accept(); } @@ -387,6 +389,13 @@ void FMenuItem::onFocusIn (FFocusEvent*) //---------------------------------------------------------------------- void FMenuItem::onFocusOut (FFocusEvent*) { + unsetSelected(); + if ( super_menu && isMenuBar(super_menu) ) + { + FMenuBar* mbar = dynamic_cast(super_menu); + if ( mbar ) + mbar->redraw(); + } if ( statusBar() ) { statusBar()->clearMessage(); @@ -468,6 +477,33 @@ void FMenuItem::unsetSelected() processDeactivate(); } +//---------------------------------------------------------------------- +void FMenuItem::openMenu() +{ + FMenu* menu; + FMenu* open_menu; + + if ( hasMenu() ) + { + menu = getMenu(); + + if ( ! menu->isVisible() ) + { + open_menu = static_cast(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) { diff --git a/src/fmenuitem.h b/src/fmenuitem.h index 61442202..a59a4d86 100644 --- a/src/fmenuitem.h +++ b/src/fmenuitem.h @@ -101,6 +101,7 @@ class FMenuItem : public FWidget FMenu* getMenu() const; void setMenu(FMenu*); bool hasMenu() const; + void openMenu(); uInt getTextLength() const; void setText (FString&); void setText (const std::string&); diff --git a/src/fterm.cpp b/src/fterm.cpp index 4d293d9d..7d90a85e 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -1776,7 +1776,7 @@ void FTerm::resizeArea (term_area* area) char_data default_char; line_changes unchanged; - if ( area == 0 ) + if ( ! area ) return; if ( term_object == this ) @@ -1939,7 +1939,7 @@ bool FTerm::isCovered(int x, int y, FTerm::term_area* area) const bool covered, found; FWidget* w; - if ( area == 0 ) + if ( ! area ) return false; covered = false; @@ -2014,7 +2014,7 @@ void FTerm::updateVTerm (FTerm::term_area* area) return; } - if ( area == 0 ) + if ( ! area ) return; 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* ac; // area character - if ( area == 0 ) + if ( ! area ) return; ax--; 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* ac; // area character - if ( area == 0 ) + if ( ! area ) return; 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) { - if ( area == 0 ) + if ( ! area ) return; if ( ! area->visible ) 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* ac; // area character - if ( area == 0 ) + if ( ! area ) return; if ( ! area->visible ) return; diff --git a/src/fwidget.cpp b/src/fwidget.cpp index fd08ba9e..a85b6368 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -72,7 +72,7 @@ FWidget::FWidget (FWidget* parent) { resize_term = false; - if ( parent == 0 ) + if ( ! parent ) { assert ( ! rootObject && "FTerm: There should be only one root object" );