diff --git a/examples/event-log.cpp b/examples/event-log.cpp index a3bd7095..0153d1d7 100644 --- a/examples/event-log.cpp +++ b/examples/event-log.cpp @@ -283,10 +283,7 @@ EventLog::EventLog (finalcut::FWidget* parent) //---------------------------------------------------------------------- EventLog::~EventLog() // destructor -{ - if ( event_dialog ) - delete event_dialog; -} +{ } //---------------------------------------------------------------------- void EventLog::onTimer (finalcut::FTimerEvent*) diff --git a/src/fapplication.cpp b/src/fapplication.cpp index 7c43f8c7..65ce075e 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -20,7 +20,6 @@ * . * ***********************************************************************/ -#include #include #include #include @@ -70,7 +69,7 @@ uInt64 FApplication::next_event_wait {5000}; // preset to 5 ms (200 struct timeval FApplication::time_last_event{}; -constexpr FApplication::CmdOption FApplication::long_options[] = +const std::vector FApplication::long_options = { {"encoding", required_argument, nullptr, 'e' }, {"log-file", required_argument, nullptr, 'l' }, @@ -485,81 +484,70 @@ void FApplication::setTerminalEncoding (const FString& enc_str) } //---------------------------------------------------------------------- -void FApplication::cmd_options (const int& argc, char* argv[]) +inline FApplication::CmdMap& FApplication::mapCmdOptions() +{ + using std::placeholders::_1; + auto enc = std::bind(&FApplication::setTerminalEncoding, _1); + auto log = std::bind(&FApplication::setLogFile, _1); + auto opt = &FApplication::getStartOptions; + static CmdMap cmd_map{}; + + // --encoding + cmd_map['e'] = [enc] (char* arg) { enc(FString(arg)); }; + // --log-file + cmd_map['l'] = [log] (char* arg) { log(FString(arg)); }; + // --no-mouse + cmd_map['m'] = [opt] (char*) { opt().mouse_support = false; }; + // --no-optimized-cursor + cmd_map['o'] = [opt] (char*) { opt().cursor_optimisation = false; }; + // --no-terminal-detection + cmd_map['d'] = [opt] (char*) { opt().terminal_detection = false; }; + // --no-terminal-data-request + cmd_map['r'] = [opt] (char*) { opt().terminal_data_request = false; }; + // --no-color-change + cmd_map['c'] = [opt] (char*) { opt().color_change = false; }; + // --no-sgr-optimizer + cmd_map['s'] = [opt] (char*) { opt().sgr_optimizer = false; }; + // --vgafont + cmd_map['v'] = [opt] (char*) { opt().vgafont = true; }; + // --newfont + cmd_map['n'] = [opt] (char*) { opt().newfont = true; }; + // --dark-theme + cmd_map['t'] = [opt] (char*) { opt().dark_theme = true; }; +#if defined(__FreeBSD__) || defined(__DragonFly__) + // --no-esc-for-alt-meta + cmd_map['E'] = [opt] (char*) { opt().meta_sends_escape = false; }; + // --no-cursorstyle-change + cmd_map['C'] = [opt] (char*) { opt().change_cursorstyle = false; }; +#elif defined(__NetBSD__) || defined(__OpenBSD__) + // --no-esc-for-alt-meta + cmd_map['E'] = [opt] (char*) { opt().meta_sends_escape = false; }; +#endif + return cmd_map; +} + +//---------------------------------------------------------------------- +void FApplication::cmdOptions (const int& argc, char* argv[]) { // Interpret the command line options + auto& cmd_map = mapCmdOptions(); + while ( true ) { opterr = 0; int idx{0}; - auto p = reinterpret_cast(long_options); + auto p = reinterpret_cast(long_options.data()); const int opt = getopt_long (argc, argv, "", p, &idx); if ( opt == -1 ) break; - switch ( opt ) - { - case 'e': // --encoding - setTerminalEncoding(FString(optarg)); - break; - - case 'l': // --log-file - setLogFile(FString(optarg)); - break; - - case 'm': // --no-mouse - getStartOptions().mouse_support = false; - break; - - case 'o': // --no-optimized-cursor - getStartOptions().cursor_optimisation = false; - break; - - case 'd': // --no-terminal-detection - getStartOptions().terminal_detection = false; - break; - - case 'r': // --no-terminal-data-request - getStartOptions().terminal_data_request = false; - break; - - case 'c': // --no-color-change - getStartOptions().color_change = false; - break; - - case 's': // --no-sgr-optimizer - getStartOptions().sgr_optimizer = false; - break; - - case 'v': // --vgafont - getStartOptions().vgafont = true; - break; - - case 'n': // --newfont - getStartOptions().newfont = true; - break; - - case 't': // --dark-theme - getStartOptions().dark_theme = true; - break; - - #if defined(__FreeBSD__) || defined(__DragonFly__) - case 'E': // --no-esc-for-alt-meta - getStartOptions().meta_sends_escape = false; - break; - - case 'C': // --no-cursorstyle-change - getStartOptions().change_cursorstyle = false; - break; - #elif defined(__NetBSD__) || defined(__OpenBSD__) - case 'E': // --no-esc-for-alt-meta - getStartOptions().meta_sends_escape = false; - break; - #endif - } + if ( cmd_map.find(opt) != cmd_map.end() ) + cmd_map[opt](optarg); } + + cmd_map.clear(); } //---------------------------------------------------------------------- @@ -848,34 +836,30 @@ bool FApplication::processAccelerator (const FWidget* const& widget) const { bool accpt{false}; - if ( widget - && ! widget->getAcceleratorList().empty() ) + if ( widget && widget->getAcceleratorList().empty() ) + return accpt; + + for (auto&& item : widget->getAcceleratorList()) { - auto iter = widget->getAcceleratorList().begin(); - const auto& last = widget->getAcceleratorList().end(); - - while ( iter != last && ! quit_now && ! app_exit_loop ) + if ( item.key == keyboard->getKey() ) { - if ( iter->key == keyboard->getKey() ) + // unset the move/size mode + auto move_size = getMoveSizeWidget(); + + if ( move_size ) { - // unset the move/size mode - auto move_size = getMoveSizeWidget(); - - if ( move_size ) - { - auto w = move_size; - setMoveSizeWidget(nullptr); - w->redraw(); - } - - FAccelEvent a_ev (fc::Accelerator_Event, getFocusWidget()); - sendEvent (iter->object, &a_ev); - accpt = a_ev.isAccepted(); - break; + setMoveSizeWidget(nullptr); + move_size->redraw(); } - ++iter; + FAccelEvent a_ev (fc::Accelerator_Event, getFocusWidget()); + sendEvent (item.object, &a_ev); + accpt = a_ev.isAccepted(); + break; } + + if ( quit_now || app_exit_loop ) + break; } return accpt; @@ -1225,7 +1209,7 @@ FWidget* FApplication::processParameters (const int& argc, char* argv[]) FApplication::exit(EXIT_SUCCESS); } - cmd_options (argc, argv); + cmdOptions (argc, argv); return nullptr; } diff --git a/src/fbuttongroup.cpp b/src/fbuttongroup.cpp index 1ae70041..85675a74 100644 --- a/src/fbuttongroup.cpp +++ b/src/fbuttongroup.cpp @@ -309,40 +309,7 @@ void FButtonGroup::onAccel (FAccelEvent*) void FButtonGroup::onFocusIn (FFocusEvent* in_ev) { in_ev->ignore(); // Change default value to ignore - - if ( hasCheckedButton() && ! buttonlist.empty() ) - { - for (auto&& item : buttonlist) - { - auto toggle_button = static_cast(item); - - if ( toggle_button->isChecked() ) - { - if ( isRadioButton(toggle_button) ) - { - auto prev_element = getFocusWidget(); - - toggle_button->setFocus(); - - FFocusEvent cfi (fc::ChildFocusIn_Event); - FApplication::sendEvent(this, &cfi); - - FFocusEvent in (fc::FocusIn_Event); - FApplication::sendEvent(toggle_button, &in); - - if ( in.isAccepted() ) - in_ev->accept(); - - if ( prev_element ) - prev_element->redraw(); - - toggle_button->redraw(); - } - - break; - } - } // end of range-based for loop - } + focusInRadioButton (in_ev); if ( ! in_ev->isAccepted() ) { @@ -483,54 +450,63 @@ void FButtonGroup::drawText ( const FString& label_text setReverse(true); } +//---------------------------------------------------------------------- +bool FButtonGroup::directFocusCheckedRadioButton (FToggleButton* item) +{ + if ( ! isRadioButton(item) ) + return false; + + auto focused_widget = getFocusWidget(); + item->setFocus(); + + if ( focused_widget ) + focused_widget->redraw(); + + focused_widget = getFocusWidget(); + + if ( focused_widget ) + focused_widget->redraw(); + + return true; +} + +//---------------------------------------------------------------------- +bool FButtonGroup::directFocusRadioButton() +{ + if ( ! hasCheckedButton() || buttonlist.empty() ) + return false; + + bool found_checked{false}; + + for (auto&& item : buttonlist) + { + auto toggle_button = static_cast(item); + + if ( toggle_button->isChecked() ) + { + found_checked = directFocusCheckedRadioButton(toggle_button); + break; + } + } + + return found_checked; +} + //---------------------------------------------------------------------- void FButtonGroup::directFocus() { - if ( ! hasFocusedButton() ) + if ( ! hasFocusedButton() && ! directFocusRadioButton() ) { - bool found_checked{false}; + auto focused_widget = getFocusWidget(); + focusFirstChild(); - if ( hasCheckedButton() && ! buttonlist.empty() ) - { - for (auto&& item : buttonlist) - { - auto toggle_button = static_cast(item); + if ( focused_widget ) + focused_widget->redraw(); - if ( toggle_button->isChecked() ) - { - if ( isRadioButton(toggle_button) ) - { - found_checked = true; - auto focused_widget = getFocusWidget(); - toggle_button->setFocus(); + focused_widget = getFocusWidget(); - if ( focused_widget ) - focused_widget->redraw(); - - focused_widget = getFocusWidget(); - - if ( focused_widget ) - focused_widget->redraw(); - } - - break; - } - } // end of range-based for loop - } - - if ( ! found_checked ) - { - auto focused_widget = getFocusWidget(); - focusFirstChild(); - - if ( focused_widget ) - focused_widget->redraw(); - - focused_widget = getFocusWidget(); - - if ( focused_widget ) - focused_widget->redraw(); - } + if ( focused_widget ) + focused_widget->redraw(); } if ( getStatusBar() ) @@ -541,6 +517,49 @@ void FButtonGroup::directFocus() } } +//---------------------------------------------------------------------- +void FButtonGroup::focusCheckedRadioButton ( FToggleButton* toggle_button + , FFocusEvent* in_ev ) +{ + auto prev_element = getFocusWidget(); + + toggle_button->setFocus(); + + FFocusEvent cfi (fc::ChildFocusIn_Event); + FApplication::sendEvent(this, &cfi); + + FFocusEvent in (fc::FocusIn_Event); + FApplication::sendEvent(toggle_button, &in); + + if ( in.isAccepted() ) + in_ev->accept(); + + if ( prev_element ) + prev_element->redraw(); + + toggle_button->redraw(); +} + +//---------------------------------------------------------------------- +void FButtonGroup::focusInRadioButton (FFocusEvent* in_ev) +{ + if ( ! hasCheckedButton() || buttonlist.empty() ) + return; + + for (auto&& item : buttonlist) + { + auto toggle_button = static_cast(item); + + if ( toggle_button->isChecked() ) + { + if ( isRadioButton(toggle_button) ) + focusCheckedRadioButton (toggle_button, in_ev); + + break; + } + } +} + //---------------------------------------------------------------------- void FButtonGroup::cb_buttonToggled (const FToggleButton* button) const { diff --git a/src/flistbox.cpp b/src/flistbox.cpp index e840233e..0d4d589b 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -1622,31 +1622,29 @@ inline bool FListBox::deletePreviousCharacter() { const std::size_t inc_len = inc_search.getLength(); - if ( inc_len > 0 ) + if ( inc_len <= 0 ) + return false; + + inc_search.remove(inc_len - 1, 1); + + if ( inc_len > 1 ) { - inc_search.remove(inc_len - 1, 1); + auto iter = itemlist.begin(); - if ( inc_len > 1 ) + while ( iter != itemlist.end() ) { - auto iter = itemlist.begin(); - - while ( iter != itemlist.end() ) + if ( inc_search.toLower() + == iter->getText().left(inc_len - 1).toLower() ) { - if ( inc_search.toLower() - == iter->getText().left(inc_len - 1).toLower() ) - { - setCurrentItem(iter); - break; - } - - ++iter; + setCurrentItem(iter); + break; } - } - return true; + ++iter; + } } - return false; + return true; } //---------------------------------------------------------------------- diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index e03f7dd2..347a20fa 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -50,7 +50,7 @@ FMenuBar::FMenuBar(FWidget* parent) //---------------------------------------------------------------------- FMenuBar::~FMenuBar() // destructor { - setMenuBar(nullptr); + FWidget::setMenuBar(nullptr); } diff --git a/src/fterm.cpp b/src/fterm.cpp index 066f4336..f4c9b047 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -713,6 +713,7 @@ bool FTerm::setVGAFont() data->setVGAFont(true); // Set font in xterm to vga getFTermXTerminal()->setFont("vga"); + data->setTermEncoding (fc::PC); data->setNewFont(false); } #if defined(__linux__) @@ -1362,13 +1363,13 @@ void FTerm::init_global_values() //---------------------------------------------------------------------- void FTerm::init_terminal_device_path() { - char termfilename[256]{}; + std::array termfilename{}; const int stdout_no = FTermios::getStdOut(); - if ( ttyname_r(stdout_no, termfilename, sizeof(termfilename)) ) + if ( ttyname_r(stdout_no, termfilename.data(), termfilename.size()) ) termfilename[0] = '\0'; - data->setTermFileName(termfilename); + data->setTermFileName(termfilename.data()); } //---------------------------------------------------------------------- @@ -2005,21 +2006,22 @@ const char* FTerm::enableCursorString() // Returns the cursor enable string static constexpr std::size_t SIZE = 32; - static char enable_str[SIZE]{}; + static std::array enable_str{}; const auto& vs = TCAP(fc::t_cursor_visible); const auto& ve = TCAP(fc::t_cursor_normal); if ( ve ) - std::strncpy (enable_str, ve, SIZE - 1); + std::strncpy (enable_str.data(), ve, SIZE - 1); else if ( vs ) - std::strncpy (enable_str, vs, SIZE - 1); + std::strncpy (enable_str.data(), vs, SIZE - 1); #if defined(__linux__) if ( isLinuxTerm() ) { // Restore the last used Linux console cursor style const char* cstyle = linux->getCursorStyleString(); - std::strncat (enable_str, cstyle, SIZE - std::strlen(enable_str) - 1); + std::size_t length = std::strlen(enable_str.data()); + std::strncat (enable_str.data(), cstyle, SIZE - length - 1); } #endif // defined(__linux__) @@ -2033,7 +2035,7 @@ const char* FTerm::enableCursorString() } #endif // defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST) - return enable_str; + return enable_str.data(); } //---------------------------------------------------------------------- diff --git a/src/ftermlinux.cpp b/src/ftermlinux.cpp index 1d574d71..fa1534a6 100644 --- a/src/ftermlinux.cpp +++ b/src/ftermlinux.cpp @@ -76,10 +76,10 @@ char* FTermLinux::getCursorStyleString() { // Gets the current cursor style string of the Linux console - static char buf[16]{}; + static std::array buf{}; std::fill (std::begin(buf), std::end(buf), '\0'); - std::snprintf (buf, sizeof(buf), CSI "?%dc", getCursorStyle()); - return buf; + std::snprintf (buf.data(), buf.size(), CSI "?%dc", getCursorStyle()); + return buf.data(); } //---------------------------------------------------------------------- diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 5dfb4856..279f9c8c 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -966,13 +966,10 @@ void FWidget::show() { for (auto&& child : getChildren()) { - if ( child->isWidget() ) - { - auto widget = static_cast(child); + auto widget = static_cast(child); - if ( ! widget->flags.hidden ) - widget->show(); - } + if ( child->isWidget() && ! widget->flags.hidden ) + widget->show(); } } @@ -1316,13 +1313,10 @@ void FWidget::adjustSize() { for (auto&& child : getChildren()) { - if ( child->isWidget() ) - { - auto widget = static_cast(child); + auto widget = static_cast(child); - if ( ! widget->isWindowWidget() ) - widget->adjustSize(); - } + if ( child->isWidget() && ! widget->isWindowWidget() ) + widget->adjustSize(); } } } diff --git a/src/fwindow.cpp b/src/fwindow.cpp index 5d005844..b1b50c8d 100644 --- a/src/fwindow.cpp +++ b/src/fwindow.cpp @@ -437,13 +437,12 @@ FWindow* FWindow::getWindowWidgetAt (int x, int y) do { --iter; - if ( *iter ) - { - auto w = static_cast(*iter); + auto w = static_cast(*iter); - if ( ! w->isWindowHidden() - && w->getTermGeometry().contains(x, y) ) - return w; + if ( *iter && ! w->isWindowHidden() + && w->getTermGeometry().contains(x, y) ) + { + return w; } } while ( iter != begin ); diff --git a/src/include/final/fapplication.h b/src/include/final/fapplication.h index 17bf7daa..e9803d9d 100644 --- a/src/include/final/fapplication.h +++ b/src/include/final/fapplication.h @@ -64,6 +64,8 @@ #include #include #include +#include +#include #include "final/ftypes.h" #include "final/fwidget.h" @@ -151,11 +153,13 @@ class FApplication : public FWidget // Typedefs typedef std::pair EventPair; typedef std::deque FEventQueue; + typedef std::unordered_map> CmdMap; // Methods void init(); static void setTerminalEncoding (const FString&); - static void cmd_options (const int&, char*[]); + static CmdMap& mapCmdOptions(); + static void cmdOptions (const int&, char*[]); static FStartOptions& getStartOptions(); static void showParameterUsage(); void destroyLog(); @@ -231,7 +235,7 @@ class FApplication : public FWidget using CmdOption = struct option; #endif - static const CmdOption long_options[]; + static const std::vector long_options; }; diff --git a/src/include/final/fbuttongroup.h b/src/include/final/fbuttongroup.h index 410f186a..65a0c6b8 100644 --- a/src/include/final/fbuttongroup.h +++ b/src/include/final/fbuttongroup.h @@ -127,7 +127,11 @@ class FButtonGroup : public FScrollView // Methods void init(); void drawText (const FString&, std::size_t); + bool directFocusCheckedRadioButton (FToggleButton*); + bool directFocusRadioButton(); void directFocus(); + void focusCheckedRadioButton (FToggleButton*, FFocusEvent*); + void focusInRadioButton (FFocusEvent*); // Callback method void cb_buttonToggled (const FToggleButton*) const; diff --git a/src/include/final/flog.h b/src/include/final/flog.h index 67e6f927..ffc5b56f 100644 --- a/src/include/final/flog.h +++ b/src/include/final/flog.h @@ -98,7 +98,7 @@ class FLog : public std::stringbuf protected: int sync() override; - const LogLevel& getLevel(); + const LogLevel& getLevel() const; LogLevel& setLevel(); const LineEnding& getEnding(); LineEnding& setEnding(); @@ -139,7 +139,7 @@ inline FString FLog::getClassName() const { return "FLog"; } //---------------------------------------------------------------------- -inline const FLog::LogLevel& FLog::getLevel() +inline const FLog::LogLevel& FLog::getLevel() const { return level; }