From 6d72168ca40b9d1873d4a51421596cb0f78b2404 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Tue, 11 Aug 2020 23:04:46 +0200 Subject: [PATCH] New callback backend was implemented --- ChangeLog | 4 + doc/class_template.h | 1 - doc/first-steps.md | 82 ++--- doc/user-theme.md | 10 +- examples/7segment.cpp | 11 +- examples/background-color.cpp | 16 +- examples/busy.cpp | 13 +- examples/calculator.cpp | 25 +- examples/checklist.cpp | 6 +- examples/choice.cpp | 9 +- examples/dialog.cpp | 7 +- examples/fullwidth-character.cpp | 14 +- examples/input-dialog.cpp | 30 +- examples/listbox.cpp | 4 +- examples/listview.cpp | 10 +- examples/menu.cpp | 12 +- examples/mouse.cpp | 6 +- examples/scrollview.cpp | 28 +- examples/term-attributes.cpp | 12 +- examples/treeview.cpp | 4 +- examples/ui.cpp | 185 +++++------ examples/watch.cpp | 16 +- examples/windows.cpp | 72 +++-- src/Makefile.am | 2 + src/Makefile.clang | 2 + src/Makefile.gcc | 2 + src/fbuttongroup.cpp | 8 +- src/fcallback.cpp | 42 +++ src/fcombobox.cpp | 16 +- src/fdialog.cpp | 15 +- src/ffiledialog.cpp | 24 +- src/flabel.cpp | 8 +- src/fmenu.cpp | 17 +- src/fmenubar.cpp | 14 +- src/fmenuitem.cpp | 29 +- src/fmessagebox.cpp | 17 +- src/fradiomenuitem.cpp | 3 +- src/fspinbox.cpp | 15 +- src/fstatusbar.cpp | 10 +- src/fvterm.cpp | 4 +- src/fwidget.cpp | 101 +----- src/fwidget_functions.cpp | 7 + src/include/final/fapplication.h | 13 +- src/include/final/fbuttongroup.h | 2 +- src/include/final/fcallback.h | 449 ++++++++++++++++++++++++++ src/include/final/fcombobox.h | 8 +- src/include/final/fdialog.h | 6 +- src/include/final/ffiledialog.h | 12 +- src/include/final/flabel.h | 2 +- src/include/final/fmenu.h | 6 +- src/include/final/fmenubar.h | 2 +- src/include/final/fmenuitem.h | 4 +- src/include/final/fmessagebox.h | 2 +- src/include/final/fscrollbar.h | 2 +- src/include/final/fspinbox.h | 4 +- src/include/final/fstatusbar.h | 2 +- src/include/final/ftypes.h | 41 +-- src/include/final/fvterm.h | 2 +- src/include/final/fwidget.h | 161 +++------- test/Makefile.am | 2 + test/fcallback-test.cpp | 534 +++++++++++++++++++++++++++++++ 61 files changed, 1524 insertions(+), 643 deletions(-) create mode 100644 src/fcallback.cpp create mode 100644 src/include/final/fcallback.h create mode 100644 test/fcallback-test.cpp diff --git a/ChangeLog b/ChangeLog index 35a3eed8..e5bfbfd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2020-08-11 Markus Gans + * New callback backend was implemented. Callback functions with any + number of arguments are now possible. + 2020-07-19 Markus Gans * API: Some method name changes: FObject::delOwnTimer() -> FObject::delOwnTimers() diff --git a/doc/class_template.h b/doc/class_template.h index c3cc4325..c8352d65 100644 --- a/doc/class_template.h +++ b/doc/class_template.h @@ -126,4 +126,3 @@ class FClassName #endif // FCLASSNAME_H - diff --git a/doc/first-steps.md b/doc/first-steps.md index e42e0b11..a52e48a0 100644 --- a/doc/first-steps.md +++ b/doc/first-steps.md @@ -609,10 +609,8 @@ use `delAllCallbacks()` to remove all existing callbacks from an object. using namespace finalcut; -void cb_changeText (FWidget* w, FDataPtr data) +void cb_changeText (const FButton& button, FLabel& label) { - FButton& button = *(static_cast(w)); - FLabel& label = *(static_cast(data)); label.clear(); label << "The " << button.getClassName() << " was pressed"; label.redraw(); @@ -635,9 +633,10 @@ int main (int argc, char* argv[]) // Connect the button signal "clicked" with the callback function button.addCallback ( - "clicked", - F_FUNCTION_CALLBACK (&cb_changeText), - &label + "clicked", // Callback signal + &cb_changeText, // Function pointer + std::cref(button), // First function argument + std::ref(label) // Second function argument ); FWidget::setMainWidget(&dialog); @@ -683,11 +682,9 @@ int main (int argc, char* argv[]) // Connect the button signal "clicked" with the lambda expression button.addCallback ( - "clicked", - [] (FWidget* w, FDataPtr d) + "clicked", // Callback signal + [] (FButton& button, FDialog& dgl) // Lambda function { - FButton& button = *(static_cast(w)); - if ( button.getY() != 2 ) { button.setPos (FPoint{15, 2}); @@ -699,9 +696,10 @@ int main (int argc, char* argv[]) button.setText("&bottom"); } - static_cast(d)->redraw(); + dgl.redraw(); }, - &dialog + std::ref(button), // First function argument + std::ref(dialog) // Second function argument ); FWidget::setMainWidget(&dialog); @@ -748,9 +746,10 @@ class dialogWidget : public FDialog // Connect the button signal "clicked" with the callback method button.addCallback ( - "clicked", - F_METHOD_CALLBACK (this, &FApplication::cb_exitApp), - nullptr + "clicked", // Callback signal + finalcut::getFApplication(), // Class instance + &finalcut::FApplication::cb_exitApp, // Method pointer + this // Function argument ); } @@ -810,45 +809,22 @@ class dialogWidget : public FDialog label.setAlignment (fc::alignRight); label.setForegroundColor (fc::Black); plus.setGeometry (FPoint{3, 3}, size); - minus.setGeometry (FPoint{13, 3}, size); + minus.setGeometry (FPoint{3, 3} + FPoint{10, 0}, size); plus.setNoUnderline(); minus.setNoUnderline(); // Connect the button signal "clicked" with the callback method - plus.addCallback - ( - "clicked", - F_METHOD_CALLBACK (this, &dialogWidget::cb_plus) - ); - - minus.addCallback - ( - "clicked", - F_METHOD_CALLBACK (this, &dialogWidget::cb_minus) - ); + plus.addCallback ("clicked", this, &dialogWidget::cb_plus); + minus.addCallback ("clicked", this, &dialogWidget::cb_minus); // Connect own signals - addCallback - ( - "hot", - F_METHOD_CALLBACK (this, &dialogWidget::cb_set_red) - ); - - addCallback - ( - "regular", - F_METHOD_CALLBACK (this, &dialogWidget::cb_set_black) - ); - - addCallback - ( - "cold", - F_METHOD_CALLBACK (this, &dialogWidget::cb_set_blue) - ); + addCallback ("hot", this, &dialogWidget::cb_set_red); + addCallback ("regular", this, &dialogWidget::cb_set_black); + addCallback ("cold", this, &dialogWidget::cb_set_blue); } private: - void cb_plus (FWidget*, FDataPtr) + void cb_plus() { if ( t < 100 ) t++; @@ -861,7 +837,7 @@ class dialogWidget : public FDialog setTemperature(); } - void cb_minus (FWidget*, FDataPtr) + void cb_minus() { if ( t > -99 ) t--; @@ -874,17 +850,17 @@ class dialogWidget : public FDialog setTemperature(); } - void cb_set_blue (FWidget*, FDataPtr) + void cb_set_blue() { label.setForegroundColor (fc::Blue); } - void cb_set_black (FWidget*, FDataPtr) + void cb_set_black() { label.setForegroundColor (fc::Black); } - void cb_set_red (FWidget*, FDataPtr) + void cb_set_red() { label.setForegroundColor (fc::Red); } @@ -1291,8 +1267,7 @@ class dialogWidget : public FDialog btn->addCallback ( "clicked", - F_METHOD_CALLBACK (this, &dialogWidget::cb_button), - static_cast(&std::get<2>(b)) + this, &dialogWidget::cb_button, std::get<2>(b) ); }; } @@ -1300,10 +1275,9 @@ class dialogWidget : public FDialog private: typedef std::tuple direction; - void cb_button (FWidget*, FDataPtr data) + void cb_button (const FPoint& p) { - FPoint* p = static_cast(data); - scrollview.scrollTo(*p); + scrollview.scrollTo(p); } FScrollView scrollview{this}; diff --git a/doc/user-theme.md b/doc/user-theme.md index 483b6a60..fc59dd45 100644 --- a/doc/user-theme.md +++ b/doc/user-theme.md @@ -370,7 +370,7 @@ class dialogWidget final : public FDialog Browse.addCallback ( "clicked", - F_METHOD_CALLBACK (this, &dialogWidget::cb_FileBrowse) + this, &dialogWidget::cb_FileBrowse ); Apply.setGeometry (FPoint{24, 5}, FSize{10, 1}); Apply.setStatusbarMessage("Apply settings"); @@ -379,17 +379,19 @@ class dialogWidget final : public FDialog Quit.addCallback ( "clicked", - F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp) + finalcut::getFApplication(), + &finalcut::FApplication::cb_exitApp, + this ); Open.addCallback ( "clicked", - F_METHOD_CALLBACK (this, &dialogWidget::cb_FileBrowse) + this, &dialogWidget::cb_FileBrowse ); } private: - void cb_FileBrowse (finalcut::FWidget*, FDataPtr) + void cb_FileBrowse() { auto filename = FFileDialog::fileOpenChooser(this); diff --git a/examples/7segment.cpp b/examples/7segment.cpp index b46eee0d..89991113 100644 --- a/examples/7segment.cpp +++ b/examples/7segment.cpp @@ -100,18 +100,19 @@ SegmentView::SegmentView (finalcut::FWidget* parent) Input.addCallback ( "changed", - [] (const finalcut::FWidget*, FDataPtr data) + [] (SegmentView& dialog) { - auto dialog = static_cast(data); - dialog->redraw(); + dialog.redraw(); }, - this + std::ref(*this) ); Exit.addCallback ( "clicked", - F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp) + finalcut::getFApplication(), + &finalcut::FApplication::cb_exitApp, + this ); } diff --git a/examples/background-color.cpp b/examples/background-color.cpp index c44f0a95..3b0d16eb 100644 --- a/examples/background-color.cpp +++ b/examples/background-color.cpp @@ -58,8 +58,8 @@ class Background final : public finalcut::FDialog private: // Callback method - void cb_changed (const finalcut::FWidget*, const FDataPtr); - void cb_choice (const finalcut::FWidget*, const FDataPtr); + void cb_changed(); + void cb_choice(); // Data members finalcut::FComboBox color_choice{this}; @@ -148,7 +148,9 @@ Background::Background (finalcut::FWidget* parent) quit.addCallback ( "clicked", - F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp) + finalcut::getFApplication(), + &finalcut::FApplication::cb_exitApp, + this ); for (const auto spinbox : {&red, &green, &blue}) @@ -156,7 +158,7 @@ Background::Background (finalcut::FWidget* parent) spinbox->addCallback ( "changed", - F_METHOD_CALLBACK (this, &Background::cb_changed) + this, &Background::cb_changed ); } @@ -165,7 +167,7 @@ Background::Background (finalcut::FWidget* parent) color_choice.addCallback ( signal, - F_METHOD_CALLBACK (this, &Background::cb_choice) + this, &Background::cb_choice ); } } @@ -175,7 +177,7 @@ Background::~Background() // destructor { } //---------------------------------------------------------------------- -void Background::cb_changed (const finalcut::FWidget*, const FDataPtr) +void Background::cb_changed() { if ( ! finalcut::FTerm::canChangeColorPalette() ) return; @@ -189,7 +191,7 @@ void Background::cb_changed (const finalcut::FWidget*, const FDataPtr) } //---------------------------------------------------------------------- -void Background::cb_choice (const finalcut::FWidget*, const FDataPtr) +void Background::cb_choice() { if ( ! finalcut::FTerm::canChangeColorPalette() ) return; diff --git a/examples/busy.cpp b/examples/busy.cpp index f867fd0f..24e3bf22 100644 --- a/examples/busy.cpp +++ b/examples/busy.cpp @@ -41,7 +41,7 @@ class Dialog final : public finalcut::FDialog void onTimer (finalcut::FTimerEvent*) override; // Callback method - void cb_start (const finalcut::FWidget*, const FDataPtr); + void cb_start(); // Data members finalcut::FSpinBox seconds{this}; @@ -67,21 +67,22 @@ Dialog::Dialog (FWidget* parent) seconds.addCallback ( "activate", - F_METHOD_CALLBACK (this, &Dialog::cb_start) + this, &Dialog::cb_start ); start.addCallback ( "clicked", - F_METHOD_CALLBACK (this, &Dialog::cb_start) + this, &Dialog::cb_start ); quit.addCallback ( "clicked", - F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp) + finalcut::getFApplication(), + &finalcut::FApplication::cb_exitApp, + this ); - } //---------------------------------------------------------------------- @@ -105,7 +106,7 @@ void Dialog::onTimer (finalcut::FTimerEvent*) } //---------------------------------------------------------------------- -void Dialog::cb_start (const finalcut::FWidget*, const FDataPtr) +void Dialog::cb_start() { if ( seconds.getValue() < 1 ) return; diff --git a/examples/calculator.cpp b/examples/calculator.cpp index 1c9eb947..8160f41e 100644 --- a/examples/calculator.cpp +++ b/examples/calculator.cpp @@ -119,13 +119,6 @@ class Calc final : public finalcut::FDialog // Destructor ~Calc() override; - // Event handlers - void onKeyPress (finalcut::FKeyEvent*) override; - void onClose (finalcut::FCloseEvent*) override; - - // Callback method - void cb_buttonClicked (const finalcut::FWidget*, FDataPtr); - private: // Typedef and Enumeration typedef std::function keyFunction; // Member function @@ -218,6 +211,13 @@ class Calc final : public finalcut::FDialog const wchar_t* getButtonText (const std::size_t) const; void mapKeyFunctions(); + // Event handlers + void onKeyPress (finalcut::FKeyEvent*) override; + void onClose (finalcut::FCloseEvent*) override; + + // Callback method + void cb_buttonClicked (Calc::button); + // Data members bool error{false}; bool arcus_mode{false}; @@ -230,7 +230,7 @@ class Calc final : public finalcut::FDialog char infix_operator{'\0'}; char last_infix_operator{'\0'}; finalcut::FString input{""}; - std::size_t button_no[Calc::NUM_OF_BUTTONS]{}; + button button_no[Calc::NUM_OF_BUTTONS]{}; struct stack_data { @@ -257,7 +257,7 @@ Calc::Calc (FWidget* parent) clearInfixOperator(); std::setlocale(LC_NUMERIC, "C"); - for (std::size_t key{0}; key < Calc::NUM_OF_BUTTONS; key++) + for (button key{Sine}; key < Calc::NUM_OF_BUTTONS; key = button(key + 1)) { auto btn = std::make_shared