From 0e7488f646bfe0fae6b51f44a565bf42d632e544 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Thu, 18 Mar 2021 18:42:21 +0100 Subject: [PATCH] little code improvement --- ChangeLog | 2 +- src/fmenu.cpp | 117 +++++++++++++++++++---------------- src/fmenubar.cpp | 38 +++++++----- src/fterm_functions.cpp | 46 +++++++------- src/fwidget.cpp | 40 ++++++------ src/include/final/fmenu.h | 1 + src/include/final/fmenubar.h | 3 +- src/include/final/ftypes.h | 2 +- 8 files changed, 134 insertions(+), 115 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8434512c..9e21d86b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,7 +22,7 @@ 2021-02-09 Markus Gans * Added support for combined unicode characters - * Added a unit test for the FTermBuffera class + * Added a unit test for the FTermBuffer class * Added a unit test for the FTterm functions 2020-12-31 Markus Gans diff --git a/src/fmenu.cpp b/src/fmenu.cpp index dd6c8cb4..ef5d4424 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2015-2020 Markus Gans * +* Copyright 2015-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -1084,57 +1084,62 @@ void FMenu::keypressMenuBar (FKeyEvent* ev) const mbar->onKeyPress(ev); } +//---------------------------------------------------------------------- +inline bool FMenu::hotkeyFound (FKey hotkey, const FKeyEvent& ev) const +{ + bool found{false}; + const FKey key = ev.key(); + + if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character + hotkey -= 0xfee0; + + if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) ) + { + if ( FKey(std::tolower(int(hotkey))) == key + || FKey(std::toupper(int(hotkey))) == key ) + found = true; + } + else if ( hotkey == key ) + found = true; + + return found; +} + //---------------------------------------------------------------------- bool FMenu::hotkeyMenu (FKeyEvent* ev) { + auto try_to_open_submenu = [this] (FMenu* sub_menu) + { + if ( ! sub_menu->isShown() ) + openSubMenu (sub_menu, SELECT_ITEM); + + sub_menu->redraw(); + }; + for (auto&& item : getItemList()) { - if ( item->hasHotkey() ) + if ( item->hasHotkey() && hotkeyFound(item->getHotkey(), *ev) ) { - bool found{false}; - FKey hotkey = item->getHotkey(); - const FKey key = ev->key(); - - if ( hotkey > 0xff00 && hotkey < 0xff5f ) // full-width character - hotkey -= 0xfee0; - - if ( std::isalpha(int(hotkey)) || std::isdigit(int(hotkey)) ) + if ( item->hasMenu() ) { - if ( FKey(std::tolower(int(hotkey))) == key - || FKey(std::toupper(int(hotkey))) == key ) - found = true; + unselectItem(); + item->setSelected(); + setSelectedItem (item); + redraw(); + try_to_open_submenu (item->getMenu()); } - else if ( hotkey == key ) - found = true; - - if ( found ) + else { - if ( item->hasMenu() ) - { - auto sub_menu = item->getMenu(); - unselectItem(); - item->setSelected(); - setSelectedItem (item); - redraw(); - - if ( ! sub_menu->isShown() ) - openSubMenu (sub_menu, SELECT_ITEM); - - sub_menu->redraw(); - } - else - { - unselectItem(); - hideSubMenus(); - hide(); - hideSuperMenus(); - ev->accept(); - item->processClicked(); - } - + unselectItem(); + hideSubMenus(); + hide(); + hideSuperMenus(); ev->accept(); - return true; + item->processClicked(); } + + ev->accept(); + return true; } } @@ -1264,24 +1269,30 @@ inline void FMenu::drawCheckMarkPrefix (const FMenuItem* m_item) if ( ! has_checkable_items ) return; + auto print_bullet = [this] () + { + if ( FTerm::isNewFont() ) + print (UniChar::NF_Bullet); // NF_Bullet ● + else + print (UniChar::BlackCircle); // BlackCircle ● + }; + + auto print_check_mark = [this] () + { + if ( FTerm::isNewFont() ) + print (UniChar::NF_check_mark); // NF_check_mark ✓ + else + print (UniChar::SquareRoot); // SquareRoot √ + }; + if ( is_checkable ) { if ( is_checked ) { if ( is_radio_btn ) - { - if ( FTerm::isNewFont() ) - print (UniChar::NF_Bullet); // NF_Bullet ● - else - print (UniChar::BlackCircle); // BlackCircle ● - } + print_bullet(); else - { - if ( FTerm::isNewFont() ) - print (UniChar::NF_check_mark); // NF_check_mark ✓ - else - print (UniChar::SquareRoot); // SquareRoot √ - } + print_check_mark(); } else { diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index 05c9e005..7f55e86e 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2015-2020 Markus Gans * +* Copyright 2015-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -105,21 +105,7 @@ void FMenuBar::onKeyPress (FKeyEvent* ev) if ( sel_item->hasMenu() ) { - auto menu = sel_item->getMenu(); - sel_item->openMenu(); - menu->selectFirstItem(); - auto first_item = menu->getSelectedItem(); - - if ( first_item ) - first_item->setFocus(); - - menu->redraw(); - - if ( getStatusBar() ) - getStatusBar()->drawMessage(); - - redraw(); - drop_down = true; + openMenu (sel_item); } else if ( key == FKey::Return || key == FKey::Enter ) { @@ -727,6 +713,26 @@ void FMenuBar::selectMenuItem (FMenuItem* item) } } +//---------------------------------------------------------------------- +void FMenuBar::openMenu (const FMenuItem* sel_item) +{ + auto menu = sel_item->getMenu(); + sel_item->openMenu(); + menu->selectFirstItem(); + auto first_item = menu->getSelectedItem(); + + if ( first_item ) + first_item->setFocus(); + + menu->redraw(); + + if ( getStatusBar() ) + getStatusBar()->drawMessage(); + + redraw(); + drop_down = true; +} + //---------------------------------------------------------------------- bool FMenuBar::activateMenu (const FMenuItem* item) { diff --git a/src/fterm_functions.cpp b/src/fterm_functions.cpp index 5d375134..57c5ce44 100644 --- a/src/fterm_functions.cpp +++ b/src/fterm_functions.cpp @@ -323,23 +323,24 @@ FString getFullWidth (const FString& str) // Converts half-width to full-width characters FString s{str}; - constexpr std::size_t HALF = 0; - constexpr std::size_t FULL = 1; + auto table_search = [] (wchar_t& c) + { + constexpr std::size_t HALF = 0; + constexpr std::size_t FULL = 1; + + for (auto&& entry : fc::halfwidth_fullwidth) + { + if ( entry[HALF] == c ) // found + c = entry[FULL]; + } + }; for (auto&& c : s) { if ( c > L'\x20' && c < L'\x7f' ) // half-width ASCII - { c += 0xfee0; - } else - { - for (auto&& entry : fc::halfwidth_fullwidth) - { - if ( entry[HALF] == c ) // found - c = entry[FULL]; - } - } + table_search(c); } return s; @@ -351,23 +352,24 @@ FString getHalfWidth (const FString& str) // Converts full-width to half-width characters FString s{str}; - constexpr std::size_t HALF = 0; - constexpr std::size_t FULL = 1; + auto table_search = [] (wchar_t& c) + { + constexpr std::size_t HALF = 0; + constexpr std::size_t FULL = 1; + + for (auto&& entry : fc::halfwidth_fullwidth) + { + if ( entry[FULL] == c ) // found + c = entry[HALF]; + } + }; for (auto&& c : s) { if ( c > L'\xff00' && c < L'\xff5f' ) // full-width ASCII - { c -= 0xfee0; - } else - { - for (auto&& entry : fc::halfwidth_fullwidth) - { - if ( entry[FULL] == c ) // found - c = entry[HALF]; - } - } + table_search(c); } return s; diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 144df8ca..c2e2d583 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2015-2020 Markus Gans * +* Copyright 2015-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -1726,10 +1726,13 @@ void FWidget::determineDesktopSize() // Determine width and height of the terminal detectTermSize(); - wsize.setRect(1, 1, getDesktopWidth(), getDesktopHeight()); + auto width = getDesktopWidth(); + auto height = getDesktopHeight(); + wsize.setRect(1, 1, width, height); adjust_wsize = wsize; - woffset.setRect(0, 0, getDesktopWidth(), getDesktopHeight()); - wclient_offset = woffset; + woffset.setRect(0, 0, width, height); + auto r = internal::var::root_widget; + wclient_offset.setRect(r->padding.left, r->padding.top, width, height); } //---------------------------------------------------------------------- @@ -1846,29 +1849,24 @@ inline void FWidget::insufficientSpaceAdjust() //---------------------------------------------------------------------- void FWidget::KeyPressEvent (FKeyEvent* kev) { + auto change_focus = [this] (const FKey key) + { + if ( isFocusNextKey(key) ) + return focusNextChild(); + else if ( isFocusPrevKey(key) ) + return focusPrevChild(); + + return false; + }; + FWidget* widget(this); while ( widget ) { widget->onKeyPress(kev); - if ( ! kev->isAccepted() ) - { - const FKey key = kev->key(); - - if ( [this, &key] () - { - if ( isFocusNextKey(key) ) - return focusNextChild(); - else if ( isFocusPrevKey(key) ) - return focusPrevChild(); - - return false; - }() ) - { - return; - } - } + if ( ! kev->isAccepted() && change_focus(kev->key()) ) + return; if ( kev->isAccepted() || widget->isRootWidget() diff --git a/src/include/final/fmenu.h b/src/include/final/fmenu.h index bbe99073..2d783672 100644 --- a/src/include/final/fmenu.h +++ b/src/include/final/fmenu.h @@ -199,6 +199,7 @@ class FMenu : public FWindow, public FMenuList bool selectNextItem(); bool selectPrevItem(); void keypressMenuBar (FKeyEvent*) const; + bool hotkeyFound (FKey, const FKeyEvent&) const; bool hotkeyMenu (FKeyEvent*); void draw() override; void drawItems(); diff --git a/src/include/final/fmenubar.h b/src/include/final/fmenubar.h index 45b8110f..7651288c 100644 --- a/src/include/final/fmenubar.h +++ b/src/include/final/fmenubar.h @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2015-2020 Markus Gans * +* Copyright 2015-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -132,6 +132,7 @@ class FMenuBar : public FWindow, public FMenuList void drawLeadingSpace (std::size_t&); void drawTrailingSpace (std::size_t&); void adjustItems() const; + void openMenu (const FMenuItem*); bool activateMenu (const FMenuItem*); bool clickItem (FMenuItem*); void unselectMenuItem (FMenuItem*); diff --git a/src/include/final/ftypes.h b/src/include/final/ftypes.h index 76826716..1275b600 100644 --- a/src/include/final/ftypes.h +++ b/src/include/final/ftypes.h @@ -49,7 +49,7 @@ << ": Not enough memory to alloc " \ << (object_name) \ << " in " \ - << __func__ << std::endl; + << __func__ << std::endl // ; using uChar = unsigned char; using uShort = unsigned short;