diff --git a/src/GUI/OptionsGroup/Field.hpp b/src/GUI/OptionsGroup/Field.hpp new file mode 100644 index 000000000..2a9b1aad2 --- /dev/null +++ b/src/GUI/OptionsGroup/Field.hpp @@ -0,0 +1,45 @@ +#ifndef SLIC3R_FIELD_HPP +#define SLIC3R_FIELD_HPP + +#include + +namespace Slic3r { namespace GUI { + +class UI_Checkbox { +public: + UI_Checkbox(wxWindow* parent, wxWindowID checkid = wxID_ANY) : parent(parent) { + ui_window = new wxCheckBox(parent, checkid, ""); + _check = dynamic_cast(ui_window); + _check->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) { this->_on_change(""); e.Skip(); }); + } + ~UI_Checkbox() { wxDELETE(ui_window); ui_window = _check = nullptr; } + /// Function to call when the contents of this change. + std::function on_change {nullptr}; + std::function on_kill_focus {nullptr}; + + /// Don't trigger on_change when this is true. + bool disable_change_event {false}; + + void enable() { this->ui_window->Enable(); } + void disable() { this->ui_window->Disable(); } + + void toggle(bool enable = true) { enable ? this->enable() : this->disable(); } + + wxCheckBox* check() { return _check; } + + bool get_bool() { return _check->GetValue();} +private: + wxWindow* parent {nullptr}; + wxWindow* ui_window {nullptr}; + wxCheckBox* _check {nullptr}; + + void _on_change(std::string opt_id) { + if (!this->disable_change_event) { + this->on_change(opt_id, this->get_bool()); + } + } +}; + +} } // Namespace Slic3r::GUI + +#endif // SLIC3R_FIELD_HPP diff --git a/src/test/GUI/test_field_checkbox.cpp b/src/test/GUI/test_field_checkbox.cpp index 3818bb9ba..4615a96a3 100644 --- a/src/test/GUI/test_field_checkbox.cpp +++ b/src/test/GUI/test_field_checkbox.cpp @@ -3,24 +3,53 @@ #ifndef WX_PRECOMP #include "wx/app.h" #include "wx/checkbox.h" + #include "wx/uiaction.h" #endif // WX_PRECOMP - +#include #include "testableframe.h" +#include "OptionsGroup/Field.hpp" +using namespace Slic3r::GUI; +SCENARIO( "GUI Checkbox option items fire their on_change event when clicked and appropriate." ) { + wxUIActionSimulator sim; + wxMilliSleep(500); + GIVEN( "A checkbox field item and disable_change = false") { + auto* exec_counter = new int(0); + auto* test_field {new UI_Checkbox(wxTheApp->GetTopWindow(), wxID_ANY)}; + wxTheApp->GetTopWindow()->Show(); + wxTheApp->GetTopWindow()->Fit(); + test_field->disable_change_event = false; + auto changefunc {[exec_counter](const std::string& opt_id, bool value) { std::cout << *exec_counter << " " ; *exec_counter += 1; std::cout << "Executing On_Action " << *exec_counter << "\n"; }}; + test_field->on_change = changefunc; -SCENARIO( "checkboxes return true when checked.", "[checkbox]" ) { - GIVEN( "A checkbox item") { - wxCheckBox* m_check = new wxCheckBox(wxTheApp->GetTopWindow(), wxID_ANY, "Check box"); WHEN ( "the box is checked") { - m_check->SetValue(true); - THEN ( "the checkbox reads true") { - REQUIRE(m_check->IsChecked() == true); + *exec_counter = 0; + sim.MouseMove(test_field->check()->GetScreenPosition() + wxPoint(10, 10)); + wxYield(); + sim.MouseMove(test_field->check()->GetScreenPosition() + wxPoint(10, 10)); + wxYield(); + sim.MouseClick(wxMOUSE_BTN_LEFT); + wxYield(); + sim.MouseClick(wxMOUSE_BTN_LEFT); + wxYield(); + THEN ( "on_change is executed.") { + REQUIRE(*exec_counter == 1); } } - WHEN ( "the box is not checked") { - m_check->SetValue(false); - THEN ( "the checkbox reads false") { - REQUIRE(m_check->IsChecked() == false); + WHEN ( "the box is unchecked") { + *exec_counter = 0; + sim.MouseMove(test_field->check()->GetScreenPosition() + wxPoint(10, 10)); + wxYield(); + sim.MouseMove(test_field->check()->GetScreenPosition() + wxPoint(10, 10)); + wxYield(); + sim.MouseClick(wxMOUSE_BTN_LEFT); + wxYield(); + sim.MouseClick(wxMOUSE_BTN_LEFT); + wxYield(); + THEN ( "on_change is executed.") { + REQUIRE(*exec_counter == 1); } } + delete test_field; + delete exec_counter; } }