New callback backend was implemented

This commit is contained in:
Markus Gans 2020-08-11 23:04:46 +02:00
parent 07127634fd
commit 6d72168ca4
61 changed files with 1524 additions and 643 deletions

View File

@ -1,3 +1,7 @@
2020-08-11 Markus Gans <guru.mail@muenster.de>
* New callback backend was implemented. Callback functions with any
number of arguments are now possible.
2020-07-19 Markus Gans <guru.mail@muenster.de>
* API: Some method name changes:
FObject::delOwnTimer() -> FObject::delOwnTimers()

View File

@ -126,4 +126,3 @@ class FClassName
#endif // FCLASSNAME_H

View File

@ -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<FButton*>(w));
FLabel& label = *(static_cast<FLabel*>(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<FButton*>(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<FDialog*>(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<FDataPtr>(&std::get<2>(b))
this, &dialogWidget::cb_button, std::get<2>(b)
);
};
}
@ -1300,10 +1275,9 @@ class dialogWidget : public FDialog
private:
typedef std::tuple<FString, FPoint, FPoint, FColorPair> direction;
void cb_button (FWidget*, FDataPtr data)
void cb_button (const FPoint& p)
{
FPoint* p = static_cast<FPoint*>(data);
scrollview.scrollTo(*p);
scrollview.scrollTo(p);
}
FScrollView scrollview{this};

View File

@ -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);

View File

@ -100,18 +100,19 @@ SegmentView::SegmentView (finalcut::FWidget* parent)
Input.addCallback
(
"changed",
[] (const finalcut::FWidget*, FDataPtr data)
[] (SegmentView& dialog)
{
auto dialog = static_cast<SegmentView*>(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
);
}

View File

@ -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;

View File

@ -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;

View File

@ -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<void(lDouble&)> 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<Button>(this);
button_no[key] = key;
@ -284,8 +284,8 @@ Calc::Calc (FWidget* parent)
btn->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Calc::cb_buttonClicked),
&button_no[key]
this, &Calc::cb_buttonClicked,
button_no[key]
);
calculator_buttons[button(key)] = btn;
@ -364,10 +364,9 @@ void Calc::onClose (finalcut::FCloseEvent* ev)
}
//----------------------------------------------------------------------
void Calc::cb_buttonClicked (const finalcut::FWidget*, FDataPtr data)
void Calc::cb_buttonClicked (Calc::button key)
{
lDouble& x = getValue();
const Calc::button& key = *(static_cast<Calc::button*>(data));
// Call the key function
key_map[key](x);

View File

@ -64,7 +64,7 @@ class CheckList final : public finalcut::FDialog
void onClose (finalcut::FCloseEvent*) override;
// Callback method
void cb_showList (const finalcut::FWidget*, const FDataPtr);
void cb_showList();
// Data members
finalcut::FListView listView{this};
@ -110,7 +110,7 @@ CheckList::CheckList (finalcut::FWidget* parent)
listView.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &CheckList::cb_showList)
this, &CheckList::cb_showList
);
}
@ -168,7 +168,7 @@ void CheckList::onClose (finalcut::FCloseEvent* ev)
}
//----------------------------------------------------------------------
void CheckList::cb_showList (const finalcut::FWidget*, const FDataPtr)
void CheckList::cb_showList()
{
auto iter = listView.beginOfList();
finalcut::FString shopping_list{};

View File

@ -31,17 +31,16 @@ using finalcut::FSize;
typedef std::shared_ptr<finalcut::FRadioButton> FRadioButtonPtr;
// Function prototypes
void cb_quit (const finalcut::FWidget*, FDataPtr);
void cb_quit (finalcut::FDialog&);
void populateChoice (std::vector<FRadioButtonPtr>&, finalcut::FButtonGroup&);
void preset (std::vector<FRadioButtonPtr>&);
//----------------------------------------------------------------------
// Callback functions
//----------------------------------------------------------------------
void cb_quit (const finalcut::FWidget*, FDataPtr data)
void cb_quit (finalcut::FDialog& dlg)
{
auto dlg = static_cast<finalcut::FDialog*>(data);
dlg->close();
dlg.close();
}
//----------------------------------------------------------------------
@ -141,7 +140,7 @@ int main (int argc, char* argv[])
(
"clicked",
&cb_quit,
&dgl
std::ref(dgl)
);
// Show the dialog

View File

@ -26,15 +26,14 @@ using finalcut::FPoint;
using finalcut::FSize;
// function prototype
void cb_quit (const finalcut::FWidget*, FDataPtr);
void cb_quit (finalcut::FApplication&);
//----------------------------------------------------------------------
// callback function
//----------------------------------------------------------------------
void cb_quit (const finalcut::FWidget*, FDataPtr data)
void cb_quit (finalcut::FApplication& app)
{
const auto& app = *(static_cast<finalcut::FApplication*>(data));
app.quit();
}
@ -77,7 +76,7 @@ int main (int argc, char* argv[])
(
"clicked",
&cb_quit,
&app
std::ref(app)
);
// Set dialog object as main widget

View File

@ -105,16 +105,14 @@ int main (int argc, char* argv[])
// Callback lambda expressions
auto cb_exit = \
[] (const finalcut::FWidget*, FDataPtr data)
[] (finalcut::FApplication& a)
{
auto a = static_cast<finalcut::FApplication*>(data);
a->quit();
a.quit();
};
auto cb_tooltip = \
[] (const finalcut::FWidget*, FDataPtr data)
[] (finalcut::FApplication* a)
{
auto a = static_cast<finalcut::FApplication*>(data);
finalcut::FToolTip tooltip(a);
tooltip.setText (full("A tooltip with\ncharacters\n"
"in full-width\nfor 3 seconds"));
@ -123,9 +121,9 @@ int main (int argc, char* argv[])
};
// Connect the signals with the callback lambda expressions
btn.addCallback ("clicked", cb_exit, &app);
Exit.addCallback ("clicked", cb_exit, &app);
Quit.addCallback ("clicked", cb_exit, &app);
btn.addCallback ("clicked", cb_exit, std::ref(app));
Exit.addCallback ("clicked", cb_exit, std::ref(app));
Quit.addCallback ("clicked", cb_exit, std::ref(app));
key_F1.addCallback ("activate", cb_tooltip, &app);
// Set dialog object as main widget

View File

@ -26,33 +26,30 @@ using finalcut::FPoint;
using finalcut::FSize;
// function prototypes
void cb_quit (const finalcut::FWidget*, FDataPtr);
void cb_publish (finalcut::FWidget*, FDataPtr);
void cb_quit (finalcut::FApplication&);
void cb_publish (finalcut::FCheckBox&, finalcut::FCheckBox&);
//----------------------------------------------------------------------
// callback functions
//----------------------------------------------------------------------
void cb_quit (const finalcut::FWidget*, FDataPtr data)
void cb_quit (finalcut::FApplication& app)
{
auto app = static_cast<finalcut::FApplication*>(data);
app->quit();
app.quit();
}
void cb_publish (finalcut::FWidget* widget, FDataPtr data)
//----------------------------------------------------------------------
void cb_publish (finalcut::FCheckBox& cbox1, finalcut::FCheckBox& cbox2)
{
auto cbox1 = static_cast<finalcut::FCheckBox*>(widget);
auto cbox2 = static_cast<finalcut::FCheckBox*>(data);
if ( cbox1->isChecked() )
cbox2->setEnable();
if ( cbox1.isChecked() )
cbox2.setEnable();
else
{
cbox2->unsetChecked();
cbox2->setDisable();
cbox2.unsetChecked();
cbox2.setDisable();
}
cbox2->redraw();
cbox2.redraw();
}
//----------------------------------------------------------------------
@ -124,7 +121,8 @@ int main (int argc, char* argv[])
(
"clicked",
&cb_publish,
&check2
std::ref(check1),
std::ref(check2)
);
// Connect the button signal "clicked" with the callback function
@ -132,7 +130,7 @@ int main (int argc, char* argv[])
(
"clicked",
&cb_quit,
&app
std::ref(app)
);
// Set dialog object as main widget

View File

@ -157,7 +157,9 @@ Listbox::Listbox (FWidget* parent)
Quit.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FApplication::cb_exitApp)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
}

View File

@ -59,7 +59,7 @@ class Listview final : public finalcut::FDialog
void onClose (finalcut::FCloseEvent*) override;
// Callback method
void cb_showInMessagebox (const finalcut::FWidget*, const FDataPtr);
void cb_showInMessagebox();
// Data members
finalcut::FListView listView{this};
@ -111,13 +111,15 @@ Listview::Listview (finalcut::FWidget* parent)
Quit.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
listView.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Listview::cb_showInMessagebox)
this, &Listview::cb_showInMessagebox
);
}
@ -187,7 +189,7 @@ void Listview::onClose (finalcut::FCloseEvent* ev)
}
//----------------------------------------------------------------------
void Listview::cb_showInMessagebox (const finalcut::FWidget*, const FDataPtr)
void Listview::cb_showInMessagebox()
{
const auto& item = listView.getCurrentItem();
finalcut::FMessageBox info ( "Weather in " + item->getText(1)

View File

@ -61,7 +61,7 @@ class Menu final : public finalcut::FDialog
void onClose (finalcut::FCloseEvent*) override;
// Callback method
void cb_message (finalcut::FWidget*, const FDataPtr);
void cb_message (finalcut::FMenuItem*);
// Data members
finalcut::FString line{13, fc::BoxDrawingsHorizontal};
@ -183,7 +183,9 @@ void Menu::configureFileMenuItems()
Quit.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
}
@ -275,7 +277,8 @@ void Menu::defaultCallback (const finalcut::FMenuList* mb)
item->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Menu::cb_message)
this, &Menu::cb_message,
item
);
// Call sub-menu
@ -302,9 +305,8 @@ void Menu::onClose (finalcut::FCloseEvent* ev)
}
//----------------------------------------------------------------------
void Menu::cb_message (finalcut::FWidget* widget, const FDataPtr)
void Menu::cb_message (finalcut::FMenuItem* menuitem)
{
const auto& menuitem = static_cast<finalcut::FMenuItem*>(widget);
auto text = menuitem->getText();
text = text.replace('&', "");
finalcut::FMessageBox::info ( this

View File

@ -353,7 +353,7 @@ class MouseDraw final : public finalcut::FDialog
void onMouseMove (finalcut::FMouseEvent*) override;
// Callback methods
void cb_colorChanged (const finalcut::FWidget*, const FDataPtr);
void cb_colorChanged();
// Data members
FTermArea* canvas{nullptr};
@ -371,7 +371,7 @@ MouseDraw::MouseDraw (finalcut::FWidget* parent)
c_chooser.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MouseDraw::cb_colorChanged)
this, &MouseDraw::cb_colorChanged
);
brush.setPos (FPoint{1, 12});
@ -572,7 +572,7 @@ void MouseDraw::onMouseMove (finalcut::FMouseEvent* ev)
}
//----------------------------------------------------------------------
void MouseDraw::cb_colorChanged (const finalcut::FWidget*, const FDataPtr)
void MouseDraw::cb_colorChanged()
{
brush.setForeground (c_chooser.getForeground());
brush.setBackground (c_chooser.getBackground());

View File

@ -54,10 +54,10 @@ class Scrollview final : public finalcut::FScrollView
void draw() override;
// Callback methods
void cb_goEast (const finalcut::FWidget*, const FDataPtr);
void cb_goSouth (const finalcut::FWidget*, const FDataPtr);
void cb_goWest (const finalcut::FWidget*, const FDataPtr);
void cb_goNorth (const finalcut::FWidget*, const FDataPtr);
void cb_goEast();
void cb_goSouth();
void cb_goWest();
void cb_goNorth();
// Data members
wchar_t pointer_right{fc::BlackRightPointingPointer};
@ -88,25 +88,25 @@ Scrollview::Scrollview (finalcut::FWidget* parent)
go_east.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Scrollview::cb_goEast)
this, &Scrollview::cb_goEast
);
go_south.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Scrollview::cb_goSouth)
this, &Scrollview::cb_goSouth
);
go_west.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Scrollview::cb_goWest)
this, &Scrollview::cb_goWest
);
go_north.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Scrollview::cb_goNorth)
this, &Scrollview::cb_goNorth
);
}
@ -150,7 +150,7 @@ void Scrollview::draw()
}
//----------------------------------------------------------------------
void Scrollview::cb_goEast (const finalcut::FWidget*, const FDataPtr)
void Scrollview::cb_goEast()
{
scrollToX (int(getScrollWidth() - getViewportWidth()) + 1);
go_south.setFocus();
@ -159,7 +159,7 @@ void Scrollview::cb_goEast (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void Scrollview::cb_goSouth (const finalcut::FWidget*, const FDataPtr)
void Scrollview::cb_goSouth()
{
scrollToY (int(getScrollHeight() - getViewportHeight()) + 1);
go_west.setFocus();
@ -168,7 +168,7 @@ void Scrollview::cb_goSouth (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void Scrollview::cb_goWest (const finalcut::FWidget*, const FDataPtr)
void Scrollview::cb_goWest()
{
scrollToX (1);
go_north.setFocus();
@ -177,7 +177,7 @@ void Scrollview::cb_goWest (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void Scrollview::cb_goNorth (const finalcut::FWidget*, const FDataPtr)
void Scrollview::cb_goNorth()
{
scrollToY (1);
go_east.setFocus();
@ -230,7 +230,9 @@ Scrollviewdemo::Scrollviewdemo (finalcut::FWidget* parent)
quit_btn.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &Scrollviewdemo::cb_quit)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
// Text label

View File

@ -58,8 +58,8 @@ class AttribDlg final : public finalcut::FDialog
void onClose (finalcut::FCloseEvent*) override;
// Callback methods
void cb_next (const finalcut::FWidget* = nullptr, const FDataPtr = nullptr);
void cb_back (const finalcut::FWidget* = nullptr, const FDataPtr = nullptr);
void cb_next();
void cb_back();
private:
// Constants
@ -90,13 +90,13 @@ AttribDlg::AttribDlg (finalcut::FWidget* parent)
next_button.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &AttribDlg::cb_next)
this, &AttribDlg::cb_next
);
back_button.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &AttribDlg::cb_back)
this, &AttribDlg::cb_back
);
}
@ -143,7 +143,7 @@ void AttribDlg::onClose (finalcut::FCloseEvent* ev)
}
//----------------------------------------------------------------------
void AttribDlg::cb_next (const finalcut::FWidget*, const FDataPtr)
void AttribDlg::cb_next()
{
if ( finalcut::FTerm::isMonochron() )
return;
@ -159,7 +159,7 @@ void AttribDlg::cb_next (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void AttribDlg::cb_back (const finalcut::FWidget*, const FDataPtr)
void AttribDlg::cb_back()
{
if ( finalcut::FTerm::isMonochron() )
return;

View File

@ -386,7 +386,9 @@ Treeview::Treeview (finalcut::FWidget* parent)
Quit.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
initialized = true;

View File

@ -63,9 +63,9 @@ class ProgressDialog final : public finalcut::FDialog
void onTimer (finalcut::FTimerEvent*) override;
// Callback methods
void cb_reset_bar (const finalcut::FWidget*, const FDataPtr);
void cb_more_bar (const finalcut::FWidget*, const FDataPtr);
void cb_exit_bar (const finalcut::FWidget*, const FDataPtr);
void cb_reset_bar();
void cb_more_bar();
void cb_exit_bar();
// Data members
finalcut::FProgressbar progressBar{this};
@ -107,19 +107,19 @@ ProgressDialog::ProgressDialog (finalcut::FWidget* parent)
reset.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &ProgressDialog::cb_reset_bar)
this, &ProgressDialog::cb_reset_bar
);
more.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &ProgressDialog::cb_more_bar)
this, &ProgressDialog::cb_more_bar
);
quit.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &ProgressDialog::cb_exit_bar)
this, &ProgressDialog::cb_exit_bar
);
}
@ -166,13 +166,13 @@ void ProgressDialog::onTimer (finalcut::FTimerEvent*)
}
//----------------------------------------------------------------------
void ProgressDialog::cb_reset_bar (const finalcut::FWidget*, const FDataPtr)
void ProgressDialog::cb_reset_bar()
{
progressBar.reset();
}
//----------------------------------------------------------------------
void ProgressDialog::cb_more_bar (const finalcut::FWidget*, const FDataPtr)
void ProgressDialog::cb_more_bar()
{
auto p = progressBar.getPercentage();
p++;
@ -180,7 +180,7 @@ void ProgressDialog::cb_more_bar (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void ProgressDialog::cb_exit_bar (const finalcut::FWidget*, const FDataPtr)
void ProgressDialog::cb_exit_bar()
{
close();
}
@ -293,22 +293,24 @@ class MyDialog final : public finalcut::FDialog
void onClose (finalcut::FCloseEvent*) override;
// Callback methods
void cb_noFunctionMsg (finalcut::FWidget*, const FDataPtr);
void cb_about (const finalcut::FWidget*, const FDataPtr);
void cb_terminfo (const finalcut::FWidget*, const FDataPtr);
void cb_drives (const finalcut::FWidget*, const FDataPtr);
void cb_cutClipboard (const finalcut::FWidget*, const FDataPtr);
void cb_copyClipboard (const finalcut::FWidget*, const FDataPtr);
void cb_pasteClipboard (const finalcut::FWidget*, const FDataPtr);
void cb_clearInput (const finalcut::FWidget*, const FDataPtr);
void cb_switchTheme (const finalcut::FWidget*, const FDataPtr) const;
void cb_input2buttonText (finalcut::FWidget*, FDataPtr) const;
void cb_setTitlebar (finalcut::FWidget*, const FDataPtr);
void cb_showProgressBar (const finalcut::FWidget*, const FDataPtr);
void cb_updateNumber (finalcut::FWidget*, FDataPtr) const;
void cb_activateButton (finalcut::FWidget*, FDataPtr) const;
void cb_view (const finalcut::FWidget*, FDataPtr);
void cb_setInput (finalcut::FWidget*, FDataPtr) const;
void cb_noFunctionMsg (finalcut::FButton&);
void cb_about();
void cb_terminfo();
void cb_drives();
void cb_cutClipboard();
void cb_copyClipboard();
void cb_pasteClipboard();
void cb_clearInput();
void cb_switchTheme (const finalcut::FCheckMenuItem*) const;
void cb_input2buttonText ( finalcut::FButton&
, const finalcut::FLineEdit& ) const;
void cb_setTitlebar (finalcut::FLineEdit&);
void cb_showProgressBar();
void cb_updateNumber (finalcut::FListBox&, finalcut::FLabel&) const;
void cb_activateButton ( finalcut::FRadioButton&
, finalcut::FButton& ) const;
void cb_view (finalcut::FMenuItem*);
void cb_setInput (finalcut::FListBox&, finalcut::FLineEdit&) const;
// Data members
bool initialized{false};
@ -448,35 +450,38 @@ void MyDialog::initFileMenuCallbacks()
Open.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_view)
this, &MyDialog::cb_view,
nullptr
);
Quit.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
// System files submenu
File1.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_view),
static_cast<FDataPtr>(&File1)
this, &MyDialog::cb_view,
&File1
);
File2.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_view),
static_cast<FDataPtr>(&File2)
this, &MyDialog::cb_view,
&File2
);
File3.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_view),
static_cast<FDataPtr>(&File3)
this, &MyDialog::cb_view,
&File3
);
}
@ -487,25 +492,25 @@ void MyDialog::initEditMenuCallbacks()
Cut.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_cutClipboard)
this, &MyDialog::cb_cutClipboard
);
Copy.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_copyClipboard)
this, &MyDialog::cb_copyClipboard
);
Paste.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_pasteClipboard)
this, &MyDialog::cb_pasteClipboard
);
Clear.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_clearInput)
this, &MyDialog::cb_clearInput
);
}
@ -516,19 +521,20 @@ void MyDialog::initViewMenuCallbacks()
Env.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_terminfo)
this, &MyDialog::cb_terminfo
);
Drive.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_drives)
this, &MyDialog::cb_drives
);
Theme.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_switchTheme)
this, &MyDialog::cb_switchTheme,
&Theme
);
}
@ -538,7 +544,7 @@ void MyDialog::initHelpMenuCallback()
Help.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_about)
this, &MyDialog::cb_about
);
}
@ -550,19 +556,22 @@ void MyDialog::initStatusBarCallbacks()
key_F1.addCallback
(
"activate",
F_METHOD_CALLBACK (this, &MyDialog::cb_about)
this, &MyDialog::cb_about
);
key_F2.addCallback
(
"activate",
F_METHOD_CALLBACK (this, &MyDialog::cb_view)
this, &MyDialog::cb_view,
nullptr
);
key_F3.addCallback
(
"activate",
F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
}
@ -627,19 +636,22 @@ void MyDialog::initFlatButtons()
MyButton1.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
this, &MyDialog::cb_noFunctionMsg,
std::ref(MyButton1)
);
MyButton2.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
this, &MyDialog::cb_noFunctionMsg,
std::ref(MyButton2)
);
MyButton3.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
this, &MyDialog::cb_noFunctionMsg,
std::ref(MyButton3)
);
}
@ -693,20 +705,22 @@ void MyDialog::initButtons()
MyButton4.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_input2buttonText),
static_cast<FDataPtr>(&myLineEdit)
this, &MyDialog::cb_input2buttonText,
std::ref(MyButton4), std::cref(myLineEdit)
);
MyButton5.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_showProgressBar)
this, &MyDialog::cb_showProgressBar
);
MyButton6.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
}
@ -739,28 +753,29 @@ void MyDialog::initWidgetsCallbacks()
myLineEdit.addCallback
(
"activate", // e.g. on <Enter>
F_METHOD_CALLBACK (this, &MyDialog::cb_setTitlebar)
this, &MyDialog::cb_setTitlebar,
std::ref(myLineEdit)
);
radio1.addCallback
(
"toggled",
F_METHOD_CALLBACK (this, &MyDialog::cb_activateButton),
static_cast<FDataPtr>(&MyButton5)
this, &MyDialog::cb_activateButton,
std::ref(radio1), std::ref(MyButton5)
);
myList.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &MyDialog::cb_setInput),
static_cast<FDataPtr>(&myLineEdit)
this, &MyDialog::cb_setInput,
std::ref(myList), std::ref(myLineEdit)
);
myList.addCallback
(
"row-selected",
F_METHOD_CALLBACK (this, &MyDialog::cb_updateNumber),
static_cast<FDataPtr>(&tagged_count)
this, &MyDialog::cb_updateNumber,
std::ref(myList), std::ref(tagged_count)
);
}
@ -789,9 +804,8 @@ void MyDialog::onClose (finalcut::FCloseEvent* ev)
}
//----------------------------------------------------------------------
void MyDialog::cb_noFunctionMsg (finalcut::FWidget* widget, const FDataPtr)
void MyDialog::cb_noFunctionMsg (finalcut::FButton& button)
{
auto& button = *(static_cast<finalcut::FButton*>(widget));
auto text = button.getText();
text = text.replace('&', "");
finalcut::FMessageBox::error ( this
@ -800,7 +814,7 @@ void MyDialog::cb_noFunctionMsg (finalcut::FWidget* widget, const FDataPtr)
}
//----------------------------------------------------------------------
void MyDialog::cb_about (const finalcut::FWidget*, const FDataPtr)
void MyDialog::cb_about()
{
constexpr char libver[] = F_VERSION;
const finalcut::FString line(2, fc::BoxDrawingsHorizontal);
@ -815,7 +829,7 @@ void MyDialog::cb_about (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void MyDialog::cb_terminfo (const finalcut::FWidget*, const FDataPtr)
void MyDialog::cb_terminfo()
{
const auto x = getDesktopWidth();
const auto y = getDesktopHeight();
@ -836,7 +850,7 @@ void MyDialog::cb_terminfo (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void MyDialog::cb_drives (const finalcut::FWidget*, const FDataPtr)
void MyDialog::cb_drives()
{
finalcut::FMessageBox info2 \
(
@ -887,7 +901,7 @@ void MyDialog::cb_drives (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void MyDialog::cb_cutClipboard (const finalcut::FWidget*, const FDataPtr)
void MyDialog::cb_cutClipboard()
{
clipboard = myLineEdit.getText();
myLineEdit.clear();
@ -895,20 +909,20 @@ void MyDialog::cb_cutClipboard (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void MyDialog::cb_copyClipboard (const finalcut::FWidget*, const FDataPtr)
void MyDialog::cb_copyClipboard()
{
clipboard = myLineEdit.getText();
}
//----------------------------------------------------------------------
void MyDialog::cb_pasteClipboard (const finalcut::FWidget*, const FDataPtr)
void MyDialog::cb_pasteClipboard()
{
myLineEdit = clipboard;
myLineEdit.redraw();
}
//----------------------------------------------------------------------
void MyDialog::cb_clearInput (const finalcut::FWidget*, const FDataPtr)
void MyDialog::cb_clearInput()
{
clipboard.clear();
myLineEdit.clear();
@ -916,11 +930,9 @@ void MyDialog::cb_clearInput (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void MyDialog::cb_switchTheme (const finalcut::FWidget* widget, const FDataPtr) const
void MyDialog::cb_switchTheme (const finalcut::FCheckMenuItem* check_menu) const
{
const auto& check_menu = *(static_cast<const finalcut::FCheckMenuItem*>(widget));
if ( check_menu.isChecked() )
if ( check_menu->isChecked() )
finalcut::FApplication::setDarkTheme();
else
finalcut::FApplication::setDefaultTheme();
@ -931,18 +943,16 @@ void MyDialog::cb_switchTheme (const finalcut::FWidget* widget, const FDataPtr)
}
//----------------------------------------------------------------------
void MyDialog::cb_input2buttonText (finalcut::FWidget* widget, FDataPtr data) const
void MyDialog::cb_input2buttonText ( finalcut::FButton& button
, const finalcut::FLineEdit& lineedit ) const
{
auto& button = *(static_cast<finalcut::FButton*>(widget));
const auto& lineedit = *(static_cast<finalcut::FLineEdit*>(data));
button.setText(lineedit.getText());
button.redraw();
}
//----------------------------------------------------------------------
void MyDialog::cb_setTitlebar (finalcut::FWidget* widget, const FDataPtr)
void MyDialog::cb_setTitlebar (finalcut::FLineEdit& lineedit)
{
const auto& lineedit = *(static_cast<finalcut::FLineEdit*>(widget));
finalcut::FString title{};
lineedit >> title;
finalcut::FTerm::setTermTitle (title);
@ -951,17 +961,16 @@ void MyDialog::cb_setTitlebar (finalcut::FWidget* widget, const FDataPtr)
}
//----------------------------------------------------------------------
void MyDialog::cb_showProgressBar (const finalcut::FWidget*, const FDataPtr)
void MyDialog::cb_showProgressBar()
{
auto p_dgl = new ProgressDialog(this);
p_dgl->show();
}
//----------------------------------------------------------------------
void MyDialog::cb_updateNumber (finalcut::FWidget* widget, FDataPtr data) const
void MyDialog::cb_updateNumber ( finalcut::FListBox& list
, finalcut::FLabel& num) const
{
const auto& list = *(static_cast<finalcut::FListBox*>(widget));
auto& num = *(static_cast<finalcut::FLabel*>(data));
const auto count = list.getCount();
int select_num = 0;
@ -975,11 +984,9 @@ void MyDialog::cb_updateNumber (finalcut::FWidget* widget, FDataPtr data) const
}
//----------------------------------------------------------------------
void MyDialog::cb_activateButton (finalcut::FWidget* widget, FDataPtr data) const
void MyDialog::cb_activateButton ( finalcut::FRadioButton& rb
, finalcut::FButton& button) const
{
const auto& rb = *(static_cast<finalcut::FRadioButton*>(widget));
auto& button = *(static_cast<finalcut::FButton*>(data));
if ( rb.isChecked() )
button.setEnable();
else
@ -989,10 +996,9 @@ void MyDialog::cb_activateButton (finalcut::FWidget* widget, FDataPtr data) cons
}
//----------------------------------------------------------------------
void MyDialog::cb_view (const finalcut::FWidget*, FDataPtr data)
void MyDialog::cb_view (finalcut::FMenuItem* item)
{
finalcut::FString file{};
const auto& item = static_cast<finalcut::FMenuItem*>(data);
if ( item && ! item->getText().isEmpty() )
file = item->getText();
@ -1026,11 +1032,10 @@ void MyDialog::cb_view (const finalcut::FWidget*, FDataPtr data)
}
//----------------------------------------------------------------------
void MyDialog::cb_setInput (finalcut::FWidget* widget, FDataPtr data) const
void MyDialog::cb_setInput ( finalcut::FListBox& listbox
, finalcut::FLineEdit& lineedit) const
{
auto& ListBox = *(static_cast<finalcut::FListBox*>(widget));
auto& lineedit = *(static_cast<finalcut::FLineEdit*>(data));
lineedit = ListBox.getItem(ListBox.currentItem()).getText();
lineedit = listbox.getItem(listbox.currentItem()).getText();
lineedit.redraw();
}

View File

@ -54,8 +54,8 @@ class Watch final : public finalcut::FDialog
void onClose (finalcut::FCloseEvent*) override;
// Callback methods
void cb_clock (const finalcut::FWidget*, const FDataPtr);
void cb_seconds (const finalcut::FWidget*, const FDataPtr);
void cb_clock();
void cb_seconds();
protected:
// Method
@ -99,21 +99,23 @@ Watch::Watch (FWidget* parent)
clock_sw.addCallback
(
"toggled",
F_METHOD_CALLBACK (this, &Watch::cb_clock)
this, &Watch::cb_clock
);
// Connect switch signal "toggled" with a callback member function
seconds_sw.addCallback
(
"toggled",
F_METHOD_CALLBACK (this, &Watch::cb_seconds)
this, &Watch::cb_seconds
);
// Connect button signal "clicked" with a callback member function
quit_btn.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &finalcut::FApplication::cb_exitApp)
finalcut::getFApplication(),
&finalcut::FApplication::cb_exitApp,
this
);
}
@ -152,7 +154,7 @@ void Watch::onClose (finalcut::FCloseEvent* ev)
}
//----------------------------------------------------------------------
void Watch::cb_clock (const finalcut::FWidget*, const FDataPtr)
void Watch::cb_clock()
{
if ( clock_sw.isChecked() )
{
@ -168,7 +170,7 @@ void Watch::cb_clock (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void Watch::cb_seconds (const finalcut::FWidget*, const FDataPtr)
void Watch::cb_seconds()
{
if ( seconds_sw.isChecked() )
sec = true;

View File

@ -176,10 +176,6 @@ class Window final : public finalcut::FDialog
Window& operator = (const Window&) = delete;
private:
// Typedefs
typedef void (Window::*WindowCallback)(const finalcut::FWidget*, const FDataPtr);
typedef void (finalcut::FApplication::*FAppCallback)(const finalcut::FWidget*, const FDataPtr);
struct win_data
{
// Constructor
@ -201,8 +197,9 @@ class Window final : public finalcut::FDialog
void configureDialogButtons();
void activateWindow (finalcut::FDialog*);
void adjustSize() override;
template<typename CallbackT>
void addClickedCallback (finalcut::FWidget*, CallbackT);
template<typename InstanceT, typename CallbackT, typename... Args>
void addClickedCallback ( finalcut::FWidget*
, InstanceT&&, CallbackT&&, Args&&... );
template <typename IteratorT>
finalcut::FDialog* getNext (IteratorT);
template <typename IteratorT>
@ -212,11 +209,11 @@ class Window final : public finalcut::FDialog
void onClose (finalcut::FCloseEvent*) override;
// Callback methods
void cb_createWindows (const finalcut::FWidget*, const FDataPtr);
void cb_closeWindows (const finalcut::FWidget*, const FDataPtr);
void cb_next (const finalcut::FWidget*, const FDataPtr);
void cb_previous (const finalcut::FWidget*, const FDataPtr);
void cb_destroyWindow (const finalcut::FWidget*, FDataPtr) const;
void cb_createWindows();
void cb_closeWindows();
void cb_next();
void cb_previous();
void cb_destroyWindow (win_data*) const;
// Data members
std::vector<win_data*> windows{};
@ -277,7 +274,7 @@ Window::~Window()
// Remove all callbacks before Window::cb_destroyWindow() will be called
if ( win_dat->is_open && win_dat->dgl )
win_dat->dgl->delAllCallbacks();
win_dat->dgl->delCallback();
delete win_dat;
iter = windows.erase(iter);
@ -300,11 +297,14 @@ void Window::configureFileMenuItems()
Quit.setStatusbarMessage ("Exit the program");
// Add menu item callback
addClickedCallback (&New, &Window::cb_createWindows);
addClickedCallback (&Close, &Window::cb_closeWindows);
addClickedCallback (&Next, &Window::cb_next);
addClickedCallback (&Previous, &Window::cb_previous);
addClickedCallback (&Quit, &finalcut::FApplication::cb_exitApp);
addClickedCallback (&New, this, &Window::cb_createWindows);
addClickedCallback (&Close, this, &Window::cb_closeWindows);
addClickedCallback (&Next, this, &Window::cb_next);
addClickedCallback (&Previous, this, &Window::cb_previous);
addClickedCallback ( &Quit
, finalcut::getFApplication()
, &finalcut::FApplication::cb_exitApp
, this );
}
//----------------------------------------------------------------------
@ -319,9 +319,12 @@ void Window::configureDialogButtons()
QuitButton.setText (L"&Quit");
// Add button callback
addClickedCallback (&CreateButton, &Window::cb_createWindows);
addClickedCallback (&CloseButton, &Window::cb_closeWindows);
addClickedCallback (&QuitButton, &finalcut::FApplication::cb_exitApp);
addClickedCallback (&CreateButton, this, &Window::cb_createWindows);
addClickedCallback (&CloseButton, this, &Window::cb_closeWindows);
addClickedCallback ( &QuitButton
, finalcut::getFApplication()
, &finalcut::FApplication::cb_exitApp
, this );
}
//----------------------------------------------------------------------
@ -373,17 +376,18 @@ void Window::adjustSize()
}
//----------------------------------------------------------------------
template<typename CallbackT>
template<typename InstanceT, typename CallbackT, typename... Args>
void Window::addClickedCallback ( finalcut::FWidget* widget
, CallbackT call )
, InstanceT&& instance
, CallbackT&& callback
, Args&&... args )
{
FMemberCallback callback
= reinterpret_cast<FMemberCallback>(call);
widget->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, callback)
std::bind ( std::forward<CallbackT>(callback)
, std::forward<InstanceT>(instance)
, std::forward<Args>(args)... )
);
}
@ -439,7 +443,7 @@ void Window::onClose (finalcut::FCloseEvent* ev)
}
//----------------------------------------------------------------------
void Window::cb_createWindows (const finalcut::FWidget*, const FDataPtr)
void Window::cb_createWindows()
{
const auto& first = windows.begin();
auto iter = first;
@ -468,8 +472,8 @@ void Window::cb_createWindows (const finalcut::FWidget*, const FDataPtr)
win->addCallback
(
"destroy",
F_METHOD_CALLBACK (this, &Window::cb_destroyWindow),
static_cast<FDataPtr>(win_dat)
this, &Window::cb_destroyWindow,
win_dat
);
}
@ -480,7 +484,7 @@ void Window::cb_createWindows (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void Window::cb_closeWindows (const finalcut::FWidget*, const FDataPtr)
void Window::cb_closeWindows()
{
if ( ! getDialogList() || getDialogList()->empty() )
return;
@ -500,7 +504,7 @@ void Window::cb_closeWindows (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void Window::cb_next (const finalcut::FWidget*, const FDataPtr)
void Window::cb_next()
{
if ( ! getDialogList() || getDialogList()->empty() )
return;
@ -520,7 +524,7 @@ void Window::cb_next (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void Window::cb_previous (const finalcut::FWidget*, const FDataPtr)
void Window::cb_previous()
{
if ( ! getDialogList() || getDialogList()->empty() )
return;
@ -542,10 +546,8 @@ void Window::cb_previous (const finalcut::FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void Window::cb_destroyWindow (const finalcut::FWidget*, FDataPtr data) const
void Window::cb_destroyWindow (win_data* win_dat) const
{
auto win_dat = static_cast<win_data*>(data);
if ( win_dat )
{
win_dat->is_open = false;

View File

@ -19,6 +19,7 @@ libfinal_la_SOURCES = \
flineedit.cpp \
fbutton.cpp \
fbuttongroup.cpp \
fcallback.cpp \
ftogglebutton.cpp \
fradiobutton.cpp \
fcheckbox.cpp \
@ -85,6 +86,7 @@ finalcutinclude_HEADERS = \
include/final/fapplication.h \
include/final/fbutton.h \
include/final/fbuttongroup.h \
include/final/fcallback.h \
include/final/fcheckbox.h \
include/final/fcolorpair.h \
include/final/fdata.h \

View File

@ -12,6 +12,7 @@ INCLUDE_HEADERS = \
fapplication.h \
fbuttongroup.h \
fbutton.h \
fcallback.h \
fcolorpair.h \
fstyle.h \
ftogglebutton.h \
@ -91,6 +92,7 @@ OBJS = \
fpoint.o \
fsize.o \
frect.o \
fcallback.o \
fscrollbar.o \
fprogressbar.o \
flineedit.o \

View File

@ -12,6 +12,7 @@ INCLUDE_HEADERS = \
fapplication.h \
fbuttongroup.h \
fbutton.h \
fcallback.h \
fcolorpair.h \
fstyle.h \
ftogglebutton.h \
@ -91,6 +92,7 @@ OBJS = \
fpoint.o \
fsize.o \
frect.o \
fcallback.o \
fscrollbar.o \
fprogressbar.o \
flineedit.o \

View File

@ -240,11 +240,11 @@ void FButtonGroup::insert (FToggleButton* button)
button->addCallback
(
"toggled",
F_METHOD_CALLBACK (this, &FButtonGroup::cb_buttonToggled)
this, &FButtonGroup::cb_buttonToggled,
button
);
}
//----------------------------------------------------------------------
void FButtonGroup::remove (FToggleButton* button)
{
if ( ! button || buttonlist.empty() )
@ -542,10 +542,8 @@ void FButtonGroup::directFocus()
}
//----------------------------------------------------------------------
void FButtonGroup::cb_buttonToggled (FWidget* widget, const FDataPtr) const
void FButtonGroup::cb_buttonToggled (FToggleButton* button) const
{
const auto& button = static_cast<FToggleButton*>(widget);
if ( (button && ! button->isChecked()) || buttonlist.empty() )
return;

42
src/fcallback.cpp Normal file
View File

@ -0,0 +1,42 @@
/***********************************************************************
* fcallback.cpp - Implements the callback functionality *
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2020 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 *
* published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* FINAL CUT is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include "final/fcallback.h"
namespace finalcut
{
//----------------------------------------------------------------------
// class FCallback
//----------------------------------------------------------------------
// constructors and destructor
//----------------------------------------------------------------------
FCallback::FCallback()
{ }
//----------------------------------------------------------------------
FCallback::~FCallback() // destructor
{ }
} // namespace finalcut

View File

@ -508,19 +508,19 @@ void FComboBox::initCallbacks()
input_field.addCallback
(
"mouse-press",
F_METHOD_CALLBACK (this, &FComboBox::cb_inputFieldSwitch)
this, &FComboBox::cb_inputFieldSwitch
);
input_field.addCallback
(
"mouse-move",
F_METHOD_CALLBACK (this, &FComboBox::cb_inputFieldHandOver)
this, &FComboBox::cb_inputFieldHandOver
);
list_window.list.addCallback
(
"row-changed",
F_METHOD_CALLBACK (this, &FComboBox::cb_setInputField)
this, &FComboBox::cb_setInputField
);
for (const auto& signal : {"row-selected", "clicked"})
@ -528,7 +528,7 @@ void FComboBox::initCallbacks()
list_window.list.addCallback
(
signal,
F_METHOD_CALLBACK (this, &FComboBox::cb_closeComboBox)
this, &FComboBox::cb_closeComboBox
);
}
}
@ -628,7 +628,7 @@ void FComboBox::processChanged()
}
//----------------------------------------------------------------------
void FComboBox::cb_setInputField (const FWidget*, const FDataPtr)
void FComboBox::cb_setInputField()
{
auto& list = list_window.list;
const std::size_t index = list.currentItem();
@ -638,14 +638,14 @@ void FComboBox::cb_setInputField (const FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void FComboBox::cb_closeComboBox (const FWidget*, const FDataPtr)
void FComboBox::cb_closeComboBox()
{
hideDropDown();
processClick();
}
//----------------------------------------------------------------------
void FComboBox::cb_inputFieldSwitch (const FWidget*, const FDataPtr)
void FComboBox::cb_inputFieldSwitch()
{
const auto& mouse = FTerm::getFMouseControl();
@ -677,7 +677,7 @@ void FComboBox::cb_inputFieldSwitch (const FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void FComboBox::cb_inputFieldHandOver (const FWidget*, const FDataPtr)
void FComboBox::cb_inputFieldHandOver()
{
const auto& mouse = FTerm::getFMouseControl();

View File

@ -873,7 +873,8 @@ void FDialog::initMoveSizeMenuItem (FMenu* menu)
move_size_item->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FDialog::cb_move)
this,
&FDialog::cb_move
);
}
@ -896,7 +897,8 @@ void FDialog::initZoomMenuItem (FMenu* menu)
zoom_item->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FDialog::cb_zoom)
this,
&FDialog::cb_zoom
);
}
@ -918,7 +920,8 @@ void FDialog::initCloseMenuItem (FMenu* menu)
close_item->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FDialog::cb_close)
this,
&FDialog::cb_close
);
}
@ -1632,7 +1635,7 @@ void FDialog::delDialog (const FWidget* obj)
}
//----------------------------------------------------------------------
void FDialog::cb_move (const FWidget*, const FDataPtr)
void FDialog::cb_move()
{
if ( isZoomed() )
return;
@ -1683,7 +1686,7 @@ void FDialog::cb_move (const FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void FDialog::cb_zoom (const FWidget*, const FDataPtr)
void FDialog::cb_zoom()
{
dialog_menu->unselectItem();
dialog_menu->hide();
@ -1694,7 +1697,7 @@ void FDialog::cb_zoom (const FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void FDialog::cb_close (const FWidget*, const FDataPtr)
void FDialog::cb_close()
{
dialog_menu->unselectItem();
dialog_menu->hide();

View File

@ -380,37 +380,37 @@ void FFileDialog::initCallbacks()
filename.addCallback
(
"activate",
F_METHOD_CALLBACK (this, &FFileDialog::cb_processActivate)
this, &FFileDialog::cb_processActivate
);
filebrowser.addCallback
(
"row-changed",
F_METHOD_CALLBACK (this, &FFileDialog::cb_processRowChanged)
this, &FFileDialog::cb_processRowChanged
);
filebrowser.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FFileDialog::cb_processClicked)
this, &FFileDialog::cb_processClicked
);
hidden_check.addCallback
(
"toggled",
F_METHOD_CALLBACK (this, &FFileDialog::cb_processShowHidden)
this, &FFileDialog::cb_processShowHidden
);
cancel_btn.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FFileDialog::cb_processCancel)
this, &FFileDialog::cb_processCancel
);
open_btn.addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FFileDialog::cb_processOpen)
this, &FFileDialog::cb_processOpen
);
}
@ -754,7 +754,7 @@ const FString FFileDialog::getHomeDir()
}
//----------------------------------------------------------------------
void FFileDialog::cb_processActivate (const FWidget*, const FDataPtr)
void FFileDialog::cb_processActivate()
{
if ( filename.getText().includes('*')
|| filename.getText().includes('?') )
@ -803,7 +803,7 @@ void FFileDialog::cb_processActivate (const FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void FFileDialog::cb_processRowChanged (const FWidget*, const FDataPtr)
void FFileDialog::cb_processRowChanged()
{
const std::size_t n = filebrowser.currentItem();
@ -821,7 +821,7 @@ void FFileDialog::cb_processRowChanged (const FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void FFileDialog::cb_processClicked (const FWidget*, const FDataPtr)
void FFileDialog::cb_processClicked()
{
const uLong n = uLong(filebrowser.currentItem() - 1);
@ -832,19 +832,19 @@ void FFileDialog::cb_processClicked (const FWidget*, const FDataPtr)
}
//----------------------------------------------------------------------
void FFileDialog::cb_processCancel (const FWidget*, const FDataPtr)
void FFileDialog::cb_processCancel()
{
done (FDialog::Reject);
}
//----------------------------------------------------------------------
void FFileDialog::cb_processOpen (const FWidget*, const FDataPtr)
void FFileDialog::cb_processOpen()
{
done (FDialog::Accept);
}
//----------------------------------------------------------------------
void FFileDialog::cb_processShowHidden (const FWidget*, const FDataPtr)
void FFileDialog::cb_processShowHidden()
{
setShowHiddenFiles(! show_hidden);
}

View File

@ -100,7 +100,7 @@ void FLabel::setAccelWidget (FWidget* widget)
accel_widget->addCallback
(
"destroy",
F_METHOD_CALLBACK (this, &FLabel::cb_accelWidgetDestroyed)
this, &FLabel::cb_accelWidgetDestroyed
);
}
@ -244,7 +244,7 @@ void FLabel::onAccel (FAccelEvent* ev)
}
//----------------------------------------------------------------------
void FLabel::cb_accelWidgetDestroyed (const FWidget*, const FDataPtr)
void FLabel::cb_accelWidgetDestroyed()
{
accel_widget = nullptr;
delAccelerator();
@ -256,7 +256,7 @@ void FLabel::cb_accelWidgetDestroyed (const FWidget*, const FDataPtr)
void FLabel::init()
{
unsetFocusable();
useParentWidgetColor();
resetColors();
}
//----------------------------------------------------------------------
@ -300,8 +300,6 @@ void FLabel::draw()
if ( text.isEmpty() )
return;
if ( FTerm::isMonochron() )
{
setReverse(true);

View File

@ -327,26 +327,21 @@ void FMenu::onMouseMove (FMouseEvent* ev)
}
//----------------------------------------------------------------------
void FMenu::cb_menuitemEnabled (const FWidget*, const FDataPtr)
void FMenu::cb_menuitemEnabled()
{
setEnable();
}
//----------------------------------------------------------------------
void FMenu::cb_menuitemDisabled (const FWidget*, const FDataPtr)
void FMenu::cb_menuitemDisabled()
{
setDisable();
}
//----------------------------------------------------------------------
void FMenu::cb_menuitemToggled (FWidget* widget, const FDataPtr) const
void FMenu::cb_menuitemToggled (FMenuItem* m_item) const
{
const auto& m_item = static_cast<FMenuItem*>(widget);
if ( ! has_checkable_items )
return;
if ( ! m_item->isChecked() )
if ( ! (has_checkable_items && m_item && m_item->isChecked()) )
return;
auto list = getItemList();
@ -497,13 +492,13 @@ void FMenu::initCallbacks()
menuitem.addCallback
(
"enable",
F_METHOD_CALLBACK (this, &FMenu::cb_menuitemEnabled)
this, &FMenu::cb_menuitemEnabled
);
menuitem.addCallback
(
"disable",
F_METHOD_CALLBACK (this, &FMenu::cb_menuitemEnabled)
this, &FMenu::cb_menuitemDisabled
);
}

View File

@ -228,16 +228,14 @@ void FMenuBar::onAccel (FAccelEvent* ev)
}
//----------------------------------------------------------------------
void FMenuBar::cb_itemDeactivated (FWidget* widget, const FDataPtr) const
void FMenuBar::cb_itemDeactivated (FMenuItem* menuitem) const
{
auto menuitem = static_cast<FMenuItem*>(widget);
if ( ! menuitem->hasMenu() )
return;
if ( menuitem->hasMenu() )
{
auto menu = menuitem->getMenu();
menu->hide();
menu->hideSubMenus();
}
}

View File

@ -546,7 +546,8 @@ void FMenuItem::init()
addCallback // for this element
(
"deactivate",
F_METHOD_CALLBACK (menubar_ptr, &FMenuBar::cb_itemDeactivated)
std::move(menubar_ptr), &FMenuBar::cb_itemDeactivated,
this
);
}
else if ( isMenu(parent) ) // Parent is menu
@ -628,14 +629,15 @@ void FMenuItem::createDialogList (FMenu* winmenu) const
win_item->addCallback
(
"clicked",
F_METHOD_CALLBACK (win_item, &FMenuItem::cb_switchToDialog),
static_cast<FDataPtr>(win)
std::move(win_item), &FMenuItem::cb_switchToDialog,
win
);
win->addCallback
(
"destroy",
F_METHOD_CALLBACK (win_item, &FMenuItem::cb_destroyDialog)
std::move(win_item), &FMenuItem::cb_destroyDialog,
win
);
win_item->associated_window = win;
@ -695,28 +697,25 @@ void FMenuItem::passMouseEvent ( T widget, const FMouseEvent* ev
}
//----------------------------------------------------------------------
void FMenuItem::cb_switchToDialog (const FWidget*, FDataPtr data) const
void FMenuItem::cb_switchToDialog (FDialog* win) const
{
auto win = static_cast<FDialog*>(data);
if ( ! win )
return;
if ( win )
{
auto focus = getFocusWidget();
FAccelEvent a_ev (fc::Accelerator_Event, focus);
FApplication::sendEvent (win, &a_ev);
}
}
//----------------------------------------------------------------------
void FMenuItem::cb_destroyDialog (FWidget* widget, const FDataPtr)
void FMenuItem::cb_destroyDialog (FDialog* win)
{
auto win = static_cast<FDialog*>(widget);
const auto& fapp = FApplication::getApplicationObject();
if ( win && fapp )
{
delAccelerator(win);
delCallback(win);
delCallback(std::move(win));
associated_window = nullptr;
}
}

View File

@ -193,10 +193,9 @@ void FMessageBox::adjustSize()
}
//----------------------------------------------------------------------
void FMessageBox::cb_processClick (const FWidget*, FDataPtr data)
void FMessageBox::cb_processClick (int reply)
{
const int reply = *(static_cast<int*>(data));
done (reply);
done(reply);
}
@ -281,8 +280,8 @@ inline void FMessageBox::initCallbacks()
button[0]->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FMessageBox::cb_processClick),
static_cast<FDataPtr>(&button_digit[0])
this, &FMessageBox::cb_processClick,
button_digit[0]
);
}
@ -291,8 +290,8 @@ inline void FMessageBox::initCallbacks()
button[1]->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FMessageBox::cb_processClick),
static_cast<FDataPtr>(&button_digit[1])
this, &FMessageBox::cb_processClick,
button_digit[1]
);
}
@ -301,8 +300,8 @@ inline void FMessageBox::initCallbacks()
button[2]->addCallback
(
"clicked",
F_METHOD_CALLBACK (this, &FMessageBox::cb_processClick),
static_cast<FDataPtr>(&button_digit[2])
this, &FMessageBox::cb_processClick,
button_digit[2]
);
}
}

View File

@ -70,7 +70,8 @@ void FRadioMenuItem::init()
addCallback // for this element
(
"toggled",
F_METHOD_CALLBACK (menu_ptr, &FMenu::cb_menuitemToggled)
std::move(menu_ptr), &FMenu::cb_menuitemToggled,
this
);
}
}

View File

@ -319,12 +319,13 @@ void FSpinBox::init()
input_field.addCallback
(
"activate",
F_METHOD_CALLBACK (this, &FSpinBox::cb_inputFieldActivate)
this, &FSpinBox::cb_inputFieldActivate
);
input_field.addCallback
(
"changed",
F_METHOD_CALLBACK (this, &FSpinBox::cb_inputFieldChange)
this, &FSpinBox::cb_inputFieldChange,
std::cref(input_field)
);
}
@ -428,23 +429,21 @@ void FSpinBox::forceFocus()
}
//----------------------------------------------------------------------
void FSpinBox::cb_inputFieldActivate (const finalcut::FWidget*, const FDataPtr)
void FSpinBox::cb_inputFieldActivate()
{
processActivate();
}
//----------------------------------------------------------------------
void FSpinBox::cb_inputFieldChange (finalcut::FWidget* w, const FDataPtr)
void FSpinBox::cb_inputFieldChange (const FLineEdit& lineedit)
{
const auto& lineedit = static_cast<FLineEdit*>(w);
if ( lineedit->getText().isEmpty() )
if ( lineedit.getText().isEmpty() )
value = 0;
else
{
std::wregex regex(L"[-]?[[:xdigit:]]+");
std::wsmatch match;
std::wstring text = lineedit->getText().wc_str();
std::wstring text = lineedit.getText().wc_str();
if ( std::regex_search(text, match, regex) )
{

View File

@ -273,7 +273,9 @@ void FStatusBar::insert (FStatusKey* skey)
skey->addCallback
(
"activate",
F_METHOD_CALLBACK (this, &FStatusBar::cb_statuskey_activated)
this,
&FStatusBar::cb_statuskey_activated,
skey
);
}
@ -486,11 +488,13 @@ void FStatusBar::onMouseMove (FMouseEvent* ev)
}
//----------------------------------------------------------------------
void FStatusBar::cb_statuskey_activated (FWidget* widget, const FDataPtr)
void FStatusBar::cb_statuskey_activated (FStatusKey* statuskey)
{
if ( ! statuskey )
return;
if ( ! key_list.empty() )
{
const auto& statuskey = static_cast<FStatusKey*>(widget);
auto iter = key_list.begin();
const auto& last = key_list.end();

View File

@ -2018,6 +2018,8 @@ void FVTerm::finish()
if ( fterm )
delete fterm;
init_object = nullptr;
}
//----------------------------------------------------------------------
@ -2359,7 +2361,7 @@ bool FVTerm::skipUnchangedCharacters (uInt& x, uInt xmax, uInt y) const
//----------------------------------------------------------------------
void FVTerm::printRange ( uInt xmin, uInt xmax, uInt y
, bool draw_trailing_ws )
, bool draw_trailing_ws ) const
{
for (uInt x = xmin; x <= xmax; x++)
{

View File

@ -101,7 +101,7 @@ FWidget::FWidget (FWidget* parent)
FWidget::~FWidget() // destructor
{
processDestroy();
delAllCallbacks();
delCallback();
auto app_object = FApplication::getApplicationObject();
app_object->removeQueuedEvent(this);
@ -832,94 +832,6 @@ bool FWidget::close()
return false;
}
//----------------------------------------------------------------------
void FWidget::addCallback ( const FString& cb_signal
, const FCallback& cb_function
, FDataPtr data )
{
// Add a (normal) function pointer as callback
FCallbackData obj{ cb_signal, nullptr, cb_function, data };
callback_objects.push_back(obj);
}
//----------------------------------------------------------------------
void FWidget::addCallback ( const FString& cb_signal
, FWidget* cb_instance
, const FCallback& cb_function
, FDataPtr data )
{
// Add a member function pointer as callback
FCallbackData obj{ cb_signal, cb_instance, cb_function, data };
callback_objects.push_back(obj);
}
//----------------------------------------------------------------------
void FWidget::delCallback (const FCallback& cb_function)
{
// Deletes entries with cb_function form the callback list
if ( callback_objects.empty() )
return;
auto iter = callback_objects.begin();
while ( iter != callback_objects.end() )
{
if ( getCallbackPtr(iter->cb_function) == getCallbackPtr(cb_function) )
iter = callback_objects.erase(iter);
else
++iter;
}
}
//----------------------------------------------------------------------
void FWidget::delCallback (const FWidget* cb_instance)
{
// Deletes entries with cb_instance from the callback list
if ( callback_objects.empty() )
return;
auto iter = callback_objects.begin();
while ( iter != callback_objects.end() )
{
if ( iter->cb_instance == cb_instance )
iter = callback_objects.erase(iter);
else
++iter;
}
}
//----------------------------------------------------------------------
void FWidget::delAllCallbacks()
{
// Delete all callbacks from this widget
callback_objects.clear(); // function pointer
}
//----------------------------------------------------------------------
void FWidget::emitCallback (const FString& emit_signal)
{
// Initiate callback for the given signal
if ( callback_objects.empty() )
return;
for (auto&& cback : callback_objects)
{
if ( cback.cb_signal == emit_signal )
{
// Calling the stored function pointer
auto callback = cback.cb_function;
callback (this, cback.data);
}
}
}
//----------------------------------------------------------------------
void FWidget::addAccelerator (FKey key, FWidget* obj)
{
@ -1956,17 +1868,6 @@ void FWidget::setWindowFocus (bool enable)
window->setWindowFocusWidget(this);
}
//----------------------------------------------------------------------
FWidget::FCallbackPtr FWidget::getCallbackPtr (const FCallback& cb_function)
{
auto ptr = cb_function.template target<FCallbackPtr>();
if ( ptr )
return *ptr;
else
return nullptr;
}
//----------------------------------------------------------------------
bool FWidget::changeFocus ( FWidget* follower, FWidget* parent
, fc::FocusTypes ft )

View File

@ -20,6 +20,7 @@
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include "final/fapplication.h"
#include "final/fcolorpair.h"
#include "final/fstyle.h"
#include "final/fwidget.h"
@ -51,6 +52,12 @@ bool isFocusPrevKey (const FKey key)
return false;
}
//----------------------------------------------------------------------
FApplication* getFApplication()
{
return FApplication::getApplicationObject();
}
//----------------------------------------------------------------------
FKey getHotkey (const FString& text)
{

View File

@ -139,7 +139,7 @@ class FApplication : public FWidget
static void closeConfirmationDialog (FWidget*, FCloseEvent*);
// Callback method
void cb_exitApp (const FWidget*, const FDataPtr);
void cb_exitApp (FWidget*);
protected:
virtual void processExternalUserEvent();
@ -214,6 +214,13 @@ class FApplication : public FWidget
static FWidget* keyboard_widget;
};
// non-member function forward declarations
// implemented in fwidget_functions.cpp
//----------------------------------------------------------------------
FApplication* getFApplication();
// FApplication inline functions
//----------------------------------------------------------------------
inline const FString FApplication::getClassName() const
@ -228,8 +235,8 @@ inline char** FApplication::getArgv() const
{ return app_argv; }
//----------------------------------------------------------------------
inline void FApplication::cb_exitApp (const FWidget*, const FDataPtr)
{ close(); }
inline void FApplication::cb_exitApp (FWidget* w)
{ w->close(); }
} // namespace finalcut

View File

@ -130,7 +130,7 @@ class FButtonGroup : public FScrollView
void directFocus();
// Callback method
void cb_buttonToggled (FWidget*, const FDataPtr) const;
void cb_buttonToggled (FToggleButton*) const;
// Data members
FString text{};

View File

@ -0,0 +1,449 @@
/***********************************************************************
* fcallback.h - Implements the callback functionality *
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2020 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 *
* published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* FINAL CUT is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
/* Standalone class
*
*
* 1 *
* FCallback - - - - FCallbackData
*
*/
#ifndef FCALLBACK_H
#define FCALLBACK_H
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
#error "Only <final/final.h> can be included directly."
#endif
#include "final/fstring.h"
#include "final/ftypes.h"
namespace finalcut
{
// class forward declaration
class FWidget;
//----------------------------------------------------------------------
// struct FCallbackData
//----------------------------------------------------------------------
struct FCallbackData
{
// Constructor
FCallbackData()
{ }
FCallbackData (const FString& s, FWidget* i, void* m, const FCall& c)
: cb_signal(s)
, cb_instance(i)
, cb_function_ptr(m)
, cb_function(c)
{ }
FCallbackData (const FCallbackData& c) // copy constructor
: cb_signal(c.cb_signal)
, cb_instance(c.cb_instance)
, cb_function_ptr(c.cb_function_ptr)
, cb_function(c.cb_function)
{ }
FCallbackData (FCallbackData&& c) noexcept // move constructor
: cb_signal(std::move(c.cb_signal))
, cb_instance(std::move(c.cb_instance))
, cb_function_ptr(std::move(c.cb_function_ptr))
, cb_function(std::move(c.cb_function))
{ }
// Destructor
~FCallbackData()
{ }
// Overloaded operators
FCallbackData& operator = (const FCallbackData& c)
{
cb_signal = c.cb_signal;
cb_instance = c.cb_instance;
cb_function_ptr = c.cb_function_ptr;
cb_function = c.cb_function;
return *this;
}
FCallbackData& operator = (FCallbackData&& c) noexcept
{
cb_signal = std::move(c.cb_signal);
cb_instance = std::move(c.cb_instance);
cb_function_ptr = std::move(c.cb_function_ptr);
cb_function = std::move(c.cb_function);
return *this;
}
// Data members
FString cb_signal{};
FWidget* cb_instance{};
void* cb_function_ptr{};
FCall cb_function{};
};
//----------------------------------------------------------------------
// class FCallback
//----------------------------------------------------------------------
class FCallback
{
public:
// Constructors
FCallback();
// Disable copy constructor
FCallback (const FCallback&) = delete;
// Destructor
~FCallback();
// Disable copy assignment operator (=)
FCallback& operator = (const FCallback&) = delete;
// Accessors
const FString getClassName() const
{
return "FCallback";
}
std::size_t getCallbackCount()
{
return callback_objects.size();
}
// Methods
template<typename Object
, typename Function
, typename std::enable_if< ! std::is_member_function_pointer<Object>::value
&& ! std::is_function<typename std::remove_pointer<Object>::type>::value
&& ! std::is_function<Object>::value
&& std::is_pointer<Object>::value
&& std::is_object<Object>::value
&& ! std::is_class<Object>::value
&& std::is_member_function_pointer<Function>::value
&& ! std::is_function<typename std::remove_pointer<Function>::type>::value
&& ! std::is_function<Function>::value
&& ! std::is_pointer<Function>::value
&& std::is_object<Function>::value
&& ! std::is_class<Function>::value
, std::nullptr_t >::type = nullptr
, typename... Args>
void addCallback ( const FString& cb_signal
, Object&& cb_instance
, Function&& cb_member
, Args&&... args)
{
// Add a member function pointer as callback
Object instance = cb_instance;
auto member = reinterpret_cast<void*>(std::addressof(cb_member));
auto fn = std::bind ( std::forward<Function>(cb_member)
, std::forward<Object>(cb_instance)
, std::forward<Args>(args)... );
FCallbackData obj{ cb_signal, instance, member, fn };
callback_objects.push_back(obj);
}
template<typename Object
, typename Function
, typename std::enable_if< ! std::is_member_function_pointer<Object>::value
&& ! std::is_function<typename std::remove_pointer<Object>::type>::value
&& ! std::is_function<Object>::value
&& std::is_pointer<Object>::value
&& std::is_object<Object>::value
&& ! std::is_class<Object>::value
&& ! std::is_member_function_pointer<Function>::value
&& ! std::is_function<typename std::remove_pointer<Function>::type>::value
&& ! std::is_function<Function>::value
&& ! std::is_pointer<Function>::value
&& std::is_object<Function>::value
&& std::is_class<Function>::value
, std::nullptr_t >::type = nullptr
, typename... Args>
void addCallback ( const FString& cb_signal
, Object&& cb_instance
, Function&& cb_function
, Args&&... args)
{
// Add a function object to an instance as callback
auto fn = std::bind (std::forward<Function>(cb_function), std::forward<Args>(args)...);
FCallbackData obj{ cb_signal, cb_instance, nullptr, fn };
callback_objects.push_back(obj);
}
template<typename Function
, typename std::enable_if< ! std::is_member_function_pointer<Function>::value
&& ! std::is_function<typename std::remove_pointer<Function>::type>::value
&& ! std::is_function<Function>::value
&& ! std::is_pointer<Function>::value
&& std::is_object<Function>::value
&& std::is_class<Function>::value
, std::nullptr_t >::type = nullptr
, typename... Args>
void addCallback ( const FString& cb_signal
, Function&& cb_function
, Args&&... args)
{
// Add a function object as callback
auto fn = std::bind ( std::forward<Function>(cb_function)
, std::forward<Args>(args)... );
FCallbackData obj{ cb_signal, nullptr, nullptr, fn };
callback_objects.push_back(obj);
}
template<typename Function
, typename std::enable_if< ! std::is_member_function_pointer<Function>::value
&& std::is_function<typename std::remove_pointer<Function>::type>::value
&& std::is_function<Function>::value
&& ! std::is_pointer<Function>::value
&& ! std::is_object<Function>::value
&& ! std::is_class<Function>::value
, std::nullptr_t >::type = nullptr
, typename... Args>
void addCallback ( const FString& cb_signal
, Function& cb_function
, Args&&... args)
{
// Add a function as callback
auto ptr = reinterpret_cast<void*>(&cb_function);
auto fn = std::bind ( std::forward<Function>(cb_function)
, std::forward<Args>(args)... );
FCallbackData obj{ cb_signal, nullptr, ptr, fn };
callback_objects.push_back(obj);;
}
template<typename Function
, typename std::enable_if< ! std::is_member_function_pointer<Function>::value
&& std::is_function<typename std::remove_pointer<Function>::type>::value
&& ! std::is_function<Function>::value
&& std::is_pointer<Function>::value
&& std::is_object<Function>::value
&& ! std::is_class<Function>::value
, std::nullptr_t >::type = nullptr
, typename... Args>
void addCallback ( const FString& cb_signal
, Function&& cb_function
, Args&&... args)
{
// Add a function pointer as callback
auto ptr = reinterpret_cast<void*>(cb_function);
auto fn = std::bind ( std::forward<Function>(cb_function)
, std::forward<Args>(args)... );
FCallbackData obj{ cb_signal, nullptr, ptr, fn };
callback_objects.push_back(obj);
}
template<typename Function
, typename std::enable_if< ! std::is_member_function_pointer<Function>::value
&& ! std::is_function<typename std::remove_pointer<Function>::type>::value
&& ! std::is_function<Function>::value
&& ! std::is_pointer<Function>::value
&& std::is_object<Function>::value
&& std::is_class<Function>::value
, std::nullptr_t >::type = nullptr
, typename... Args>
void addCallback ( const FString& cb_signal
, Function& cb_function
, Args&&... args)
{
// Add a non-union class type as callback
auto fn = std::bind ( std::forward<Function>(cb_function)
, std::forward<Args>(args)... );
FCallbackData obj{ cb_signal, nullptr, nullptr, fn };
callback_objects.push_back(obj);
}
template<typename Object
, typename std::enable_if< ! std::is_member_function_pointer<Object>::value
&& ! std::is_function<typename std::remove_pointer<Object>::type>::value
&& ! std::is_function<Object>::value
&& std::is_pointer<Object>::value
&& std::is_object<Object>::value
&& ! std::is_class<Object>::value
, std::nullptr_t >::type = nullptr >
void delCallback (Object&& cb_instance)
{
// Deletes entries with the given instance from the callback list
if ( callback_objects.empty() )
return;
auto iter = callback_objects.begin();
while ( iter != callback_objects.end() )
{
if ( iter->cb_instance == cb_instance )
iter = callback_objects.erase(iter);
else
++iter;
}
}
void delCallback (const FString& cb_signal)
{
// Deletes entries with the given signal from the callback list
if ( callback_objects.empty() )
return;
auto iter = callback_objects.begin();
while ( iter != callback_objects.end() )
{
if ( iter->cb_signal == cb_signal )
iter = callback_objects.erase(iter);
else
++iter;
}
}
template<typename Object
, typename std::enable_if< ! std::is_member_function_pointer<Object>::value
&& ! std::is_function<typename std::remove_pointer<Object>::type>::value
&& ! std::is_function<Object>::value
&& std::is_pointer<Object>::value
&& std::is_object<Object>::value
&& ! std::is_class<Object>::value
, std::nullptr_t >::type = nullptr >
void delCallback (const FString& cb_signal, Object&& cb_instance)
{
// Deletes entries with the given signal and instance
// from the callback list
if ( callback_objects.empty() )
return;
auto iter = callback_objects.begin();
while ( iter != callback_objects.end() )
{
if ( iter->cb_signal == cb_signal
&& iter->cb_instance == cb_instance )
iter = callback_objects.erase(iter);
else
++iter;
}
}
template<typename FunctionPtr
, typename std::enable_if< ! std::is_member_function_pointer<FunctionPtr>::value
&& std::is_function<typename std::remove_pointer<FunctionPtr>::type>::value
&& ! std::is_function<FunctionPtr>::value
&& std::is_pointer<FunctionPtr>::value
&& std::is_object<FunctionPtr>::value
&& ! std::is_class<FunctionPtr>::value
, std::nullptr_t >::type = nullptr >
void delCallback (FunctionPtr&& cb_func_ptr)
{
// Deletes entries with the given function pointer
// from the callback list
if ( callback_objects.empty() )
return;
auto ptr = reinterpret_cast<void*>(cb_func_ptr);
auto iter = callback_objects.begin();
while ( iter != callback_objects.end() )
{
if ( iter->cb_function_ptr == ptr )
iter = callback_objects.erase(iter);
else
++iter;
}
}
template<typename Function
, typename std::enable_if< ! std::is_member_function_pointer<Function>::value
&& std::is_function<typename std::remove_pointer<Function>::type>::value
&& std::is_function<Function>::value
&& ! std::is_pointer<Function>::value
&& ! std::is_object<Function>::value
&& ! std::is_class<Function>::value
, std::nullptr_t >::type = nullptr >
void delCallback (Function& cb_function)
{
// Deletes entries with the given function from the callback list
if ( callback_objects.empty() )
return;
auto ptr = reinterpret_cast<void*>(&cb_function);
auto iter = callback_objects.begin();
while ( iter != callback_objects.end() )
{
if ( iter->cb_function_ptr == ptr )
iter = callback_objects.erase(iter);
else
++iter;
}
}
void delCallback()
{
// Delete all callbacks from this widget
callback_objects.clear(); // function pointer
}
void emitCallback (const FString& emit_signal)
{
// Initiate callback for the given signal
if ( callback_objects.empty() )
return;
for (auto&& cback : callback_objects)
{
if ( cback.cb_signal == emit_signal )
{
// Calling the stored function pointer
cback.cb_function();
}
}
}
private:
// Typedefs
typedef std::vector<FCallbackData> FCallbackObjects;
// Data members
FCallbackObjects callback_objects{};
};
} // namespace finalcut
#endif // FCALLBACK_H

View File

@ -215,10 +215,10 @@ class FComboBox : public FWidget
void processChanged();
// Callback methods
void cb_setInputField (const FWidget*, const FDataPtr);
void cb_closeComboBox (const FWidget*, const FDataPtr);
void cb_inputFieldSwitch (const FWidget*, const FDataPtr);
void cb_inputFieldHandOver (const FWidget*, const FDataPtr);
void cb_setInputField();
void cb_closeComboBox();
void cb_inputFieldSwitch();
void cb_inputFieldHandOver();
// Data members
FLineEdit input_field{this};

View File

@ -209,9 +209,9 @@ class FDialog : public FWindow
static void delDialog (const FWidget*);
// Callback methods
void cb_move (const FWidget*, const FDataPtr);
void cb_zoom (const FWidget*, const FDataPtr);
void cb_close (const FWidget*, const FDataPtr);
void cb_move();
void cb_zoom();
void cb_close();
// Data members
FString tb_text{}; // title bar text

View File

@ -206,12 +206,12 @@ class FFileDialog : public FDialog
static const FString getHomeDir();
// Callback methods
void cb_processActivate (const FWidget*, const FDataPtr);
void cb_processRowChanged (const FWidget*, const FDataPtr);
void cb_processClicked (const FWidget*, const FDataPtr);
void cb_processCancel (const FWidget*, const FDataPtr);
void cb_processOpen (const FWidget*, const FDataPtr);
void cb_processShowHidden (const FWidget*, const FDataPtr);
void cb_processActivate();
void cb_processRowChanged();
void cb_processClicked();
void cb_processCancel();
void cb_processOpen();
void cb_processShowHidden();
// Data members
static FSystem* fsystem;

View File

@ -123,7 +123,7 @@ class FLabel : public FWidget
void onAccel (FAccelEvent*) override;
// Callback method
void cb_accelWidgetDestroyed (const FWidget*, const FDataPtr);
void cb_accelWidgetDestroyed();
private:
// Constants

View File

@ -125,9 +125,9 @@ class FMenu : public FWindow, public FMenuList
void onAccel (FAccelEvent*) override;
// Callback method
void cb_menuitemEnabled (const FWidget*, const FDataPtr);
void cb_menuitemDisabled (const FWidget*, const FDataPtr);
void cb_menuitemToggled (FWidget*, const FDataPtr) const;
void cb_menuitemEnabled();
void cb_menuitemDisabled();
void cb_menuitemToggled (FMenuItem*) const;
private:
// Constants

View File

@ -99,7 +99,7 @@ class FMenuBar : public FWindow, public FMenuList
void onAccel (FAccelEvent*) override;
// Callback methods
void cb_itemDeactivated (FWidget*, const FDataPtr) const;
void cb_itemDeactivated (FMenuItem*) const;
private:
// Constants

View File

@ -165,8 +165,8 @@ class FMenuItem : public FWidget
void passMouseEvent (T, const FMouseEvent*, fc::events) const;
// Callback methods
void cb_switchToDialog (const FWidget*, FDataPtr) const;
void cb_destroyDialog (FWidget*, const FDataPtr);
void cb_switchToDialog (FDialog*) const;
void cb_destroyDialog (FDialog*);
virtual void processClicked();

View File

@ -134,7 +134,7 @@ class FMessageBox : public FDialog
void adjustSize() override;
// Callback method
void cb_processClick (const FWidget*, FDataPtr);
void cb_processClick (int);
private:
// Methods

View File

@ -196,7 +196,7 @@ void initScrollbar ( FScrollbarPtr& bar
bar->addCallback
(
"change-value",
std::bind(cb_handler, cb_instance, _1, _2)
std::bind(cb_handler, cb_instance, bar.get(), nullptr)
);
}

View File

@ -140,8 +140,8 @@ class FSpinBox : public FWidget
void forceFocus();
// Callback methods
void cb_inputFieldActivate (const finalcut::FWidget*, const FDataPtr);
void cb_inputFieldChange (finalcut::FWidget*, const FDataPtr);
void cb_inputFieldActivate();
void cb_inputFieldChange (const FLineEdit&);
// Data members
FLineEdit input_field{this};

View File

@ -227,7 +227,7 @@ class FStatusBar : public FWindow
void onMouseMove (FMouseEvent*) override;
// Callback method
void cb_statuskey_activated (FWidget*, const FDataPtr);
void cb_statuskey_activated (FStatusKey*);
private:
// Typedef

View File

@ -31,6 +31,7 @@
#include <sys/types.h>
#include <cstddef>
#include <functional>
#include <limits>
#include <unordered_map>
#include <string>
@ -69,7 +70,7 @@ typedef uInt16 FColor;
typedef uInt16 FAttribute;
typedef uInt32 FKey;
typedef void* FDataPtr;
typedef std::function<void()> FCall;
namespace finalcut
{

View File

@ -390,7 +390,7 @@ class FVTerm
static bool canClearLeadingWS (uInt&, uInt);
static bool canClearTrailingWS (uInt&, uInt);
bool skipUnchangedCharacters (uInt&, uInt, uInt) const;
void printRange (uInt, uInt, uInt, bool);
void printRange (uInt, uInt, uInt, bool) const;
void replaceNonPrintableFullwidth (uInt, FChar*&) const;
void printCharacter (uInt&, uInt, bool, FChar*&) const;
void printFullWidthCharacter (uInt&, uInt, FChar*&) const;

View File

@ -98,6 +98,7 @@
#include <utility>
#include <vector>
#include "final/fcallback.h"
#include "final/fobject.h"
#include "final/fpoint.h"
#include "final/frect.h"
@ -105,16 +106,11 @@
#include "final/ftypes.h"
#include "final/fvterm.h"
// Callback macros
#define F_FUNCTION_CALLBACK(h) \
reinterpret_cast<finalcut::FWidget::FCallbackPtr>((h))
#define F_METHOD_CALLBACK(i,h) \
reinterpret_cast<finalcut::FWidget*>((i)), \
std::bind ( reinterpret_cast<finalcut::FWidget::FMemberCallback>((h)) \
, reinterpret_cast<finalcut::FWidget*>((i)) \
, std::placeholders::_1 \
, std::placeholders::_2 )
// Old callback macros (deprecated)
#define F_FUNCTION_CALLBACK(h) (h), this, nullptr
#define F_FUNCTION_CALLBACK_DATA(h) (h), this
#define F_METHOD_CALLBACK(i,h) (i), (h), this, nullptr
#define F_METHOD_CALLBACK_DATA(i,h) (i), (h), this
namespace finalcut
{
@ -147,9 +143,6 @@ class FWidget : public FVTerm, public FObject
// Typedefs
typedef std::vector<FWidget*> FWidgetList;
typedef std::vector<FAccelerator> FAcceleratorList;
typedef void (*FCallbackPtr)(FWidget*, FDataPtr);
typedef void (FWidget::*FMemberCallback)(FWidget*, FDataPtr);
typedef std::function<void(FWidget*, FDataPtr)> FCallback;
typedef std::shared_ptr<FWidgetColors> FWidgetColorsPtr;
struct FWidgetFlags // Properties of a widget ⚑
@ -323,17 +316,11 @@ class FWidget : public FVTerm, public FObject
int numOfFocusableChildren();
virtual bool close();
void clearStatusbarMessage();
void addCallback ( const FString&
, const FCallback&
, FDataPtr = nullptr );
void addCallback ( const FString&
, FWidget*
, const FCallback&
, FDataPtr = nullptr );
void delCallback (const FCallback&);
void delCallback (const FWidget*);
void delAllCallbacks();
void emitCallback (const FString&);
template<typename... Args>
void addCallback (FString&&, Args&&...);
template<typename... Args>
void delCallback (Args&&...);
void emitCallback (FString&&);
void addAccelerator (FKey);
virtual void addAccelerator (FKey, FWidget*);
void delAccelerator ();
@ -351,11 +338,6 @@ class FWidget : public FVTerm, public FObject
static void quit();
protected:
struct FCallbackData; // forward declaration
// Typedefs
typedef std::vector<FCallbackData> FCallbackObjects;
// Accessor
FTermArea* getPrintArea() override;
static uInt getModalDialogCounter();
@ -461,7 +443,6 @@ class FWidget : public FVTerm, public FObject
void KeyDownEvent (FKeyEvent*);
void emitWheelCallback (const FWheelEvent*);
void setWindowFocus (bool);
FCallbackPtr getCallbackPtr (const FCallback&);
bool changeFocus (FWidget*, FWidget*, fc::FocusTypes);
void processDestroy();
virtual void draw();
@ -498,7 +479,7 @@ class FWidget : public FVTerm, public FObject
FColor background_color{fc::Default};
FString statusbar_message{};
FAcceleratorList accelerator_list{};
FCallbackObjects callback_objects{};
FCallback callback_impl{};
static FStatusBar* statusbar;
static FMenuBar* menubar;
@ -532,71 +513,10 @@ class FWidget : public FVTerm, public FObject
friend void clearFlatBorder (FWidget*);
};
//----------------------------------------------------------------------
// struct FWidget::FCallbackData
//----------------------------------------------------------------------
struct FWidget::FCallbackData
{
// Constructor
FCallbackData()
{ }
FCallbackData (const FString& s, FWidget* i, const FCallback& c, FDataPtr d)
: cb_signal(s)
, cb_instance(i)
, cb_function(c)
, data(d)
{ }
FCallbackData (const FCallbackData& c) // copy constructor
: cb_signal(c.cb_signal)
, cb_instance(c.cb_instance)
, cb_function(c.cb_function)
, data(c.data)
{ }
FCallbackData (FCallbackData&& c) noexcept // move constructor
: cb_signal(std::move(c.cb_signal))
, cb_instance(std::move(c.cb_instance))
, cb_function(std::move(c.cb_function))
, data(std::move(c.data))
{ }
// Destructor
~FCallbackData()
{ }
// Overloaded operators
FCallbackData& operator = (const FCallbackData& c)
{
cb_signal = c.cb_signal;
cb_instance = c.cb_instance;
cb_function = c.cb_function;
data = c.data;
return *this;
}
FCallbackData& operator = (FCallbackData&& c) noexcept
{
cb_signal = std::move(c.cb_signal);
cb_instance = std::move(c.cb_instance);
cb_function = std::move(c.cb_function);
data = std::move(c.data);
return *this;
}
// Data members
FString cb_signal{};
FWidget* cb_instance{};
FCallback cb_function{};
FDataPtr data{};
};
// non-member function forward declarations
// implemented in fwidget_functions.cpp
//----------------------------------------------------------------------
void initWidget (FWidget*);
void detectTermSize();
bool isFocusNextKey (const FKey);
bool isFocusPrevKey (const FKey);
@ -1062,6 +982,27 @@ inline bool FWidget::isPaddingIgnored() const
inline void FWidget::clearStatusbarMessage()
{ statusbar_message.clear(); }
//----------------------------------------------------------------------
template<typename... Args>
inline void FWidget::addCallback (FString&& cb_signal, Args&&... args)
{
callback_impl.addCallback ( std::forward<FString>(cb_signal)
, std::forward<Args>(args)... );
}
//----------------------------------------------------------------------
template<typename... Args>
inline void FWidget::delCallback (Args&&... args)
{
callback_impl.delCallback(std::forward<Args>(args)...);
}
//----------------------------------------------------------------------
inline void FWidget::emitCallback (FString&& emit_signal)
{
callback_impl.emitCallback(std::forward<FString>(emit_signal));
}
//----------------------------------------------------------------------
inline void FWidget::addAccelerator (FKey key)
{ addAccelerator (key, this); }

View File

@ -8,6 +8,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include -Wall -Werror -std=c++11
noinst_PROGRAMS = \
fobject_test \
fcallback_test \
fmouse_test \
fkeyboard_test \
ftermdata_test \
@ -28,6 +29,7 @@ noinst_PROGRAMS = \
frect_test
fobject_test_SOURCES = fobject-test.cpp
fcallback_test_SOURCES = fcallback-test.cpp
fmouse_test_SOURCES = fmouse-test.cpp
fkeyboard_test_SOURCES = fkeyboard-test.cpp
ftermdata_test_SOURCES = ftermdata-test.cpp

534
test/fcallback-test.cpp Normal file
View File

@ -0,0 +1,534 @@
/***********************************************************************
* callback-test.cpp - FCallback unit tests *
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2020 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 *
* published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* FINAL CUT is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <final/final.h>
//----------------------------------------------------------------------
// class Widget
//----------------------------------------------------------------------
class Widget
{
public:
template<typename... Args>
void addCallback (finalcut::FString&& cb_signal, Args&&... args)
{
cb.addCallback(std::forward<finalcut::FString>(cb_signal), std::forward<Args>(args)...);
}
template<typename... Args>
void delCallback (Args&&... args)
{
cb.delCallback(std::forward<Args>(args)...);
}
void emitCallback (finalcut::FString&& emit_signal)
{
cb.emitCallback(std::forward<finalcut::FString>(emit_signal));
}
private:
finalcut::FCallback cb{};
};
//----------------------------------------------------------------------
// class cb_class
//----------------------------------------------------------------------
class cb_class final : public finalcut::FWidget
{
public:
cb_class (int i, finalcut::FWidget* parent)
: finalcut::FWidget{parent}
, data{i}
{ }
void cb_method_ptr (int* value)
{
(*value)--;
}
void cb_method_ptr_const (int* value) const
{
*value -= 4;
}
void cb_method_ref (int& value)
{
value -= data;
}
void cb_method_ref_const (int& value) const
{
value -= (2 * data);
}
private:
int data;
};
//----------------------------------------------------------------------
// functions
//----------------------------------------------------------------------
void cb_function_ptr (int* value)
{
(*value)++;
}
//----------------------------------------------------------------------
void cb_function_ref (int& value)
{
value += 2;
}
//----------------------------------------------------------------------
// class FCallbackTest
//----------------------------------------------------------------------
class FCallbackTest : public CPPUNIT_NS::TestFixture
{
public:
FCallbackTest()
{ }
protected:
void classNameTest();
void memberFunctionCallbackTest();
void instanceWithFunctionCallbackTest();
void functionObjectTest();
void functionCallbackTest();
void functionPointerCallbackTest();
void nonUnionClassCallbackTest();
void ownWidgetTest();
private:
// Adds code needed to register the test suite
CPPUNIT_TEST_SUITE (FCallbackTest);
// Add a methods to the test suite
CPPUNIT_TEST (classNameTest);
CPPUNIT_TEST (memberFunctionCallbackTest);
CPPUNIT_TEST (instanceWithFunctionCallbackTest);
CPPUNIT_TEST (functionObjectTest);
CPPUNIT_TEST (functionCallbackTest);
CPPUNIT_TEST (functionPointerCallbackTest);
CPPUNIT_TEST (nonUnionClassCallbackTest);
CPPUNIT_TEST (ownWidgetTest);
// End of test suite definition
CPPUNIT_TEST_SUITE_END();
// Data member
static finalcut::FWidget root_widget;
};
// static class attributes
finalcut::FWidget FCallbackTest::root_widget{nullptr};
//----------------------------------------------------------------------
void FCallbackTest::classNameTest()
{
const finalcut::FCallback cb;
const finalcut::FString& classname = cb.getClassName();
CPPUNIT_ASSERT ( classname == "FCallback" );
}
//----------------------------------------------------------------------
void FCallbackTest::memberFunctionCallbackTest()
{
finalcut::FCallback cb{};
cb_class c{5, &root_widget};
int i{75};
using Object = decltype(&c);
using MemberFunctionPointer = decltype(&cb_class::cb_method_ptr);
CPPUNIT_ASSERT ( 0 == std::is_member_function_pointer<Object>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<typename std::remove_pointer<Object>::type>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<Object>::value );
CPPUNIT_ASSERT ( 1 == std::is_pointer<Object>::value );
CPPUNIT_ASSERT ( 1 == std::is_object<Object>::value );
CPPUNIT_ASSERT ( 0 == std::is_class<Object>::value );
CPPUNIT_ASSERT ( 1 == std::is_member_function_pointer<MemberFunctionPointer>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<typename std::remove_pointer<MemberFunctionPointer>::type>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<MemberFunctionPointer>::value );
CPPUNIT_ASSERT ( 0 == std::is_pointer<MemberFunctionPointer>::value );
CPPUNIT_ASSERT ( 1 == std::is_object<MemberFunctionPointer>::value );
CPPUNIT_ASSERT ( 0 == std::is_class<MemberFunctionPointer>::value );
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.addCallback ("clicked", &c, &cb_class::cb_method_ptr, &i);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
cb.addCallback ("activate", &c, &cb_class::cb_method_ptr_const, &i);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
CPPUNIT_ASSERT ( i == 75 );
cb.emitCallback ("pressed");
CPPUNIT_ASSERT ( i == 75 );
cb.emitCallback("clicked");
CPPUNIT_ASSERT ( i == 74 );
cb.delCallback ("clicked");
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i == 74 );
cb.emitCallback ("activate");
CPPUNIT_ASSERT ( i == 70 );
cb.delCallback ("activate");
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.emitCallback ("activate");
CPPUNIT_ASSERT ( i == 70 );
cb.addCallback ("on", &c, &cb_class::cb_method_ref, std::ref(i));
cb.addCallback ("on", &c, &cb_class::cb_method_ref_const, std::ref(i));
cb.emitCallback ("on");
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
CPPUNIT_ASSERT ( i == 55 );
cb.delCallback (&c);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.emitCallback ("on");
CPPUNIT_ASSERT ( i == 55 );
}
//----------------------------------------------------------------------
void FCallbackTest::instanceWithFunctionCallbackTest()
{
finalcut::FCallback cb{};
cb_class c{15, &root_widget};
int i{100};
auto func1 = std::bind(&cb_class::cb_method_ptr, &c, &i);
auto func2 = std::bind(&cb_class::cb_method_ptr_const, &c, &i);
auto func3 = std::bind(&cb_class::cb_method_ref, &c, std::ref(i));
auto func4 = std::bind(&cb_class::cb_method_ref_const, &c, std::ref(i));
auto func5 = std::bind(&cb_class::cb_method_ptr, &c, std::placeholders::_1);
auto func6 = std::bind(&cb_class::cb_method_ref, &c, std::placeholders::_1);
using Object = decltype(&c);
using ClassObject = decltype(func1);
CPPUNIT_ASSERT ( 0 == std::is_member_function_pointer<Object>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<typename std::remove_pointer<Object>::type>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<Object>::value );
CPPUNIT_ASSERT ( 1 == std::is_pointer<Object>::value );
CPPUNIT_ASSERT ( 1 == std::is_object<Object>::value );
CPPUNIT_ASSERT ( 0 == std::is_class<Object>::value );
CPPUNIT_ASSERT ( 0 == std::is_member_function_pointer<ClassObject>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<typename std::remove_pointer<ClassObject>::type>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<ClassObject>::value );
CPPUNIT_ASSERT ( 0 == std::is_pointer<ClassObject>::value );
CPPUNIT_ASSERT ( 1 == std::is_object<ClassObject>::value );
CPPUNIT_ASSERT ( 1 == std::is_class<ClassObject>::value );
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.addCallback ("clicked", &c, std::move(func1));
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
cb.addCallback ("activate", &c, std::move(func2));
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
CPPUNIT_ASSERT ( i == 100 );
cb.emitCallback ("pressed");
CPPUNIT_ASSERT ( i == 100 );
cb.emitCallback("clicked");
CPPUNIT_ASSERT ( i == 99 );
cb.delCallback ("clicked");
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i == 99 );
cb.emitCallback ("activate");
CPPUNIT_ASSERT ( i == 95 );
cb.delCallback ("activate");
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.emitCallback ("activate");
CPPUNIT_ASSERT ( i == 95 );
cb.addCallback ("on", &c, std::move(func3));
cb.addCallback ("on", &c, std::move(func4));
cb.emitCallback ("on");
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
CPPUNIT_ASSERT ( i == 50 );
cb.delCallback (&c);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.emitCallback ("on");
CPPUNIT_ASSERT ( i == 50 );
cb.addCallback ("enabled", &c, std::move(func5), &i);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
cb.addCallback ("joined", &c, std::move(func6), std::ref(i));
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
cb.emitCallback("enabled");
CPPUNIT_ASSERT ( i == 49 );
cb.delCallback ("enabled", &c);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
cb.emitCallback("joined");
CPPUNIT_ASSERT ( i == 34 );
cb.delCallback ("joined", &c);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
}
//----------------------------------------------------------------------
void FCallbackTest::functionObjectTest()
{
finalcut::FCallback cb{};
int i1{2};
int i2{3};
auto lambda = [] (int& a, const int& b)
{
a += b;
};
using Lambda = decltype(lambda);
CPPUNIT_ASSERT ( 0 == std::is_member_function_pointer<Lambda>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<typename std::remove_pointer<Lambda>::type>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<Lambda>::value );
CPPUNIT_ASSERT ( 0 == std::is_pointer<Lambda>::value );
CPPUNIT_ASSERT ( 1 == std::is_object<Lambda>::value );
CPPUNIT_ASSERT ( 1 == std::is_class<Lambda>::value );
cb.addCallback
(
"clicked",
std::ref(lambda),
std::ref(i1),
std::cref(i2)
);
cb.addCallback
(
"changed",
[] (int* a)
{
(*a)++;
},
&i2
);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
CPPUNIT_ASSERT ( i1 == 2 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 5 );
i2 = -3;
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 2 );
cb.emitCallback ("changed");
CPPUNIT_ASSERT ( i2 == -2 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 0 );
cb.delCallback("changed");
cb.emitCallback ("changed");
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
CPPUNIT_ASSERT ( i2 == -2 );
cb.delCallback();
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
}
//----------------------------------------------------------------------
void FCallbackTest::functionCallbackTest()
{
finalcut::FCallback cb{};
int i1{22};
int i2{11};
using Function = decltype(cb_function_ptr);
CPPUNIT_ASSERT ( 0 == std::is_member_function_pointer<Function>::value );
CPPUNIT_ASSERT ( 1 == std::is_function<typename std::remove_pointer<Function>::type>::value );
CPPUNIT_ASSERT ( 1 == std::is_function<Function>::value );
CPPUNIT_ASSERT ( 0 == std::is_pointer<Function>::value );
CPPUNIT_ASSERT ( 0 == std::is_object<Function>::value );
CPPUNIT_ASSERT ( 0 == std::is_class<Function>::value );
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.addCallback ("clicked", cb_function_ptr, &i1);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
CPPUNIT_ASSERT ( i1 == 22 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 23 );
cb.addCallback ("clicked", cb_function_ref, std::ref(i2));
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
CPPUNIT_ASSERT ( i2 == 11 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 24 );
CPPUNIT_ASSERT ( i2 == 13 );
cb.delCallback (&cb_function_ptr); // Delete via function pointer
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 24 );
CPPUNIT_ASSERT ( i2 == 15 );
cb.delCallback (cb_function_ref); // Delete via function
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 24 );
CPPUNIT_ASSERT ( i2 == 15 );
}
//----------------------------------------------------------------------
void FCallbackTest::functionPointerCallbackTest()
{
finalcut::FCallback cb{};
int i1{5};
int i2{9};
using FunctionPointer = decltype(&cb_function_ptr);
CPPUNIT_ASSERT ( 0 == std::is_member_function_pointer<FunctionPointer>::value );
CPPUNIT_ASSERT ( 1 == std::is_function<typename std::remove_pointer<FunctionPointer>::type>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<FunctionPointer>::value );
CPPUNIT_ASSERT ( 1 == std::is_pointer<FunctionPointer>::value );
CPPUNIT_ASSERT ( 1 == std::is_object<FunctionPointer>::value );
CPPUNIT_ASSERT ( 0 == std::is_class<FunctionPointer>::value );
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
cb.addCallback ("clicked", &cb_function_ptr, &i1);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
CPPUNIT_ASSERT ( i1 == 5 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 6 );
cb.addCallback ("clicked", &cb_function_ref, std::ref(i2));
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
CPPUNIT_ASSERT ( i2 == 9 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 7 );
CPPUNIT_ASSERT ( i2 == 11 );
cb.delCallback (&cb_function_ptr);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
cb.emitCallback ("clicked");
CPPUNIT_ASSERT ( i1 == 7 );
CPPUNIT_ASSERT ( i2 == 13 );
}
//----------------------------------------------------------------------
void FCallbackTest::nonUnionClassCallbackTest()
{
finalcut::FCallback cb{};
int i{4};
auto lambda1 = [] (int* value)
{
*value = *value << 8;
};
auto lambda2 = [] (int& value)
{
value = value >> 4;
};
using NonUnionClass = decltype(lambda1);
CPPUNIT_ASSERT ( 0 == std::is_member_function_pointer<NonUnionClass>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<typename std::remove_pointer<NonUnionClass>::type>::value );
CPPUNIT_ASSERT ( 0 == std::is_function<NonUnionClass>::value );
CPPUNIT_ASSERT ( 0 == std::is_pointer<NonUnionClass>::value );
CPPUNIT_ASSERT ( 1 == std::is_object<NonUnionClass>::value );
CPPUNIT_ASSERT ( 1 == std::is_class<NonUnionClass>::value );
cb.addCallback ("toggled", lambda1, &i);
CPPUNIT_ASSERT ( cb.getCallbackCount() == 1 );
CPPUNIT_ASSERT ( i == 4 );
cb.emitCallback ("toggled");
CPPUNIT_ASSERT ( i == 1024 );
cb.addCallback ("row-selected", lambda2, std::ref(i));
CPPUNIT_ASSERT ( cb.getCallbackCount() == 2 );
CPPUNIT_ASSERT ( i == 1024 );
cb.emitCallback ("row-selected");
CPPUNIT_ASSERT ( i == 64 );
cb.delCallback();
CPPUNIT_ASSERT ( cb.getCallbackCount() == 0 );
}
void FCallbackTest::ownWidgetTest()
{
Widget w;
int value = 3141593;
int* i = &value;
w.addCallback("focus-in", cb_function_ptr, i);
CPPUNIT_ASSERT ( value == 3141593 );
w.emitCallback("focus-in");
CPPUNIT_ASSERT ( value == 3141594 );
w.emitCallback("focus-in");
CPPUNIT_ASSERT ( value == 3141595 );
w.emitCallback("focus-in");
CPPUNIT_ASSERT ( value == 3141596 );
w.delCallback();
w.emitCallback("focus-in");
CPPUNIT_ASSERT ( value != 3141597 );
CPPUNIT_ASSERT ( value == 3141596 );
}
// Put the test suite in the registry
CPPUNIT_TEST_SUITE_REGISTRATION (FCallbackTest);
// The general unit test main part
#include <main-test.inc>