mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-14 11:56:06 +08:00
Continued implementation for UI_Slider
Added enable/disable methods and set_range() text control should update as well. Added tests to build.
This commit is contained in:
parent
2090fae11d
commit
17e588904b
@ -193,6 +193,7 @@ set(UI_TEST_SOURCES
|
||||
${GUI_TESTDIR}/test_field_point.cpp
|
||||
${GUI_TESTDIR}/test_field_point3.cpp
|
||||
${GUI_TESTDIR}/test_field_colorpicker.cpp
|
||||
${GUI_TESTDIR}/test_field_slider.cpp
|
||||
${GUI_TESTDIR}/test_misc_ui.cpp
|
||||
)
|
||||
|
||||
|
@ -421,8 +421,7 @@ private:
|
||||
|
||||
class UI_Slider : public UI_Sizer {
|
||||
public:
|
||||
UI_Slider(wxWindow* parent, Slic3r::ConfigOptionDef _opt);
|
||||
UI_Slider(wxWindow* parent, Slic3r::ConfigOptionDef _opt, size_t scale);
|
||||
UI_Slider(wxWindow* parent, Slic3r::ConfigOptionDef _opt, size_t scale = 10);
|
||||
|
||||
~UI_Slider();
|
||||
|
||||
@ -431,11 +430,21 @@ public:
|
||||
double get_double() override;
|
||||
int get_int() override;
|
||||
|
||||
void enable() override;
|
||||
void disable() override;
|
||||
|
||||
/// change the min/max of the built-in slider
|
||||
template <typename T> void set_range(T min, T max);
|
||||
|
||||
/// Change the scale of the slider bar. Return value from get_X functions does not change.
|
||||
void set_scale(size_t new_scale);
|
||||
|
||||
/// Returns pointer to owned wxSlider.
|
||||
wxSlider* slider() { return _slider;}
|
||||
/// Returns pointer to owned wxTextCtrl.
|
||||
wxTextCtrl* textctrl() { return _textctrl;}
|
||||
|
||||
/// Registered on_change callback.
|
||||
std::function<void (const std::string&, const double&)> on_change {nullptr};
|
||||
protected:
|
||||
virtual std::string LogChannel() override { return "UI_Slider"s; }
|
||||
@ -445,6 +454,7 @@ private:
|
||||
this->on_change(opt_id, _slider->GetValue() / _scale);
|
||||
}
|
||||
}
|
||||
void _update_textctrl();
|
||||
wxTextCtrl* _textctrl {nullptr};
|
||||
wxSlider* _slider {nullptr};
|
||||
size_t _scale {10};
|
||||
|
@ -3,28 +3,98 @@
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
UI_Slider::UI_Slider(wxWindow* parent, Slic3r::ConfigOptionDef _opt) : UI_Sizer(parent, _opt), _scale(10) {
|
||||
}
|
||||
UI_Slider::UI_Slider(wxWindow* parent, Slic3r::ConfigOptionDef _opt, size_t scale ) : UI_Sizer(parent, _opt), _scale(scale) {
|
||||
UI_Slider::UI_Slider(wxWindow* parent, Slic3r::ConfigOptionDef _opt, size_t scale) : UI_Sizer(parent, _opt), _scale(scale) {
|
||||
double default_value {0.0};
|
||||
|
||||
sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
_slider = new wxSlider(parent, wxID_ANY,
|
||||
(default_value < _opt.min ? _opt.min : default_value) * this->_scale,
|
||||
(_opt.min > _opt.max || _opt.min == INT_MIN ? 0 : _opt.min) * this->_scale,
|
||||
(_opt.max <= _opt.min || _opt.max == INT_MAX ? 100 : _opt.max) * this->_scale,
|
||||
wxDefaultPosition,
|
||||
wxSize(_opt.width, _opt.height));
|
||||
|
||||
_textctrl = new wxTextCtrl(parent, wxID_ANY,
|
||||
static_cast<double>(_slider->GetValue()) / this->_scale,
|
||||
wxDefaultPosition,
|
||||
wxSize(50, -1));
|
||||
|
||||
|
||||
sizer->Add(_slider, 1, wxALIGN_CENTER_VERTICAL, 0);
|
||||
sizer->Add(_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||
|
||||
_textctrl->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) { this->_on_change(""); e.Skip(); });
|
||||
_textctrl->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) { if (this->on_kill_focus != nullptr) {this->on_kill_focus(""); this->_on_change("");} e.Skip(); });
|
||||
|
||||
_slider->Bind(wxEVT_SLIDER, [this](wxCommandEvent& e) { this->_on_change(""); e.Skip(); });
|
||||
|
||||
|
||||
|
||||
}
|
||||
UI_Slider::~UI_Slider() { _slider->Destroy(); _textctrl->Destroy(); }
|
||||
|
||||
void UI_Slider::set_value(boost::any value) {
|
||||
this->disable_change_event = true;
|
||||
if (value.type() == typeid(int)) {
|
||||
this->_slider->SetValue(boost::any_cast<int>(value) * this->_scale);
|
||||
} else if (value.type() == typeid(double)) {
|
||||
this->_slider->SetValue(boost::any_cast<double>(value) * this->_scale);
|
||||
} else if (value.type() == typeid(float)) {
|
||||
this->_slider->SetValue(boost::any_cast<float>(value) * this->_scale);
|
||||
} else if (value.type() == typeid(std::string)) {
|
||||
std::string _val = boost::any_cast<std::string>(value);
|
||||
try {
|
||||
this->_slider->SetValue(std::stod(_val) * this->_scale);
|
||||
} catch (std::invalid_argument &e) {
|
||||
Slic3r::Log::error(this->LogChannel()) << "Conversion to numeric from string failed.\n";
|
||||
}
|
||||
} else if (value.type() == typeid(wxString)) {
|
||||
std::string _val = boost::any_cast<wxString>(value).ToStdString();
|
||||
try {
|
||||
this->_slider->SetValue(std::stod(_val) * this->_scale);
|
||||
} catch (std::invalid_argument &e) {
|
||||
Slic3r::Log::error(this->LogChannel()) << "Conversion to numeric from string failed.\n";
|
||||
}
|
||||
} else {
|
||||
Slic3r::Log::warn(this->LogChannel(), LOG_WSTRING("Type " << value.type().name() << " is not handled in set_value."));
|
||||
}
|
||||
this->_update_textctrl();
|
||||
this->disable_change_event = false;
|
||||
}
|
||||
|
||||
double UI_Slider::get_double() {
|
||||
return 0.0;
|
||||
return static_cast<double>(this->_slider->GetValue()) / this->_scale;
|
||||
}
|
||||
|
||||
int UI_Slider::get_int() {
|
||||
return 0;
|
||||
return static_cast<int>(this->_slider->GetValue()) / this->_scale;
|
||||
}
|
||||
|
||||
std::string UI_Slider::get_string() {
|
||||
return std::string();
|
||||
return trim_zeroes(std::to_string(static_cast<double>(this->_slider->GetValue()) / this->_scale));
|
||||
}
|
||||
|
||||
void UI_Slider::set_scale(size_t new_scale) {
|
||||
this->disable_change_event = true;
|
||||
auto current_value {this->get_double()};
|
||||
|
||||
this->_slider->SetRange(
|
||||
this->_slider->GetMin() / this->_scale * new_scale,
|
||||
this->_slider->GetMax() / this->_scale * new_scale);
|
||||
this->_scale = new_scale;
|
||||
this->set_value(current_value);
|
||||
|
||||
this->disable_change_event = false;
|
||||
}
|
||||
|
||||
void UI_Slider::_update_textctrl() {
|
||||
this->_textctrl->ChangeValue(this->get_string());
|
||||
this->_textctrl->SetInsertionPointEnd();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void UI_Slider::set_range(T min, T max) {
|
||||
this->_slider->SetRange(static_cast<int>(min * static_cast<int>(self->_scale)), static_cast<int>(max * static_cast<int>(self->_scale)));
|
||||
}
|
||||
|
||||
} } // Namespace Slic3r::GUI
|
||||
|
@ -77,6 +77,34 @@ SCENARIO( "UI_Slider: Defaults, Min/max handling, accessors.") {
|
||||
REQUIRE(test_field.textctrl()->GetValue() == "0.0");
|
||||
}
|
||||
}
|
||||
WHEN("disable() is called") {
|
||||
test_field.slider()->Enable();
|
||||
test_field.textctrl()->Enable();
|
||||
test_field.textctrl()->SetEditable(true);
|
||||
|
||||
test_field.disable();
|
||||
THEN("Internal slider is disabled.") {
|
||||
REQUIRE(test_field.slider()->IsEnabled() == false);
|
||||
}
|
||||
THEN("Internal textctrl is disabled.") {
|
||||
REQUIRE(test_field.textctrl()->IsEnabled() == false);
|
||||
REQUIRE(test_field.textctrl()->IsEditable() == false);
|
||||
}
|
||||
}
|
||||
WHEN("enable() is called") {
|
||||
test_field.slider()->Disable();
|
||||
test_field.textctrl()->Disable();
|
||||
test_field.textctrl()->SetEditable(false);
|
||||
|
||||
test_field.enable();
|
||||
THEN("Internal slider is enabled.") {
|
||||
REQUIRE(test_field.slider()->IsEnabled() == true);
|
||||
}
|
||||
THEN("Internal textctrl is enabled.") {
|
||||
REQUIRE(test_field.textctrl()->IsEnabled() == true);
|
||||
REQUIRE(test_field.textctrl()->IsEditable() == true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A UI Slider with scale of 1") {
|
||||
@ -98,6 +126,7 @@ SCENARIO( "UI_Slider: Defaults, Min/max handling, accessors.") {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO( "UI_Slider: Event handlers") {
|
||||
wxTestableFrame* old = dynamic_cast<wxTestableFrame*>(wxTheApp->GetTopWindow());
|
||||
old->Destroy();
|
||||
|
Loading…
x
Reference in New Issue
Block a user