From a41de9496f9fe53e2db61747efd03bcdf3afe1e3 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Thu, 5 Nov 2015 23:25:21 +0100 Subject: [PATCH] Menu bar navigation without menu drop down --- ChangeLog | 3 ++ doc/Makefile.am | 2 - doc/Makefile.in | 2 - doc/menu-draft.png | Bin 1779 -> 0 bytes src/fapp.cpp | 24 +++++++++--- src/ffiledialog.cpp | 4 +- src/fmenubar.cpp | 89 +++++++++++++++++++++++++++----------------- src/fmenubar.h | 22 ++++++----- src/fmenuitem.cpp | 38 ++++++++++++++++++- src/fmenuitem.h | 1 + src/fterm.cpp | 14 +++---- src/fwidget.cpp | 2 +- 12 files changed, 136 insertions(+), 65 deletions(-) delete mode 100644 doc/menu-draft.png 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 6859b6118d64af36578c0412685df793d6351658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1779 zcmX|?dpy(oAICRlmTj)(GK4z0wcp7Zrd7x_%SmFyNo<%^?w0#~ZuN6(r3u4MkxPqj zlDQiyF{IxitKXsDagB+TL%D2csmJf}czxdQ&*%Ne=kaD5D2dHZGl0>OjYqv(fL<`ow$QQwZ%=MS`etS zvr{Azp?r8z;u+Z2@szF9m(Ybi@hx$9TPs4$+YhByc@It?`b3+yvRvBEr8@aX6uP9U z&O4D|DE(--KKbqCQ(E}k$@V5^>m)uh%2!YIEOt4lx33#hPY*d=@JBJpJoNLB=gd@p zoe*8Ju_^QSFFUV3V~s06|21`Zf}zsItPNjjF37(sWe_NL{2|l!s|I=^b&PVO_f?IQ zvdg2jEWbO!PSNu7zzktF40iY`=Sl)BelSLwk(4`@rvYbfw&U<%I&ymS4?{Z_SS^T=8)pIR6}+gN!LZ)5caiig{5n|ZM?{iu;3otlwt zn0){Fxx3RZ206gVR0&0mD&Etb#W~&nyAF&Oc(sb(s$D&}3z(Ij(-Q^$Z(hy=%tIH< zod3JzSdwy82xi}(2q?Sd1rG{{BQ$v3j`e96G)1>*5o2?JKU&ZGtsC=>oEf$ES@Ou` zpp?T}b5QOf3@+o-A|`Pgd9PELi#i@*mn+aUv83pgy$-(#{WpAxK~Q9)sz;4rOP#;0 zCh1nZ!`(HZs@3|IY@Ca8P9_YDlN-tpwpuLv_EwR=%`r;nF56R;NBgIrSW*>YR=2yV zM>p)u(o8+RsRN4sYpA3R!;Wt&@&llO0CWq>U(LO+=mG|*F6|?FZsxgZjq(5=m5frM zgmPiV?8bxD+a$d?dezYb+AE(s^@zRlM(JTK<-w`5ku&^@oq4Wt<*n|A_a%d(V7-b) z=t4%26tCS$&^RD)1snr`n$oGn>A&UCVd4CWhCx5~=}3*_%I9k9f-ar~MQ`rQDBh-U za9VZ4Tv}biC_QDRJ{#*C8uPS?@-rq{b}OX5k5~^8n4kA!hiUePP?3%uy`5xq<310U zgOjn1%#nJOz^E*--8ve84AYIafRZvIr6T1%q7B}*0K?ihkWHgBAA}?34Ul_fdqM_j z7%>LEs4DfQK54@W@CP(|dQum(g+hJhu0#*+vtLu*(&7e+uRs}#&08Adq8!%|jiq6Q zm;r-Ja!pjz$@Z81_FG@#gqg^?CMbnb-Fu zDA!v)^wd@m%?(*f(OMDEABH)Wlre(kkzAQZjOtEAMNYT(UiX~D1!DX$bamyVUBC&- z8fX8SloJ)Vql>P7cvL?eRB&*_Yza=X`d7yPo);x~!{C_jhQ*%6vV^SfJcbtee?N(9 zG@xFE+jOg(wW!`RtwZgf6a)m5jf%V3Rjn_r`@m>3MB7kj=GZ~WEH7m508^Oati`DC*Wg^@rcCIU=n5eLHGMME8|OJ<)xm= zaGQjf2DDN}WBT4dC5KO{3(@n>dJNTZCE5D$rBa;a5ab3(&3%xo{{iB-_SksDUh#uKM=tW^Pm$i_g4E^S=7y!R%(;)B}!OG&FfHhusZ7pTkW`PEMZA$EI~4 zf?zNmGz<*xrGa7Kg|1~{DoITl0q?<}VergDn(vjA6|e{%kUmLLvE>8l`tx}t8=9sC z*!`z$AYDE#%Z{dL+rX3VmhI@t-1ge%5xZP0MFv!|b_#}mK=_X0|Mf`cj%4h$JPs{C ReB;|cg|~CEt+OW5{sCb~M34Xg 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" );