diff --git a/resources/icons/check_off.svg b/resources/icons/check_off.svg
new file mode 100644
index 0000000000..f28cba5ea4
--- /dev/null
+++ b/resources/icons/check_off.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/check_off_disabled.svg b/resources/icons/check_off_disabled.svg
new file mode 100644
index 0000000000..492a88ea83
--- /dev/null
+++ b/resources/icons/check_off_disabled.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/check_off_focused.svg b/resources/icons/check_off_focused.svg
new file mode 100644
index 0000000000..3fb1ab9bc2
--- /dev/null
+++ b/resources/icons/check_off_focused.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/check_on.svg b/resources/icons/check_on.svg
new file mode 100644
index 0000000000..62c23441a9
--- /dev/null
+++ b/resources/icons/check_on.svg
@@ -0,0 +1,4 @@
+
diff --git a/resources/icons/check_on_disabled.svg b/resources/icons/check_on_disabled.svg
new file mode 100644
index 0000000000..2c00ecfa59
--- /dev/null
+++ b/resources/icons/check_on_disabled.svg
@@ -0,0 +1,4 @@
+
diff --git a/resources/icons/check_on_focused.svg b/resources/icons/check_on_focused.svg
new file mode 100644
index 0000000000..6b4e7935e1
--- /dev/null
+++ b/resources/icons/check_on_focused.svg
@@ -0,0 +1,4 @@
+
diff --git a/resources/icons/checked.svg b/resources/icons/checked.svg
new file mode 100644
index 0000000000..88747cb95d
--- /dev/null
+++ b/resources/icons/checked.svg
@@ -0,0 +1,4 @@
+
diff --git a/resources/icons/drop_down.svg b/resources/icons/drop_down.svg
new file mode 100644
index 0000000000..3354ddc295
--- /dev/null
+++ b/resources/icons/drop_down.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/spin_dec.svg b/resources/icons/spin_dec.svg
new file mode 100644
index 0000000000..889ad9ce23
--- /dev/null
+++ b/resources/icons/spin_dec.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/spin_dec_act.svg b/resources/icons/spin_dec_act.svg
new file mode 100644
index 0000000000..a9924d8235
--- /dev/null
+++ b/resources/icons/spin_dec_act.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/spin_inc.svg b/resources/icons/spin_inc.svg
new file mode 100644
index 0000000000..cf6b3a6998
--- /dev/null
+++ b/resources/icons/spin_inc.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/spin_inc_act.svg b/resources/icons/spin_inc_act.svg
new file mode 100644
index 0000000000..e052bb7644
--- /dev/null
+++ b/resources/icons/spin_inc_act.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/toggle_off.svg b/resources/icons/toggle_off.svg
new file mode 100644
index 0000000000..4a7925a155
--- /dev/null
+++ b/resources/icons/toggle_off.svg
@@ -0,0 +1,5 @@
+
diff --git a/resources/icons/toggle_on.svg b/resources/icons/toggle_on.svg
new file mode 100644
index 0000000000..caae9478be
--- /dev/null
+++ b/resources/icons/toggle_on.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index 426cc53309..4bf4b4a2cd 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -104,6 +104,9 @@ void AppConfig::set_defaults()
if (get("tabs_as_menu").empty())
set("tabs_as_menu", "0");
+
+ if (get("suppress_round_corners").empty())
+ set("suppress_round_corners", "1");
#endif // _WIN32
// remove old 'use_legacy_opengl' parameter from this config, if present
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 8f9900bbf2..5eee8dd7e4 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -256,6 +256,29 @@ set(SLIC3R_GUI_SOURCES
GUI/DesktopIntegrationDialog.hpp
GUI/HintNotification.cpp
GUI/HintNotification.hpp
+ GUI/Widgets/BitmapToggleButton.cpp
+ GUI/Widgets/BitmapToggleButton.hpp
+ GUI/Widgets/Button.cpp
+ GUI/Widgets/Button.hpp
+ GUI/Widgets/CheckBox.cpp
+ GUI/Widgets/CheckBox.hpp
+ GUI/Widgets/ComboBox.cpp
+ GUI/Widgets/ComboBox.hpp
+ GUI/Widgets/DropDown.cpp
+ GUI/Widgets/DropDown.hpp
+ GUI/Widgets/StateColor.cpp
+ GUI/Widgets/StateColor.hpp
+ GUI/Widgets/StateHandler.cpp
+ GUI/Widgets/StateHandler.hpp
+ GUI/Widgets/StaticBox.cpp
+ GUI/Widgets/StaticBox.hpp
+ GUI/Widgets/SpinInput.cpp
+ GUI/Widgets/SpinInput.hpp
+ GUI/Widgets/SwitchButton.cpp
+ GUI/Widgets/SwitchButton.hpp
+ GUI/Widgets/TextInput.cpp
+ GUI/Widgets/TextInput.hpp
+ GUI/Widgets/UIColors.hpp
GUI/FileArchiveDialog.cpp
GUI/FileArchiveDialog.hpp
GUI/Downloader.cpp
diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp
index 10f7277309..98b2889aa1 100644
--- a/src/slic3r/GUI/BitmapCache.cpp
+++ b/src/slic3r/GUI/BitmapCache.cpp
@@ -414,6 +414,8 @@ wxBitmapBundle* BitmapCache::from_svg(const std::string& bitmap_name, unsigned t
if (!new_color.empty())
replaces["\"#ED6B21\""] = "\"" + new_color + "\"";
+ replaces["\"#ButtonBG\""] = dark_mode ? "\"#4E4E4E\"" : "\"#828282\"";
+
std::string str;
nsvgGetDataFromFileWithReplace(Slic3r::var(bitmap_name + ".svg").c_str(), str, replaces);
if (str.empty())
diff --git a/src/slic3r/GUI/BitmapComboBox.cpp b/src/slic3r/GUI/BitmapComboBox.cpp
index 465eb4822b..2c50ab8cf7 100644
--- a/src/slic3r/GUI/BitmapComboBox.cpp
+++ b/src/slic3r/GUI/BitmapComboBox.cpp
@@ -66,10 +66,11 @@ BitmapComboBox::BitmapComboBox(wxWindow* parent,
int n/* = 0*/,
const wxString choices[]/* = NULL*/,
long style/* = 0*/) :
- wxBitmapComboBox(parent, id, value, pos, size, n, choices, style)
+// wxBitmapComboBox(parent, id, value, pos, size, n, choices, style)
+ ::ComboBox(parent, id, value, pos, size, n, choices, style | DD_NO_CHECK_ICON)
{
SetFont(Slic3r::GUI::wxGetApp().normal_font());
-#ifdef _WIN32
+#if 0 //#ifdef _WIN32
// Workaround for ignoring CBN_EDITCHANGE events, which are processed after the content of the combo box changes, so that
// the index of the item inside CBN_EDITCHANGE may no more be valid.
EnableTextChangedEvents(false);
@@ -79,11 +80,12 @@ BitmapComboBox::BitmapComboBox(wxWindow* parent,
#endif /* _WIN32 */
}
+#if 0
BitmapComboBox::~BitmapComboBox()
{
}
-#ifdef _WIN32
+//#ifdef _WIN32
int BitmapComboBox::Append(const wxString& item)
{
diff --git a/src/slic3r/GUI/BitmapComboBox.hpp b/src/slic3r/GUI/BitmapComboBox.hpp
index 07031f6bf2..e1398ec041 100644
--- a/src/slic3r/GUI/BitmapComboBox.hpp
+++ b/src/slic3r/GUI/BitmapComboBox.hpp
@@ -8,6 +8,8 @@
#include
#include
+#include "Widgets/ComboBox.hpp"
+
#include "GUI_Utils.hpp"
// ---------------------------------
@@ -17,7 +19,8 @@ namespace Slic3r {
namespace GUI {
// BitmapComboBox used to presets list on Sidebar and Tabs
-class BitmapComboBox : public wxBitmapComboBox
+//class BitmapComboBox : public wxBitmapComboBox
+class BitmapComboBox : public ::ComboBox
{
public:
BitmapComboBox(wxWindow* parent,
@@ -28,6 +31,7 @@ BitmapComboBox(wxWindow* parent,
int n = 0,
const wxString choices[] = NULL,
long style = 0);
+#if 0
~BitmapComboBox();
#ifdef _WIN32
@@ -40,7 +44,7 @@ BitmapComboBox(wxWindow* parent,
protected:
-#ifdef _WIN32
+//#ifdef _WIN32
bool MSWOnDraw(WXDRAWITEMSTRUCT* item) override;
void DrawBackground_(wxDC& dc, const wxRect& rect, int WXUNUSED(item), int flags) const;
public:
diff --git a/src/slic3r/GUI/ButtonsDescription.cpp b/src/slic3r/GUI/ButtonsDescription.cpp
index 105dbe777d..08d1cb76c8 100644
--- a/src/slic3r/GUI/ButtonsDescription.cpp
+++ b/src/slic3r/GUI/ButtonsDescription.cpp
@@ -78,7 +78,7 @@ wxBitmapBundle * ModePaletteComboBox::get_bmp(const std::vector &pa
// Create the bitmap with color bars.
std::vector bmps;
for (const auto& color : palette) {
- bmps.emplace_back(get_bmp_bundle("mode", icon_height, color));
+ bmps.emplace_back(get_bmp_bundle("mode", icon_height, icon_height, color));
bmps.emplace_back(get_empty_bmp_bundle(wxOSX ? 5 : 6, icon_height));
}
bmp_bndl = bitmap_cache().insert_bndl(bitmap_key, bmps);
diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.cpp b/src/slic3r/GUI/ExtruderSequenceDialog.cpp
index ca2fee15e6..1268b3595f 100644
--- a/src/slic3r/GUI/ExtruderSequenceDialog.cpp
+++ b/src/slic3r/GUI/ExtruderSequenceDialog.cpp
@@ -22,6 +22,7 @@
#include "MainFrame.hpp"
#include "BitmapComboBox.hpp"
+#include "Widgets/CheckBox.hpp"
namespace Slic3r {
namespace GUI {
@@ -165,7 +166,7 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
intervals_box_sizer->Add(m_intervals_grid_sizer, 0, wxLEFT, em);
option_sizer->Add(intervals_box_sizer, 0, wxEXPAND);
- m_random_sequence = new wxCheckBox(this, wxID_ANY, _L("Random sequence"));
+ m_random_sequence = new ::CheckBox(this, _L("Random sequence"));
m_random_sequence->SetValue(m_sequence.random_sequence);
m_random_sequence->SetToolTip(_L("If enabled, random sequence of the selected extruders will be used."));
m_random_sequence->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) {
@@ -173,7 +174,7 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
m_color_repetition->Enable(m_sequence.random_sequence);
});
- m_color_repetition = new wxCheckBox(this, wxID_ANY, _L("Allow next color repetition"));
+ m_color_repetition = new ::CheckBox(this, _L("Allow next color repetition"));
m_color_repetition->SetValue(m_sequence.color_repetition);
m_color_repetition->SetToolTip(_L("If enabled, a repetition of the next random color will be allowed."));
m_color_repetition->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) {m_sequence.color_repetition = e.IsChecked(); });
diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.hpp b/src/slic3r/GUI/ExtruderSequenceDialog.hpp
index 1c986682c9..61cd057425 100644
--- a/src/slic3r/GUI/ExtruderSequenceDialog.hpp
+++ b/src/slic3r/GUI/ExtruderSequenceDialog.hpp
@@ -10,7 +10,7 @@
class wxTextCtrl;
class wxFlexGridSizer;
-class wxCheckBox;
+class CheckBox;
namespace Slic3r {
namespace GUI {
@@ -27,8 +27,8 @@ class ExtruderSequenceDialog: public DPIDialog
wxTextCtrl* m_interval_by_layers {nullptr};
wxTextCtrl* m_interval_by_mm {nullptr};
- wxCheckBox* m_random_sequence {nullptr};
- wxCheckBox* m_color_repetition{nullptr};
+ CheckBox* m_random_sequence {nullptr};
+ CheckBox* m_color_repetition{nullptr};
wxFlexGridSizer* m_intervals_grid_sizer {nullptr};
wxFlexGridSizer* m_extruders_grid_sizer {nullptr};
diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index c93a831927..9a8c0287c3 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -28,6 +28,8 @@
#include "MsgDialog.hpp"
#include "BitmapComboBox.hpp"
+#include "Widgets/ComboBox.hpp"
+
#ifdef __WXOSX__
#define wxOSX true
#else
@@ -102,8 +104,6 @@ Field::~Field()
void Field::PostInitialize()
{
- auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
-
switch (m_opt.type)
{
case coPercents:
@@ -488,10 +488,7 @@ void TextCtrl::BUILD() {
}
long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER;
-#ifdef _WIN32
- style |= wxBORDER_SIMPLE;
-#endif
- auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style);
+ auto temp = new text_ctrl(m_parent, text_value, "", "", wxDefaultPosition, size, style);
if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double)temp->GetSize().GetHeight()/m_em_unit;
temp->SetFont(m_opt.is_code ?
@@ -503,9 +500,6 @@ void TextCtrl::BUILD() {
// Only disable background refresh for single line input fields, as they are completely painted over by the edit control.
// This does not apply to the multi-line edit field, where the last line and a narrow frame around the text is not cleared.
temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
-#ifdef __WXOSX__
- temp->OSXDisableAllSmartSubstitutions();
-#endif // __WXOSX__
temp->SetToolTip(get_tooltip_text(text_value));
@@ -562,7 +556,7 @@ bool TextCtrl::value_was_changed()
return true;
boost::any val = m_value;
- wxString ret_str = static_cast(window)->GetValue();
+ wxString ret_str = static_cast(window)->GetValue();
// update m_value!
// ret_str might be changed inside get_value_by_opt_type
get_value_by_opt_type(ret_str);
@@ -593,11 +587,11 @@ bool TextCtrl::value_was_changed()
void TextCtrl::propagate_value()
{
- wxString val = dynamic_cast(window)->GetValue();
+ wxString val = dynamic_cast(window)->GetValue();
if (m_opt.nullable && val != na_value())
m_last_meaningful_value = val;
- if (!is_defined_input_value(window, m_opt.type) )
+ if (!is_defined_input_value(window, m_opt.type) )
// on_kill_focus() cause a call of OptionsGroup::reload_config(),
// Thus, do it only when it's really needed (when undefined value was input)
on_kill_focus();
@@ -611,14 +605,14 @@ void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/)
const bool m_is_na_val = boost::any_cast(value) == na_value();
if (!m_is_na_val)
m_last_meaningful_value = value;
- dynamic_cast(window)->SetValue(m_is_na_val ? na_value() : boost::any_cast(value));
+ dynamic_cast(window)->SetValue(m_is_na_val ? na_value() : boost::any_cast(value));
}
else
- dynamic_cast(window)->SetValue(boost::any_cast(value));
+ dynamic_cast(window)->SetValue(boost::any_cast(value));
m_disable_change_event = false;
if (!change_event) {
- wxString ret_str = static_cast(window)->GetValue();
+ wxString ret_str = static_cast(window)->GetValue();
/* Update m_value to correct work of next value_was_changed().
* But after checking of entered value, don't fix the "incorrect" value and don't show a warning message,
* just clear m_value in this case.
@@ -629,19 +623,19 @@ void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/)
void TextCtrl::set_last_meaningful_value()
{
- dynamic_cast(window)->SetValue(boost::any_cast(m_last_meaningful_value));
+ dynamic_cast(window)->SetValue(boost::any_cast(m_last_meaningful_value));
propagate_value();
}
void TextCtrl::set_na_value()
{
- dynamic_cast(window)->SetValue(na_value());
+ dynamic_cast(window)->SetValue(na_value());
propagate_value();
}
boost::any& TextCtrl::get_value()
{
- wxString ret_str = static_cast(window)->GetValue();
+ wxString ret_str = static_cast(window)->GetValue();
// update m_value
get_value_by_opt_type(ret_str);
@@ -659,8 +653,11 @@ void TextCtrl::msw_rescale()
size.SetHeight(lround(opt_height*m_em_unit));
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
- if (size != wxDefaultSize)
- {
+ if (size != wxDefaultSize) {
+ if (::TextInput* text_input = dynamic_cast<::TextInput*>(window)) {
+ text_input->SetCtrlSize(size);
+ return;
+ }
wxTextCtrl* field = dynamic_cast(window);
if (parent_is_custom_ctrl)
field->SetSize(size);
@@ -670,8 +667,8 @@ void TextCtrl::msw_rescale()
}
-void TextCtrl::enable() { dynamic_cast(window)->Enable(); dynamic_cast(window)->SetEditable(true); }
-void TextCtrl::disable() { dynamic_cast(window)->Disable(); dynamic_cast(window)->SetEditable(false); }
+void TextCtrl::enable() { dynamic_cast(window)->Enable(); }
+void TextCtrl::disable() { dynamic_cast(window)->Disable();}
#ifdef __WXGTK__
void TextCtrl::change_field_value(wxEvent& event)
@@ -682,10 +679,71 @@ void TextCtrl::change_field_value(wxEvent& event)
};
#endif //__WXGTK__
+
+wxWindow* CheckBox::GetNewWin(wxWindow* parent, const wxString& label /*= wxEmptyString*/)
+{
+ if (wxGetApp().suppress_round_corners())
+ return new ::CheckBox(parent, label);
+
+ return new ::SwitchButton(parent, label);
+}
+
+void CheckBox::SetValue(wxWindow* win, bool value)
+{
+ if (wxGetApp().suppress_round_corners()) {
+ if (::CheckBox* ch_b = dynamic_cast<::CheckBox*>(win))
+ ch_b->SetValue(value);
+ }
+ else {
+ if (::SwitchButton* ch_b = dynamic_cast<::SwitchButton*>(win))
+ ch_b->SetValue(value);
+ }
+}
+
+bool CheckBox::GetValue(wxWindow* win)
+{
+ if (wxGetApp().suppress_round_corners())
+ return dynamic_cast<::CheckBox*>(win)->GetValue();
+
+ return dynamic_cast<::SwitchButton*>(win)->GetValue();
+}
+
+void CheckBox::Rescale(wxWindow* win)
+{
+ if (wxGetApp().suppress_round_corners())
+ dynamic_cast<::CheckBox*>(win)->Rescale();
+ else
+ dynamic_cast<::SwitchButton*>(win)->Rescale();
+}
+
+void CheckBox::SysColorChanged(wxWindow* win)
+{
+ if (!wxGetApp().suppress_round_corners())
+ dynamic_cast<::SwitchButton*>(win)->SysColorChange();
+}
+
+void CheckBox::SetValue(bool value)
+{
+ if (wxGetApp().suppress_round_corners())
+ dynamic_cast<::CheckBox*>(window)->SetValue(value);
+ else
+ dynamic_cast<::SwitchButton*>(window)->SetValue(value);
+}
+
+bool CheckBox::GetValue()
+{
+ if (wxGetApp().suppress_round_corners())
+ return dynamic_cast<::CheckBox*>(window)->GetValue();
+
+ return dynamic_cast<::SwitchButton*>(window)->GetValue();
+}
+
void CheckBox::BUILD() {
auto size = wxSize(wxDefaultSize);
- if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
- if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
+ if (m_opt.height >= 0)
+ size.SetHeight(m_opt.height*m_em_unit);
+ if (m_opt.width >= 0)
+ size.SetWidth(m_opt.width*m_em_unit);
bool check_value = m_opt.type == coBool ?
m_opt.default_value->getBool() : m_opt.type == coBools ?
@@ -695,21 +753,29 @@ void CheckBox::BUILD() {
m_last_meaningful_value = static_cast(check_value);
// Set Label as a string of at least one space simbol to correct system scaling of a CheckBox
- auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size);
- temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
- if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
- temp->SetValue(check_value);
- if (m_opt.readonly) temp->Disable();
+ window = GetNewWin(m_parent);
+ wxGetApp().UpdateDarkUI(window);
+ window->SetFont(wxGetApp().normal_font());
+ if (!wxOSX)
+ window->SetBackgroundStyle(wxBG_STYLE_PAINT);
+ if (m_opt.readonly)
+ window->Disable();
- temp->Bind(wxEVT_CHECKBOX, ([this](wxCommandEvent e) {
+ SetValue(check_value);
+
+ window->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent e) {
m_is_na_val = false;
on_change_field();
- }), temp->GetId());
+ });
- temp->SetToolTip(get_tooltip_text(check_value ? "true" : "false"));
+ window->SetToolTip(get_tooltip_text(check_value ? "true" : "false"));
+}
- // recast as a wxWindow to fit the calling convention
- window = dynamic_cast(temp);
+void CheckBox::set_value(const bool value, bool change_event/* = false*/)
+{
+ m_disable_change_event = !change_event;
+ SetValue(value);
+ m_disable_change_event = false;
}
void CheckBox::set_value(const boost::any& value, bool change_event)
@@ -719,10 +785,10 @@ void CheckBox::set_value(const boost::any& value, bool change_event)
m_is_na_val = boost::any_cast(value) == ConfigOptionBoolsNullable::nil_value();
if (!m_is_na_val)
m_last_meaningful_value = value;
- dynamic_cast(window)->SetValue(m_is_na_val ? false : boost::any_cast(value) != 0);
+ SetValue(m_is_na_val ? false : boost::any_cast(value) != 0);
}
else
- dynamic_cast(window)->SetValue(boost::any_cast(value));
+ SetValue(boost::any_cast(value));
m_disable_change_event = false;
}
@@ -730,7 +796,7 @@ void CheckBox::set_last_meaningful_value()
{
if (m_opt.nullable) {
m_is_na_val = false;
- dynamic_cast(window)->SetValue(boost::any_cast(m_last_meaningful_value) != 0);
+ SetValue(boost::any_cast(m_last_meaningful_value) != 0);
on_change_field();
}
}
@@ -739,15 +805,13 @@ void CheckBox::set_na_value()
{
if (m_opt.nullable) {
m_is_na_val = true;
- dynamic_cast(window)->SetValue(false);
on_change_field();
}
}
boost::any& CheckBox::get_value()
{
-// boost::any m_value;
- bool value = dynamic_cast(window)->GetValue();
+ bool value = GetValue();
if (m_opt.type == coBool)
m_value = static_cast(value);
else
@@ -761,6 +825,23 @@ void CheckBox::msw_rescale()
window->SetInitialSize(window->GetBestSize());
}
+void CheckBox::sys_color_changed()
+{
+ Field::sys_color_changed();
+ if (auto switch_btn = dynamic_cast<::SwitchButton*>(window))
+ switch_btn->SysColorChange();
+}
+
+void CheckBox::enable()
+{
+ window->Enable();
+}
+
+void CheckBox::disable()
+{
+ window->Disable();
+}
+
void SpinCtrl::BUILD() {
auto size = wxSize(def_width() * m_em_unit, wxDefaultCoord);
@@ -804,11 +885,9 @@ void SpinCtrl::BUILD() {
? (int)0 : (int)m_opt.min;
const int max_val = m_opt.max < FLT_MAX ? (int)m_opt.max : INT_MAX;
- auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size,
+ auto temp = new ::SpinInput(m_parent, text_value, "", wxDefaultPosition, size,
wxTE_PROCESS_ENTER | wxSP_ARROW_KEYS
-#ifdef _WIN32
- | wxBORDER_SIMPLE
-#endif
+
, min_val, max_val, default_value);
#ifdef __WXGTK3__
@@ -823,14 +902,7 @@ void SpinCtrl::BUILD() {
if (m_opt.height < 0 && parent_is_custom_ctrl)
opt_height = (double)temp->GetSize().GetHeight() / m_em_unit;
-// XXX: On OS X the wxSpinCtrl widget is made up of two subwidgets, unfortunatelly
-// the kill focus event is not propagated to the encompassing widget,
-// so we need to bind it on the inner text widget instead. (Ugh.)
-#ifdef __WXOSX__
- temp->GetText()->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e)
-#else
temp->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e)
-#endif
{
e.Skip();
if (bEnterPressed) {
@@ -849,29 +921,16 @@ void SpinCtrl::BUILD() {
propagate_value();
bEnterPressed = true;
}), temp->GetId());
+ temp->SetToolTip(get_tooltip_text(text_value));
- temp->Bind(wxEVT_TEXT, ([this, temp](wxCommandEvent e)
- {
-// # On OSX / Cocoa, wxSpinCtrl::GetValue() doesn't return the new value
-// # when it was changed from the text control, so the on_change callback
-// # gets the old one, and on_kill_focus resets the control to the old value.
-// # As a workaround, we get the new value from $event->GetString and store
-// # here temporarily so that we can return it from get_value()
-
- long value;
- const bool parsed = e.GetString().ToLong(&value);
- if (!parsed || value < INT_MIN || value > INT_MAX)
+ temp->Bind(wxEVT_TEXT, [this, temp](wxCommandEvent e) {
+ long value;
+ if (!e.GetString().ToLong(&value))
+ return;
+ if (value < INT_MIN || value > INT_MAX)
tmp_value = UNDEF_VALUE;
else {
tmp_value = std::min(std::max((int)value, temp->GetMin()), temp->GetMax());
-#ifdef __WXOSX__
- // Forcibly set the input value for SpinControl, since the value
- // inserted from the keyboard or clipboard is not updated under OSX
- temp->SetValue(tmp_value);
- // But in SetValue() is executed m_text_ctrl->SelectAll(), so
- // discard this selection and set insertion point to the end of string
- temp->GetText()->SetInsertionPointEnd();
-#else
// update value for the control only if it was changed in respect to the Min/max values
if (tmp_value != (int)value) {
temp->SetValue(tmp_value);
@@ -880,11 +939,8 @@ void SpinCtrl::BUILD() {
int pos = std::to_string(tmp_value).length();
temp->SetSelection(pos, pos);
}
-#endif
}
- }), temp->GetId());
-
- temp->SetToolTip(get_tooltip_text(text_value));
+ }, temp->GetId());
// recast as a wxWindow to fit the calling convention
window = dynamic_cast(temp);
@@ -898,35 +954,35 @@ void SpinCtrl::set_value(const boost::any& value, bool change_event/* = false*/)
if (m_opt.nullable) {
const bool m_is_na_val = tmp_value == ConfigOptionIntsNullable::nil_value();
if (m_is_na_val)
- dynamic_cast(window)->SetValue(na_value(true));
+ dynamic_cast<::SpinInput*>(window)->SetValue(na_value(true));
else {
m_last_meaningful_value = value;
- dynamic_cast(window)->SetValue(tmp_value);
+ dynamic_cast<::SpinInput*>(window)->SetValue(tmp_value);
}
}
else
- dynamic_cast(window)->SetValue(tmp_value);
+ dynamic_cast<::SpinInput*>(window)->SetValue(tmp_value);
m_disable_change_event = false;
}
void SpinCtrl::set_last_meaningful_value()
{
const int val = boost::any_cast(m_last_meaningful_value);
- dynamic_cast(window)->SetValue(val);
+ dynamic_cast<::SpinInput*>(window)->SetValue(val);
tmp_value = val;
propagate_value();
}
void SpinCtrl::set_na_value()
{
- dynamic_cast(window)->SetValue(na_value(true));
+ dynamic_cast<::SpinInput*>(window)->SetValue(na_value(true));
m_value = ConfigOptionIntsNullable::nil_value();
propagate_value();
}
boost::any& SpinCtrl::get_value()
{
- wxSpinCtrl* spin = static_cast(window);
+ ::SpinInput* spin = static_cast<::SpinInput*>(window);
if (spin->GetTextValue() == na_value(true))
return m_value;
@@ -949,7 +1005,7 @@ void SpinCtrl::propagate_value()
#ifdef __WXOSX__
// check input value for minimum
if (m_opt.min > 0 && tmp_value < m_opt.min) {
- wxSpinCtrl* spin = static_cast(window);
+ ::SpinInput* spin = static_cast<::SpinInput*>(window);
spin->SetValue(m_opt.min);
spin->GetText()->SetInsertionPointEnd();
}
@@ -962,13 +1018,16 @@ void SpinCtrl::msw_rescale()
{
Field::msw_rescale();
- wxSpinCtrl* field = dynamic_cast(window);
+ auto field = dynamic_cast<::SpinInput*>(window);
if (parent_is_custom_ctrl)
field->SetSize(wxSize(def_width() * m_em_unit, lround(opt_height * m_em_unit)));
else
field->SetMinSize(wxSize(def_width() * m_em_unit, int(1.9f*field->GetFont().GetPixelSize().y)));
}
+#if 1
+using choice_ctrl = ::ComboBox;
+#else
#ifdef __WXOSX__
static_assert(wxMAJOR_VERSION >= 3, "Use of wxBitmapComboBox on Settings Tabs requires wxWidgets 3.0 and newer");
using choice_ctrl = wxBitmapComboBox;
@@ -979,6 +1038,7 @@ using choice_ctrl = BitmapComboBox;
using choice_ctrl = wxComboBox;
#endif
#endif // __WXOSX__
+#endif
void Choice::BUILD() {
wxSize size(def_width_wider() * m_em_unit, wxDefaultCoord);
@@ -989,10 +1049,10 @@ void Choice::BUILD() {
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined
&& m_opt.gui_type != ConfigOptionDef::GUIType::select_close) {
m_is_editable = true;
- temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER);
+ temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER | DD_NO_CHECK_ICON);
}
else {
-#ifdef __WXOSX__
+#if 0 //#ifdef __WXOSX__
/* wxBitmapComboBox with wxCB_READONLY style return NULL for GetTextCtrl(),
* so ToolTip doesn't shown.
* Next workaround helps to solve this problem
@@ -1001,7 +1061,7 @@ void Choice::BUILD() {
temp->SetTextCtrlStyle(wxTE_READONLY);
temp->Create(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr);
#else
- temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY);
+ temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY | DD_NO_CHECK_ICON);
#endif //__WXOSX__
}
@@ -1458,18 +1518,15 @@ void PointCtrl::BUILD()
wxString Y = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None);
long style = wxTE_PROCESS_ENTER;
-#ifdef _WIN32
- style |= wxBORDER_SIMPLE;
-#endif
- x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, style);
- y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, style);
+ x_textctrl = new text_ctrl(m_parent, X, "", "", wxDefaultPosition, field_size, style);
+ y_textctrl = new text_ctrl(m_parent, Y, "", "", wxDefaultPosition, field_size, style);
if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double)x_textctrl->GetSize().GetHeight() / m_em_unit;
x_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font());
- x_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT);
+ if (!wxOSX) x_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT);
y_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font());
- y_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT);
+ if (!wxOSX) y_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT);
auto static_text_x = new wxStaticText(m_parent, wxID_ANY, "x : ");
auto static_text_y = new wxStaticText(m_parent, wxID_ANY, " y : ");
@@ -1527,7 +1584,7 @@ void PointCtrl::sys_color_changed()
#endif
}
-bool PointCtrl::value_was_changed(wxTextCtrl* win)
+bool PointCtrl::value_was_changed(text_ctrl* win)
{
if (m_value.empty())
return true;
@@ -1539,7 +1596,7 @@ bool PointCtrl::value_was_changed(wxTextCtrl* win)
return boost::any_cast(m_value) != boost::any_cast(val);
}
-void PointCtrl::propagate_value(wxTextCtrl* win)
+void PointCtrl::propagate_value(text_ctrl* win)
{
if (win->GetValue().empty())
on_kill_focus();
diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp
index bdc8199136..2d9625e499 100644
--- a/src/slic3r/GUI/Field.hpp
+++ b/src/slic3r/GUI/Field.hpp
@@ -25,6 +25,10 @@
#include "GUI.hpp"
#include "wxExtensions.hpp"
+#include "Widgets/CheckBox.hpp"
+#include "Widgets/SwitchButton.hpp"
+#include "Widgets/SpinInput.hpp"
+#include "Widgets/TextInput.hpp"
#ifdef __WXMSW__
#define wxMSW true
@@ -294,6 +298,8 @@ inline bool is_window_field(const t_field& obj) { return !is_bad_field(obj) && o
/// Covenience function to determine whether this field is a valid sizer field.
inline bool is_sizer_field(const t_field& obj) { return !is_bad_field(obj) && obj->getSizer() != nullptr; }
+using text_ctrl = ::TextInput; //wxTextCtrl
+
class TextCtrl : public Field {
using Field::Field;
#ifdef __WXGTK__
@@ -314,7 +320,7 @@ public:
void set_value(const std::string& value, bool change_event = false) {
m_disable_change_event = !change_event;
- dynamic_cast(window)->SetValue(wxString(value));
+ dynamic_cast(window)->SetValue(wxString(value));
m_disable_change_event = false;
}
void set_value(const boost::any& value, bool change_event = false) override;
@@ -338,24 +344,31 @@ public:
CheckBox(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~CheckBox() {}
+ static wxWindow* GetNewWin(wxWindow* parent, const wxString& label = wxEmptyString);
+ static void SetValue(wxWindow* win, bool value);
+ static bool GetValue(wxWindow* win);
+ static void Rescale(wxWindow* win);
+ static void SysColorChanged(wxWindow* win);
+
wxWindow* window{ nullptr };
void BUILD() override;
- void set_value(const bool value, bool change_event = false) {
- m_disable_change_event = !change_event;
- dynamic_cast(window)->SetValue(value);
- m_disable_change_event = false;
- }
+ void set_value(const bool value, bool change_event = false);
void set_value(const boost::any& value, bool change_event = false) override;
void set_last_meaningful_value() override;
void set_na_value() override;
boost::any& get_value() override;
void msw_rescale() override;
+ void sys_color_changed() override;
- void enable() override { dynamic_cast(window)->Enable(); }
- void disable() override { dynamic_cast(window)->Disable(); }
+ void enable() override;
+ void disable() override;
wxWindow* getWindow() override { return window; }
+
+private:
+ void SetValue(bool value);
+ bool GetValue();
};
class SpinCtrl : public Field {
@@ -377,20 +390,32 @@ public:
/*
void set_value(const std::string& value, bool change_event = false) {
m_disable_change_event = !change_event;
- dynamic_cast(window)->SetValue(value);
+ dynamic_cast<::SpinInput*>(window)->SetValue(value);
m_disable_change_event = false;
}
+ void set_value(const boost::any& value, bool change_event = false) override {
+ m_disable_change_event = !change_event;
+ tmp_value = boost::any_cast(value);
+ m_value = value;
+ dynamic_cast<::SpinInput*>(window)->SetValue(tmp_value);
+ m_disable_change_event = false;
+ }
*/
void set_value(const boost::any& value, bool change_event = false) override;
void set_last_meaningful_value() override;
void set_na_value() override;
boost::any& get_value() override;
-
+/*
+ boost::any& get_value() override {
+ int value = static_cast<::SpinInput*>(window)->GetValue();
+ return m_value = value;
+ }
+*/
void msw_rescale() override;
- void enable() override { dynamic_cast(window)->Enable(); }
- void disable() override { dynamic_cast(window)->Disable(); }
+ void enable() override { dynamic_cast<::SpinInput*>(window)->Enable(); }
+ void disable() override { dynamic_cast<::SpinInput*>(window)->Disable(); }
wxWindow* getWindow() override { return window; }
};
@@ -466,13 +491,13 @@ public:
~PointCtrl();
wxSizer* sizer{ nullptr };
- wxTextCtrl* x_textctrl{ nullptr };
- wxTextCtrl* y_textctrl{ nullptr };
+ text_ctrl* x_textctrl{ nullptr };
+ text_ctrl* y_textctrl{ nullptr };
void BUILD() override;
- bool value_was_changed(wxTextCtrl* win);
+ bool value_was_changed(text_ctrl* win);
// Propagate value from field to the OptionGroupe and Config after kill_focus/ENTER
- void propagate_value(wxTextCtrl* win);
+ void propagate_value(text_ctrl* win);
void set_value(const Vec2d& value, bool change_event = false);
void set_value(const boost::any& value, bool change_event = false) override;
boost::any& get_value() override;
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 41745e843c..04c2c5c506 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -1756,6 +1756,11 @@ bool GUI_App::tabs_as_menu() const
return app_config->get_bool("tabs_as_menu"); // || dark_mode();
}
+bool GUI_App::suppress_round_corners() const
+{
+ return app_config->get("suppress_round_corners") == "1";
+}
+
wxSize GUI_App::get_min_size() const
{
return wxSize(76*m_em_unit, 49 * m_em_unit);
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 039818e012..fb4e1d87ab 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -248,6 +248,7 @@ public:
const wxFont& link_font() { return m_link_font; }
int em_unit() const { return m_em_unit; }
bool tabs_as_menu() const;
+ bool suppress_round_corners() const;
wxSize get_min_size() const;
float toolbar_icon_scale(const bool is_limited = false) const;
void set_auto_toolbar_icon_scale(float scale) const;
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
index 0b7534b1d6..19b8b3e108 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
@@ -25,6 +25,8 @@
#include
#include "slic3r/Utils/FixModelByWin10.hpp"
+#include "Widgets/CheckBox.hpp"
+
// For special mirroring in manipulation gizmo
#include "Gizmos/GLGizmosManager.hpp"
#include "Gizmos/GLGizmoEmboss.hpp"
@@ -77,7 +79,7 @@ static choice_ctrl* create_word_local_combo(wxWindow *parent)
wxSize size(15 * wxGetApp().em_unit(), -1);
choice_ctrl* temp = nullptr;
-#ifdef __WXOSX__
+#if 0//def __WXOSX__
/* wxBitmapComboBox with wxCB_READONLY style return NULL for GetTextCtrl(),
* so ToolTip doesn't shown.
* Next workaround helps to solve this problem
@@ -86,7 +88,7 @@ static choice_ctrl* create_word_local_combo(wxWindow *parent)
temp->SetTextCtrlStyle(wxTE_READONLY);
temp->Create(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr);
#else
- temp = new choice_ctrl(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY | wxBORDER_SIMPLE);
+ temp = new choice_ctrl(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY/* | wxBORDER_SIMPLE*/);
#endif //__WXOSX__
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
@@ -137,7 +139,7 @@ void msw_rescale_word_local_combo(choice_ctrl* combo)
static void set_font_and_background_style(wxWindow* win, const wxFont& font)
{
win->SetFont(font);
- win->SetBackgroundStyle(wxBG_STYLE_PAINT);
+ if (!wxOSX) win->SetBackgroundStyle(wxBG_STYLE_PAINT);
}
static const wxString axes_color_text[] = { "#990000", "#009900", "#000099" };
@@ -495,16 +497,16 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
});
m_main_grid_sizer->Add(m_reset_skew_button);
- m_check_inch = new wxCheckBox(parent, wxID_ANY, _L("Inches"));
+ m_check_inch = CheckBox::GetNewWin(parent, _L("Inches"));
m_check_inch->SetFont(wxGetApp().normal_font());
- m_check_inch->SetValue(m_imperial_units);
+ CheckBox::SetValue(m_check_inch, m_imperial_units);
m_check_inch->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) {
- wxGetApp().app_config->set("use_inches", m_check_inch->GetValue() ? "1" : "0");
+ wxGetApp().app_config->set("use_inches", CheckBox::GetValue(m_check_inch) ? "1" : "0");
wxGetApp().sidebar().update_ui_from_settings();
});
- m_main_grid_sizer->Add(m_check_inch, 1, wxEXPAND);
+ m_main_grid_sizer->Add(m_check_inch);
m_og->activate();
m_og->sizer->Clear(true);
@@ -533,7 +535,7 @@ void ObjectManipulation::Show(const bool show)
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
bool show_world_local_combo = wxGetApp().get_mode() != comSimple && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier());
if (selection.is_single_volume_or_modifier() && m_word_local_combo->GetCount() < 3) {
-#ifdef __linux__
+#if 0//def __linux__
m_word_local_combo->Insert(coordinate_type_str(ECoordinatesType::Local), 2);
#else
m_word_local_combo->Insert(coordinate_type_str(ECoordinatesType::Local), wxNullBitmap, 2);
@@ -615,7 +617,7 @@ void ObjectManipulation::update_ui_from_settings()
update(3/*meSize*/, m_new_size);
}
}
- m_check_inch->SetValue(m_imperial_units);
+ CheckBox::SetValue(m_check_inch, m_imperial_units);
if (m_use_colors != wxGetApp().app_config->get_bool("color_mapinulation_panel")) {
m_use_colors = wxGetApp().app_config->get_bool("color_mapinulation_panel");
@@ -1199,6 +1201,8 @@ void ObjectManipulation::sys_color_changed()
wxGetApp().UpdateDarkUI(m_word_local_combo);
wxGetApp().UpdateDarkUI(m_check_inch);
#endif
+
+ CheckBox::SysColorChanged(m_check_inch);
for (ManipulationEditor* editor : m_editors)
editor->sys_color_changed(this);
@@ -1227,19 +1231,12 @@ static const char axes[] = { 'x', 'y', 'z' };
ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
const std::string& opt_key,
int axis) :
- wxTextCtrl(parent->parent(), wxID_ANY, wxEmptyString, wxDefaultPosition,
- wxSize((wxOSX ? 5 : 6)*int(wxGetApp().em_unit()), wxDefaultCoord), wxTE_PROCESS_ENTER
-#ifdef _WIN32
- | wxBORDER_SIMPLE
-#endif
- ),
+ ::TextInput(parent->parent(), "", "", "", wxDefaultPosition,
+ wxSize(int(5.8 * wxGetApp().em_unit()), wxDefaultCoord), wxTE_PROCESS_ENTER),
m_opt_key(opt_key),
m_axis(axis)
{
set_font_and_background_style(this, wxGetApp().normal_font());
-#ifdef __WXOSX__
- this->OSXDisableAllSmartSubstitutions();
-#endif // __WXOSX__
if (parent->use_colors()) {
this->SetBackgroundColour(wxColour(axes_color_back[axis]));
this->SetForegroundColour(*wxBLACK);
@@ -1295,8 +1292,7 @@ ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
void ManipulationEditor::msw_rescale()
{
- const int em = wxGetApp().em_unit();
- SetMinSize(wxSize(5 * em, wxDefaultCoord));
+ SetCtrlSize(wxSize(int(5.8 * wxGetApp().em_unit()), wxDefaultCoord));
}
void ManipulationEditor::sys_color_changed(ObjectManipulation* parent)
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp
index 8952f7248d..96e006a6ba 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp
@@ -13,6 +13,9 @@
#include "libslic3r/Point.hpp"
#include
+#include "Widgets/ComboBox.hpp"
+#include "Widgets/TextInput.hpp"
+
#ifdef __WXOSX__
class wxBitmapComboBox;
#else
@@ -21,15 +24,17 @@ class wxComboBox;
class wxStaticText;
class LockButton;
class wxStaticBitmap;
-class wxCheckBox;
namespace Slic3r {
-namespace GUI {
+ namespace GUI {
#ifdef _WIN32
-class BitmapComboBox;
+ class BitmapComboBox;
#endif
+#if 1
+ using choice_ctrl = ::ComboBox;
+#else
#ifdef __WXOSX__
static_assert(wxMAJOR_VERSION >= 3, "Use of wxBitmapComboBox on Manipulation panel requires wxWidgets 3.0 and newer");
using choice_ctrl = wxBitmapComboBox;
@@ -40,11 +45,12 @@ class BitmapComboBox;
using choice_ctrl = wxComboBox;
#endif
#endif // __WXOSX__
+#endif
class Selection;
class ObjectManipulation;
-class ManipulationEditor : public wxTextCtrl
+class ManipulationEditor : public ::TextInput
{
std::string m_opt_key;
int m_axis;
@@ -128,7 +134,7 @@ private:
ScalableButton* m_reset_skew_button{ nullptr };
ScalableButton* m_drop_to_bed_button{ nullptr };
- wxCheckBox* m_check_inch {nullptr};
+ wxWindow* m_check_inch {nullptr};
std::array m_mirror_buttons;
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 1ee12c1fb5..c6bb44851c 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -732,7 +732,7 @@ void MainFrame::init_tabpanel()
#ifdef _MSW_DARK_MODE
if (wxGetApp().tabs_as_menu()) {
m_tabpanel = new wxSimplebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
- wxGetApp().UpdateDarkUI(m_tabpanel);
+// wxGetApp().UpdateDarkUI(m_tabpanel);
}
else
m_tabpanel = new Notebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME, true);
@@ -740,6 +740,8 @@ void MainFrame::init_tabpanel()
m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
#endif
+ wxGetApp().UpdateDarkUI(m_tabpanel);
+
#ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
#endif
@@ -1107,7 +1109,6 @@ void MainFrame::on_sys_color_changed()
wxGetApp().update_ui_colours_from_appconfig();
#ifdef __WXMSW__
wxGetApp().UpdateDarkUI(m_tabpanel);
- // m_statusbar->update_dark_ui();
#ifdef _MSW_DARK_MODE
// update common mode sizer
if (!wxGetApp().tabs_as_menu())
@@ -2311,7 +2312,7 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
this->SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
#else
this->SetFont(wxGetApp().normal_font());
- this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+// this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__
// Load the icon either from the exe, or from the ico file.
diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp
index bf919a6f8f..b8c4151ad0 100644
--- a/src/slic3r/GUI/MsgDialog.cpp
+++ b/src/slic3r/GUI/MsgDialog.cpp
@@ -27,6 +27,8 @@
#include "slic3r/GUI/MainFrame.hpp"
#include "GUI_App.hpp"
+#include "Widgets/CheckBox.hpp"
+
namespace Slic3r {
namespace GUI {
@@ -268,7 +270,7 @@ RichMessageDialog::RichMessageDialog(wxWindow* parent,
{
add_msg_content(this, content_sizer, get_wraped_wxString(message));
- m_checkBox = new wxCheckBox(this, wxID_ANY, m_checkBoxText);
+ m_checkBox = new ::CheckBox(this, m_checkBoxText);
wxGetApp().UpdateDarkUI(m_checkBox);
m_checkBox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { m_checkBoxValue = m_checkBox->GetValue(); });
diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp
index cde5928425..96c7703755 100644
--- a/src/slic3r/GUI/MsgDialog.hpp
+++ b/src/slic3r/GUI/MsgDialog.hpp
@@ -17,7 +17,7 @@
#include
class wxBoxSizer;
-class wxCheckBox;
+class CheckBox;
class wxStaticBitmap;
namespace Slic3r {
@@ -132,7 +132,7 @@ public:
// Generic rich message dialog, used intead of wxRichMessageDialog
class RichMessageDialog : public MsgDialog
{
- wxCheckBox* m_checkBox{ nullptr };
+ CheckBox* m_checkBox{ nullptr };
wxString m_checkBoxText;
bool m_checkBoxValue{ false };
diff --git a/src/slic3r/GUI/OG_CustomCtrl.cpp b/src/slic3r/GUI/OG_CustomCtrl.cpp
index ad38d68435..fb1cfc2138 100644
--- a/src/slic3r/GUI/OG_CustomCtrl.cpp
+++ b/src/slic3r/GUI/OG_CustomCtrl.cpp
@@ -686,7 +686,8 @@ wxCoord OG_CustomCtrl::CtrlLine::draw_mode_bmp(wxDC& dc, wxCoord v_pos)
return ctrl->m_h_gap;
ConfigOptionMode mode = og_line.get_options()[0].opt.mode;
- wxBitmapBundle* bmp = get_bmp_bundle("mode", wxOSX ? 10 : 12, wxGetApp().get_mode_btn_color(mode));
+ int pix_cnt = wxOSX ? 10 : 12;
+ wxBitmapBundle* bmp = get_bmp_bundle("mode", pix_cnt, pix_cnt, wxGetApp().get_mode_btn_color(mode));
wxCoord y_draw = v_pos + lround((height - get_bitmap_size(bmp, ctrl).GetHeight()) / 2);
if (og_line.get_options().front().opt.gui_type != ConfigOptionDef::GUIType::legend)
diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp
index 0fa39cd106..bf6c8571a3 100644
--- a/src/slic3r/GUI/OptionsGroup.cpp
+++ b/src/slic3r/GUI/OptionsGroup.cpp
@@ -288,6 +288,7 @@ void OptionsGroup::activate_line(Line& line)
if (!custom_ctrl && m_use_custom_ctrl) {
custom_ctrl = new OG_CustomCtrl(is_legend_line || !staticbox ? this->parent() : static_cast(this->stb), this);
+ wxGetApp().UpdateDarkUI(custom_ctrl);
if (is_legend_line)
sizer->Add(custom_ctrl, 0, wxEXPAND | wxLEFT, wxOSX ? 0 : 10);
else
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 0bd5f21312..ddbe95a156 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -141,6 +141,8 @@
#include "libslic3r/CustomGCode.hpp"
#include "libslic3r/Platform.hpp"
+#include "Widgets/CheckBox.hpp"
+
using boost::optional;
namespace fs = boost::filesystem;
using Slic3r::_3DScene;
@@ -800,7 +802,7 @@ Sidebar::Sidebar(Plater *parent)
wxGetApp().UpdateDarkUI(this);
wxGetApp().UpdateDarkUI(p->scrolled);
#else
- SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+// SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
#endif
@@ -6112,7 +6114,7 @@ ProjectDropDialog::ProjectDropDialog(const std::string& filename)
main_sizer->Add(stb_sizer, 1, wxEXPAND | wxRIGHT | wxLEFT, 10);
wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
- wxCheckBox* check = new wxCheckBox(this, wxID_ANY, _L("Don't show again"));
+ ::CheckBox* check = new ::CheckBox(this, _L("Don't show again"));
check->Bind(wxEVT_CHECKBOX, [](wxCommandEvent& evt) {
wxGetApp().app_config->set("show_drop_project_dialog", evt.IsChecked() ? "0" : "1");
});
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index 6fb2f23258..1e884e3fc0 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -212,7 +212,7 @@ void PreferencesDialog::build()
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this);
#else
- SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+ //SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
const wxFont& font = wxGetApp().normal_font();
SetFont(font);
@@ -223,7 +223,7 @@ void PreferencesDialog::build()
tabs = new Notebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME | wxNB_DEFAULT);
#else
tabs = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL |wxNB_NOPAGETHEME | wxNB_DEFAULT );
- tabs->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+// tabs->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
// Add "General" tab
@@ -527,6 +527,13 @@ void PreferencesDialog::build()
m_optgroup_gui->append_separator();
+ append_bool_option(m_optgroup_gui, "suppress_round_corners",
+ L("Suppress round corners for controls (experimental)"),
+ L("If enabled, Settings Tabs will be placed as menu items. If disabled, old UI will be used."),
+ app_config->get("suppress_round_corners") == "1");
+
+ m_optgroup_gui->append_separator();
+
append_bool_option(m_optgroup_gui, "show_hints",
L("Show \"Tip of the day\" notification after start"),
L("If enabled, useful hints are displayed at startup."),
@@ -706,7 +713,7 @@ void PreferencesDialog::accept(wxEvent&)
#endif // __linux__
}
- std::vector options_to_recreate_GUI = { "no_defaults", "tabs_as_menu", "sys_menu_enabled", "font_size" };
+ std::vector options_to_recreate_GUI = { "no_defaults", "tabs_as_menu", "sys_menu_enabled", "font_size", "suppress_round_corners" };
for (const std::string& option : options_to_recreate_GUI) {
if (m_values.find(option) != m_values.end()) {
diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp
index e31e47647b..224752bdff 100644
--- a/src/slic3r/GUI/PresetComboBoxes.cpp
+++ b/src/slic3r/GUI/PresetComboBoxes.cpp
@@ -45,6 +45,8 @@
#include "PhysicalPrinterDialog.hpp"
#include "MsgDialog.hpp"
+#include "Widgets/ComboBox.hpp"
+
// A workaround for a set of issues related to text fitting into gtk widgets:
// See e.g.: https://github.com/prusa3d/PrusaSlicer/issues/4584
#if defined(__WXGTK20__) || defined(__WXGTK3__)
@@ -437,6 +439,7 @@ void PresetComboBox::update_from_bundle()
void PresetComboBox::msw_rescale()
{
m_em_unit = em_unit(this);
+ ::ComboBox::Rescale();
}
void PresetComboBox::sys_color_changed()
diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp
index 951e01b691..79b7ed70d4 100644
--- a/src/slic3r/GUI/Search.cpp
+++ b/src/slic3r/GUI/Search.cpp
@@ -525,9 +525,9 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
wxBoxSizer* check_sizer = new wxBoxSizer(wxHORIZONTAL);
- check_category = new wxCheckBox(this, wxID_ANY, _L("Category"));
+ check_category = new ::CheckBox(this, _L("Category"));
if (GUI::wxGetApp().is_localized())
- check_english = new wxCheckBox(this, wxID_ANY, _L("Search in English"));
+ check_english = new ::CheckBox(this, _L("Search in English"));
wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL);
GUI::wxGetApp().UpdateDarkUI(static_cast(this->FindWindowById(wxID_CANCEL, this)));
diff --git a/src/slic3r/GUI/Search.hpp b/src/slic3r/GUI/Search.hpp
index 99c3b319e7..571448d492 100644
--- a/src/slic3r/GUI/Search.hpp
+++ b/src/slic3r/GUI/Search.hpp
@@ -24,6 +24,9 @@
#include "OptionsGroup.hpp"
#include "libslic3r/Preset.hpp"
+#include "Widgets/CheckBox.hpp"
+
+class CheckBox;
namespace Slic3r {
@@ -162,8 +165,8 @@ class SearchDialog : public GUI::DPIDialog
wxTextCtrl* search_line { nullptr };
wxDataViewCtrl* search_list { nullptr };
SearchListModel* search_list_model { nullptr };
- wxCheckBox* check_category { nullptr };
- wxCheckBox* check_english { nullptr };
+ CheckBox* check_category { nullptr };
+ CheckBox* check_english { nullptr };
OptionsSearcher* searcher { nullptr };
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 4d279ebbeb..5199e45220 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -69,6 +69,8 @@
#include "MsgDialog.hpp"
#include "Notebook.hpp"
+#include "Widgets/CheckBox.hpp"
+
#ifdef WIN32
#include
#endif // WIN32
@@ -82,7 +84,11 @@ Tab::Tab(wxBookCtrlBase* parent, const wxString& title, Preset::Type type) :
Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL/*, name*/);
this->SetFont(Slic3r::GUI::wxGetApp().normal_font());
+#ifdef __WXMSW__
wxGetApp().UpdateDarkUI(this);
+#else
+ SetBackgroundColour(parent->GetBackgroundColour());
+#endif
m_compatible_printers.type = Preset::TYPE_PRINTER;
m_compatible_printers.key_list = "compatible_printers";
@@ -167,8 +173,6 @@ void Tab::create_preset_tab()
}
});
- auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
-
//buttons
m_scaled_buttons.reserve(6);
m_scaled_buttons.reserve(2);
@@ -422,10 +426,6 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str
}
// Initialize the page.
PageShp page(new Page(m_page_view, title, icon_idx));
-// page->SetBackgroundStyle(wxBG_STYLE_SYSTEM);
-#ifdef __WINDOWS__
-// page->SetDoubleBuffered(true);
-#endif //__WINDOWS__
if (!is_extruder_pages)
m_pages.push_back(page);
@@ -961,6 +961,11 @@ void Tab::msw_rescale()
m_presets_choice->msw_rescale();
m_treectrl->SetMinSize(wxSize(20 * m_em_unit, -1));
+ if (m_compatible_printers.checkbox)
+ CheckBox::Rescale(m_compatible_printers.checkbox);
+ if (m_compatible_prints.checkbox)
+ CheckBox::Rescale(m_compatible_prints.checkbox);
+
// rescale options_groups
if (m_active_page)
m_active_page->msw_rescale();
@@ -1939,21 +1944,23 @@ void TabFilament::create_line_with_near_label_widget(ConfigOptionsGroupShp optgr
else
line = optgroup->create_single_option_line(optgroup->get_option(opt_key));
- line.near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(optgroup), opt_key, opt_index](wxWindow* parent) {
- wxCheckBox* check_box = new wxCheckBox(parent, wxID_ANY, "");
- check_box->Bind(wxEVT_CHECKBOX, [optgroup_wk, opt_key, opt_index](wxCommandEvent& evt) {
- const bool is_checked = evt.IsChecked();
- if (auto optgroup_sh = optgroup_wk.lock(); optgroup_sh) {
- if (Field *field = optgroup_sh->get_fieldc(opt_key, opt_index); field != nullptr) {
- field->toggle(is_checked);
- if (is_checked)
- field->set_last_meaningful_value();
- else
- field->set_na_value();
+ line.near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(optgroup), opt_key, opt_index](wxWindow* parent) {
+ wxWindow* check_box = CheckBox::GetNewWin(parent);
+ wxGetApp().UpdateDarkUI(check_box);
+
+ check_box->Bind(wxEVT_CHECKBOX, [optgroup_wk, opt_key, opt_index](wxCommandEvent& evt) {
+ const bool is_checked = evt.IsChecked();
+ if (auto optgroup_sh = optgroup_wk.lock(); optgroup_sh) {
+ if (Field *field = optgroup_sh->get_fieldc(opt_key, opt_index); field != nullptr) {
+ field->toggle(is_checked);
+ if (is_checked)
+ field->set_last_meaningful_value();
+ else
+ field->set_na_value();
+ }
}
- }
- }, check_box->GetId());
+ });
m_overrides_options[opt_key] = check_box;
return check_box;
@@ -1969,7 +1976,7 @@ void TabFilament::update_line_with_near_label_widget(ConfigOptionsGroupShp optgr
m_overrides_options[opt_key]->Enable(is_checked);
is_checked &= !m_config->option(opt_key)->is_nil();
- m_overrides_options[opt_key]->SetValue(is_checked);
+ CheckBox::SetValue(m_overrides_options[opt_key], is_checked);
Field* field = optgroup->get_fieldc(opt_key, opt_index);
if (field != nullptr)
@@ -2038,6 +2045,16 @@ void TabFilament::update_filament_overrides_page()
{
bool is_checked = opt_key=="filament_retract_length" ? true : have_retract_length;
update_line_with_near_label_widget(optgroup, opt_key, extruder_idx, is_checked);
+/*
+ m_overrides_options[opt_key]->Enable(is_checked);
+
+ is_checked &= !m_config->option(opt_key)->is_nil();
+ CheckBox::SetValue(m_overrides_options[opt_key], is_checked);
+
+ Field* field = optgroup->get_fieldc(opt_key, extruder_idx);
+ if (field != nullptr)
+ field->toggle(is_checked);
+*/
}
og_it = std::find_if(page->m_optgroups.begin(), page->m_optgroups.end(), [](const ConfigOptionsGroupShp og) { return og->title == "Retraction when tool is disabled"; });
@@ -2399,6 +2416,9 @@ void TabFilament::clear_pages()
m_volumetric_speed_description_line = nullptr;
m_cooling_description_line = nullptr;
+
+ for (auto& over_opt : m_overrides_options)
+ over_opt.second = nullptr;
}
void TabFilament::msw_rescale()
@@ -2406,7 +2426,6 @@ void TabFilament::msw_rescale()
for (const auto& over_opt : m_overrides_options)
if (wxWindow* win = over_opt.second)
win->SetInitialSize(win->GetBestSize());
-
Tab::msw_rescale();
}
@@ -2416,8 +2435,16 @@ void TabFilament::sys_color_changed()
update_extruder_combobox();
Tab::sys_color_changed();
+
+ for (const auto& over_opt : m_overrides_options)
+ if (wxWindow* check_box = over_opt.second) {
+ wxGetApp().UpdateDarkUI(check_box);
+ CheckBox::SysColorChanged(check_box);
+ }
}
+
+
void TabFilament::load_current_preset()
{
const std::string& selected_filament_name = m_presets->get_selected_preset_name();
@@ -4463,9 +4490,9 @@ void Tab::create_line_with_widget(ConfigOptionsGroup* optgroup, const std::strin
// Return a callback to create a Tab widget to mark the preferences as compatible / incompatible to the current printer.
wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &deps)
{
- deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All")));
+ deps.checkbox = CheckBox::GetNewWin(parent, _L("All"));
deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font());
- wxGetApp().UpdateDarkUI(deps.checkbox, false, true);
+ wxGetApp().UpdateDarkUI(deps.checkbox);
deps.btn = new ScalableButton(parent, wxID_ANY, "printer", format_wxstr(" %s %s", _L("Set"), dots),
wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT);
deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
@@ -4477,11 +4504,12 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
deps.checkbox->Bind(wxEVT_CHECKBOX, ([this, &deps](wxCommandEvent e)
{
- deps.btn->Enable(! deps.checkbox->GetValue());
+ const bool is_checked = CheckBox::GetValue(deps.checkbox);
+ deps.btn->Enable(!is_checked);
// All printers have been made compatible with this preset.
- if (deps.checkbox->GetValue())
+ if (is_checked)
this->load_key_value(deps.key_list, std::vector {});
- this->get_field(deps.key_condition)->toggle(deps.checkbox->GetValue());
+ this->get_field(deps.key_condition)->toggle(is_checked);
this->update_changed_ui();
}) );
@@ -4524,7 +4552,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
for (auto idx : selections)
value.push_back(presets[idx].ToUTF8().data());
if (value.empty()) {
- deps.checkbox->SetValue(1);
+ CheckBox::SetValue(deps.checkbox, true);
deps.btn->Disable();
}
// All depending_presets have been made compatible with this preset.
@@ -4646,11 +4674,7 @@ void SubstitutionManager::add_substitution( int substitution_id,
auto top_sizer = new wxBoxSizer(wxHORIZONTAL);
auto add_text_editor = [substitution_id, top_sizer, this](const wxString& value, int opt_pos, int proportion) {
- auto editor = new wxTextCtrl(m_parent, wxID_ANY, value, wxDefaultPosition, wxSize(15 * m_em, wxDefaultCoord), wxTE_PROCESS_ENTER
-#ifdef _WIN32
- | wxBORDER_SIMPLE
-#endif
- );
+ auto editor = new ::TextInput(m_parent, value, "", "", wxDefaultPosition, wxSize(15 * m_em, wxDefaultCoord), wxTE_PROCESS_ENTER);
editor->SetFont(wxGetApp().normal_font());
wxGetApp().UpdateDarkUI(editor);
@@ -4679,39 +4703,39 @@ void SubstitutionManager::add_substitution( int substitution_id,
bool whole_word = strchr(params.c_str(), 'w') != nullptr || strchr(params.c_str(), 'W') != nullptr;
bool match_single_line = strchr(params.c_str(), 's') != nullptr || strchr(params.c_str(), 'S') != nullptr;
- auto chb_regexp = new wxCheckBox(m_parent, wxID_ANY, _L("Regular expression"));
- chb_regexp->SetValue(regexp);
+ auto chb_regexp = CheckBox::GetNewWin(m_parent, _L("Regular expression"));
+ CheckBox::SetValue(chb_regexp, regexp);
params_sizer->Add(chb_regexp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, m_em);
- auto chb_case_insensitive = new wxCheckBox(m_parent, wxID_ANY, _L("Case insensitive"));
- chb_case_insensitive->SetValue(case_insensitive);
+ auto chb_case_insensitive = CheckBox::GetNewWin(m_parent, _L("Case insensitive"));
+ CheckBox::SetValue(chb_case_insensitive, case_insensitive);
params_sizer->Add(chb_case_insensitive, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, m_em);
- auto chb_whole_word = new wxCheckBox(m_parent, wxID_ANY, _L("Whole word"));
- chb_whole_word->SetValue(whole_word);
+ auto chb_whole_word = CheckBox::GetNewWin(m_parent, _L("Whole word"));
+ CheckBox::SetValue(chb_whole_word, whole_word);
params_sizer->Add(chb_whole_word, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, m_em);
- auto chb_match_single_line = new wxCheckBox(m_parent, wxID_ANY, _L("Match single line"));
- chb_match_single_line->SetValue(match_single_line);
+ auto chb_match_single_line = CheckBox::GetNewWin(m_parent, _L("Match single line"));
+ CheckBox::SetValue(chb_match_single_line, match_single_line);
chb_match_single_line->Show(regexp);
m_chb_match_single_lines.emplace_back(chb_match_single_line);
params_sizer->Add(chb_match_single_line, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, m_em);
- for (wxCheckBox* chb : std::initializer_list{ chb_regexp, chb_case_insensitive, chb_whole_word, chb_match_single_line }) {
+ for (wxWindow* chb : std::initializer_list{ chb_regexp, chb_case_insensitive, chb_whole_word, chb_match_single_line }) {
chb->SetFont(wxGetApp().normal_font());
chb->Bind(wxEVT_CHECKBOX, [this, substitution_id, chb_regexp, chb_case_insensitive, chb_whole_word, chb_match_single_line](wxCommandEvent e) {
std::string value = std::string();
- if (chb_regexp->GetValue())
+ if (CheckBox::GetValue(chb_regexp))
value += "r";
- if (chb_case_insensitive->GetValue())
+ if (CheckBox::GetValue(chb_case_insensitive))
value += "i";
- if (chb_whole_word->GetValue())
+ if (CheckBox::GetValue(chb_whole_word))
value += "w";
- if (chb_match_single_line->GetValue())
+ if (CheckBox::GetValue(chb_match_single_line))
value += "s";
- chb_match_single_line->Show(chb_regexp->GetValue());
+ chb_match_single_line->Show(CheckBox::GetValue(chb_regexp));
m_grid_sizer->Layout();
edit_substitution(substitution_id, 2, value);
@@ -4978,7 +5002,7 @@ void Tab::compatible_widget_reload(PresetDependencies &deps)
bool has_any = ! m_config->option(deps.key_list)->values.empty();
has_any ? deps.btn->Enable() : deps.btn->Disable();
- deps.checkbox->SetValue(! has_any);
+ CheckBox::SetValue(deps.checkbox, !has_any);
field->toggle(! has_any);
}
diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp
index 1b8dc99bc5..69ac11f95c 100644
--- a/src/slic3r/GUI/Tab.hpp
+++ b/src/slic3r/GUI/Tab.hpp
@@ -51,6 +51,8 @@
#include "OptionsGroup.hpp"
#include "libslic3r/Preset.hpp"
+class CheckBox;
+
namespace Slic3r {
namespace GUI {
@@ -202,7 +204,7 @@ protected:
struct PresetDependencies {
Preset::Type type = Preset::TYPE_INVALID;
- wxCheckBox *checkbox = nullptr;
+ wxWindow *checkbox = nullptr;
ScalableButton *btn = nullptr;
std::string key_list; // "compatible_printers"
std::string key_condition;
@@ -473,7 +475,7 @@ class TabFilament : public Tab
void create_extruder_combobox();
void update_volumetric_flow_preset_hints();
- std::map m_overrides_options;
+ std::map m_overrides_options;
public:
TabFilament(wxBookCtrlBase* parent) :
Tab(parent, _(L("Filament Settings")), Slic3r::Preset::TYPE_FILAMENT) {}
diff --git a/src/slic3r/GUI/Widgets/BitmapToggleButton.cpp b/src/slic3r/GUI/Widgets/BitmapToggleButton.cpp
new file mode 100644
index 0000000000..4531446665
--- /dev/null
+++ b/src/slic3r/GUI/Widgets/BitmapToggleButton.cpp
@@ -0,0 +1,47 @@
+#include "BitmapToggleButton.hpp"
+
+#include
+
+BitmapToggleButton::BitmapToggleButton(wxWindow* parent, const wxString& label, wxWindowID id)
+{
+#ifdef __linux__
+ long style = wxBORDER_NONE | wxBU_EXACTFIT;
+ if (label.IsEmpty())
+ style = style | wxBU_NOTEXT;
+ // Call Create() from wxToggleButton instead of wxBitmapToggleButton to allow add Label text under Linux
+ wxToggleButton::Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style);
+#else
+ wxBitmapToggleButton::Create(parent, id, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxBU_EXACTFIT);
+ if (!label.IsEmpty())
+ SetLabel(label);
+#endif
+
+#ifdef __WXMSW__
+ if (parent) {
+ SetBackgroundColour(parent->GetBackgroundColour());
+ SetForegroundColour(parent->GetForegroundColour());
+ }
+#elif __linux__
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+#endif
+
+ Bind(wxEVT_TOGGLEBUTTON, [this](auto& e) {
+ update();
+
+ wxCommandEvent evt(wxEVT_CHECKBOX);
+ evt.SetInt(int(GetValue()));
+ wxPostEvent(this, evt);
+
+ e.Skip();
+ });
+}
+
+void BitmapToggleButton::update_size()
+{
+#ifdef __linux__
+ if (GetLabel().IsEmpty())
+ SetSize(GetBitmap().GetSize());
+ else
+#endif
+ SetSize(GetBestSize());
+}
diff --git a/src/slic3r/GUI/Widgets/BitmapToggleButton.hpp b/src/slic3r/GUI/Widgets/BitmapToggleButton.hpp
new file mode 100644
index 0000000000..db653e03fb
--- /dev/null
+++ b/src/slic3r/GUI/Widgets/BitmapToggleButton.hpp
@@ -0,0 +1,17 @@
+#ifndef slic3r_GUI_BitmapToggleButton_hpp_
+#define slic3r_GUI_BitmapToggleButton_hpp_
+
+#include
+
+class BitmapToggleButton : public wxBitmapToggleButton
+{
+ virtual void update() = 0;
+
+public:
+ BitmapToggleButton(wxWindow * parent = NULL, const wxString& label = wxEmptyString, wxWindowID id = wxID_ANY);
+
+protected:
+ void update_size();
+};
+
+#endif // !slic3r_GUI_BitmapToggleButton_hpp_
diff --git a/src/slic3r/GUI/Widgets/Button.cpp b/src/slic3r/GUI/Widgets/Button.cpp
index fa1dc15ee2..10e2819b05 100644
--- a/src/slic3r/GUI/Widgets/Button.cpp
+++ b/src/slic3r/GUI/Widgets/Button.cpp
@@ -1,7 +1,8 @@
#include "Button.hpp"
-#include "Label.hpp"
#include
+#include
+#include
BEGIN_EVENT_TABLE(Button, StaticBox)
@@ -36,23 +37,20 @@ Button::Button()
std::make_pair(*wxBLACK, (int) StateColor::Normal));
}
-Button::Button(wxWindow* parent, wxString text, wxString icon, long style, int iconSize)
+Button::Button(wxWindow* parent, wxString text, wxString icon, long style, wxSize iconSize/* = wxSize(16, 16)*/)
: Button()
{
Create(parent, text, icon, style, iconSize);
}
-bool Button::Create(wxWindow* parent, wxString text, wxString icon, long style, int iconSize)
+bool Button::Create(wxWindow* parent, wxString text, wxString icon, long style, wxSize iconSize/* = wxSize(16, 16)*/)
{
StaticBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style);
state_handler.attach({&text_color});
state_handler.update_binds();
- //BBS set default font
- SetFont(Label::Body_14);
wxWindow::SetLabel(text);
if (!icon.IsEmpty()) {
- //BBS set button icon default size to 20
- this->active_icon = ScalableBitmap(this, icon.ToStdString(), iconSize > 0 ? iconSize : 20);
+ this->active_icon = ScalableBitmap(this, icon.ToStdString(), iconSize);
}
messureSize();
return true;
@@ -68,8 +66,7 @@ void Button::SetLabel(const wxString& label)
void Button::SetIcon(const wxString& icon)
{
if (!icon.IsEmpty()) {
- //BBS set button icon default size to 20
- this->active_icon = ScalableBitmap(this, icon.ToStdString(), this->active_icon.px_cnt());
+ this->active_icon = ScalableBitmap(this, icon.ToStdString(), this->active_icon.px_size());
}
else
{
@@ -81,8 +78,7 @@ void Button::SetIcon(const wxString& icon)
void Button::SetInactiveIcon(const wxString &icon)
{
if (!icon.IsEmpty()) {
- // BBS set button icon default size to 20
- this->inactive_icon = ScalableBitmap(this, icon.ToStdString(), this->active_icon.px_cnt());
+ this->inactive_icon = ScalableBitmap(this, icon.ToStdString(), this->active_icon.px_size());
} else {
this->inactive_icon = ScalableBitmap();
}
@@ -129,12 +125,12 @@ void Button::SetCanFocus(bool canFocus) { this->canFocus = canFocus; }
void Button::Rescale()
{
- if (this->active_icon.bmp().IsOk())
+/* if (this->active_icon.bmp().IsOk())
this->active_icon.msw_rescale();
if (this->inactive_icon.bmp().IsOk())
this->inactive_icon.msw_rescale();
-
+*/
messureSize();
}
@@ -162,6 +158,7 @@ void Button::render(wxDC& dc)
ScalableBitmap icon;
if (m_selected || ((states & (int)StateColor::State::Hovered) != 0))
+// if (m_selected || (states & (int)StateColor::State::Hovered))
icon = active_icon;
else
icon = inactive_icon;
@@ -171,7 +168,7 @@ void Button::render(wxDC& dc)
//BBS norrow size between text and icon
szContent.x += padding;
}
- szIcon = icon.GetBmpSize();
+ szIcon = icon.GetSize();
szContent.x += szIcon.x;
if (szIcon.y > szContent.y)
szContent.y = szIcon.y;
@@ -190,7 +187,7 @@ void Button::render(wxDC& dc)
wxPoint pt = rcContent.GetLeftTop();
if (icon.bmp().IsOk()) {
pt.y += (rcContent.height - szIcon.y) / 2;
- dc.DrawBitmap(icon.bmp(), pt);
+ dc.DrawBitmap(icon.get_bitmap(), pt);
//BBS norrow size between text and icon
pt.x += szIcon.x + padding;
pt.y = rcContent.y;
@@ -220,7 +217,7 @@ void Button::messureSize()
//BBS norrow size between text and icon
szContent.x += 5;
}
- wxSize szIcon = this->active_icon.GetBmpSize();
+ wxSize szIcon = this->active_icon.GetSize();
szContent.x += szIcon.x;
if (szIcon.y > szContent.y)
szContent.y = szIcon.y;
diff --git a/src/slic3r/GUI/Widgets/Button.hpp b/src/slic3r/GUI/Widgets/Button.hpp
index 43aac6b9fb..249989ddff 100644
--- a/src/slic3r/GUI/Widgets/Button.hpp
+++ b/src/slic3r/GUI/Widgets/Button.hpp
@@ -24,9 +24,9 @@ class Button : public StaticBox
public:
Button();
- Button(wxWindow* parent, wxString text, wxString icon = "", long style = 0, int iconSize = 0);
+ Button(wxWindow* parent, wxString text, wxString icon = "", long style = 0, wxSize iconSize = wxSize(16, 16));
- bool Create(wxWindow* parent, wxString text, wxString icon = "", long style = 0, int iconSize = 0);
+ bool Create(wxWindow* parent, wxString text, wxString icon = "", long style = 0, wxSize iconSize = wxSize(16, 16));
void SetLabel(const wxString& label) override;
diff --git a/src/slic3r/GUI/Widgets/CheckBox.cpp b/src/slic3r/GUI/Widgets/CheckBox.cpp
index 4ca1ca5ba0..627f1d0971 100644
--- a/src/slic3r/GUI/Widgets/CheckBox.cpp
+++ b/src/slic3r/GUI/Widgets/CheckBox.cpp
@@ -1,31 +1,25 @@
#include "CheckBox.hpp"
-#include "../wxExtensions.hpp"
+//#include "../wxExtensions.hpp"
-CheckBox::CheckBox(wxWindow* parent)
- : wxBitmapToggleButton(parent, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)
- , m_on(this, "check_on", 18)
- , m_half(this, "check_half", 18)
- , m_off(this, "check_off", 18)
- , m_on_disabled(this, "check_on_disabled", 18)
- , m_half_disabled(this, "check_half_disabled", 18)
- , m_off_disabled(this, "check_off_disabled", 18)
- , m_on_focused(this, "check_on_focused", 18)
- , m_half_focused(this, "check_half_focused", 18)
- , m_off_focused(this, "check_off_focused", 18)
+const int px_cnt = 16;
+
+CheckBox::CheckBox(wxWindow* parent, const wxString& name)
+ : BitmapToggleButton(parent, name, wxID_ANY)
+ , m_on(this, "check_on", px_cnt)
+ , m_off(this, "check_off", px_cnt)
+ , m_on_disabled(this, "check_on_disabled", px_cnt)
+ , m_off_disabled(this, "check_off_disabled", px_cnt)
+ , m_on_focused(this, "check_on_focused", px_cnt)
+ , m_off_focused(this, "check_off_focused", px_cnt)
{
- //SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
- if (parent)
- SetBackgroundColour(parent->GetBackgroundColour());
- Bind(wxEVT_TOGGLEBUTTON, [this](auto& e) { m_half_checked = false; update(); e.Skip(); });
#ifdef __WXOSX__ // State not fully implement on MacOS
Bind(wxEVT_SET_FOCUS, &CheckBox::updateBitmap, this);
Bind(wxEVT_KILL_FOCUS, &CheckBox::updateBitmap, this);
Bind(wxEVT_ENTER_WINDOW, &CheckBox::updateBitmap, this);
Bind(wxEVT_LEAVE_WINDOW, &CheckBox::updateBitmap, this);
#endif
- SetSize(m_on.GetBmpSize());
- SetMinSize(m_on.GetBmpSize());
+
update();
}
@@ -35,61 +29,59 @@ void CheckBox::SetValue(bool value)
update();
}
-void CheckBox::SetHalfChecked(bool value)
+void CheckBox::Update()
{
- m_half_checked = value;
- update();
+ update();
}
void CheckBox::Rescale()
{
- m_on.msw_rescale();
- m_half.msw_rescale();
- m_off.msw_rescale();
- m_on_disabled.msw_rescale();
- m_half_disabled.msw_rescale();
- m_off_disabled.msw_rescale();
- m_on_focused.msw_rescale();
- m_half_focused.msw_rescale();
- m_off_focused.msw_rescale();
- SetSize(m_on.GetBmpSize());
update();
}
void CheckBox::update()
{
- SetBitmapLabel((m_half_checked ? m_half : GetValue() ? m_on : m_off).bmp());
- SetBitmapDisabled((m_half_checked ? m_half_disabled : GetValue() ? m_on_disabled : m_off_disabled).bmp());
+ const bool val = GetValue();
+ const wxBitmapBundle& bmp = (val ? m_on : m_off).bmp();
+ SetBitmap(bmp);
+ SetBitmapCurrent(bmp);
+ SetBitmapDisabled((val ? m_on_disabled : m_off_disabled).bmp());
#ifdef __WXMSW__
- SetBitmapFocus((m_half_checked ? m_half_focused : GetValue() ? m_on_focused : m_off_focused).bmp());
+ SetBitmapFocus((val ? m_on_focused : m_off_focused).bmp());
#endif
- SetBitmapCurrent((m_half_checked ? m_half_focused : GetValue() ? m_on_focused : m_off_focused).bmp());
#ifdef __WXOSX__
wxCommandEvent e(wxEVT_UPDATE_UI);
updateBitmap(e);
#endif
+
+ update_size();
}
#ifdef __WXMSW__
-CheckBox::State CheckBox::GetNormalState() const { return State_Normal; }
+CheckBox::State CheckBox::GetNormalState() const
+{
+ return State_Normal;
+}
#endif
-
-#ifdef __WXOSX__
-
bool CheckBox::Enable(bool enable)
{
bool result = wxBitmapToggleButton::Enable(enable);
+
+#ifdef __WXOSX__
if (result) {
m_disable = !enable;
wxCommandEvent e(wxEVT_ACTIVATE);
updateBitmap(e);
}
+#endif
return result;
}
+#ifdef __WXOSX__
+
wxBitmap CheckBox::DoGetBitmap(State which) const
{
if (m_disable) {
diff --git a/src/slic3r/GUI/Widgets/CheckBox.hpp b/src/slic3r/GUI/Widgets/CheckBox.hpp
index 53c41b6470..727bbce9b5 100644
--- a/src/slic3r/GUI/Widgets/CheckBox.hpp
+++ b/src/slic3r/GUI/Widgets/CheckBox.hpp
@@ -2,25 +2,20 @@
#define slic3r_GUI_CheckBox_hpp_
#include "../wxExtensions.hpp"
+#include "BitmapToggleButton.hpp"
-#include
-
-class CheckBox : public wxBitmapToggleButton
+class CheckBox : public BitmapToggleButton
{
public:
- CheckBox(wxWindow * parent = NULL);
+ CheckBox(wxWindow* parent = NULL, const wxString& name = wxEmptyString);
public:
void SetValue(bool value) override;
-
- void SetHalfChecked(bool value = true);
+ void Update() override;
+ bool Enable(bool enable = true) override;
void Rescale();
-#ifdef __WXOSX__
- virtual bool Enable(bool enable = true) wxOVERRIDE;
-#endif
-
protected:
#ifdef __WXMSW__
virtual State GetNormalState() const wxOVERRIDE;
@@ -37,19 +32,14 @@ protected:
#endif
private:
- void update();
+ void update() override;
-private:
- ScalableBitmap m_on;
- ScalableBitmap m_half;
- ScalableBitmap m_off;
- ScalableBitmap m_on_disabled;
- ScalableBitmap m_half_disabled;
- ScalableBitmap m_off_disabled;
- ScalableBitmap m_on_focused;
- ScalableBitmap m_half_focused;
- ScalableBitmap m_off_focused;
- bool m_half_checked = false;
+ ScalableBitmap m_on;
+ ScalableBitmap m_off;
+ ScalableBitmap m_on_disabled;
+ ScalableBitmap m_off_disabled;
+ ScalableBitmap m_on_focused;
+ ScalableBitmap m_off_focused;
};
#endif // !slic3r_GUI_CheckBox_hpp_
diff --git a/src/slic3r/GUI/Widgets/ComboBox.cpp b/src/slic3r/GUI/Widgets/ComboBox.cpp
index 01d7d9614c..68fc6ee8c5 100644
--- a/src/slic3r/GUI/Widgets/ComboBox.cpp
+++ b/src/slic3r/GUI/Widgets/ComboBox.cpp
@@ -1,11 +1,13 @@
#include "ComboBox.hpp"
-#include "Label.hpp"
+#include "UIColors.hpp"
#include
+#include "../GUI_App.hpp"
+
BEGIN_EVENT_TABLE(ComboBox, TextInput)
-EVT_LEFT_DOWN(ComboBox::mouseDown)
+ EVT_LEFT_DOWN(ComboBox::mouseDown)
//EVT_MOUSEWHEEL(ComboBox::mouseWheelMoved)
EVT_KEY_DOWN(ComboBox::keyDown)
@@ -28,27 +30,23 @@ ComboBox::ComboBox(wxWindow * parent,
long style)
: drop(texts, icons)
{
- if (style & wxCB_READONLY)
- style |= wxRIGHT;
text_off = style & CB_NO_TEXT;
TextInput::Create(parent, "", value, (style & CB_NO_DROP_ICON) ? "" : "drop_down", pos, size,
style | wxTE_PROCESS_ENTER);
- drop.Create(this, style & DD_STYLE_MASK);
+ drop.Create(this, style);
- if (style & wxCB_READONLY) {
+ SetFont(Slic3r::GUI::wxGetApp().normal_font());
+ if (style & wxCB_READONLY)
GetTextCtrl()->Hide();
- TextInput::SetFont(Label::Body_14);
- TextInput::SetBorderColor(StateColor(std::make_pair(0xDBDBDB, (int) StateColor::Disabled),
- std::make_pair(0x00AE42, (int) StateColor::Hovered),
- std::make_pair(0xDBDBDB, (int) StateColor::Normal)));
- TextInput::SetBackgroundColor(StateColor(std::make_pair(0xF0F0F0, (int) StateColor::Disabled),
- std::make_pair(0xEDFAF2, (int) StateColor::Focused),
- std::make_pair(*wxWHITE, (int) StateColor::Normal)));
- TextInput::SetLabelColor(StateColor(std::make_pair(0x909090, (int) StateColor::Disabled),
- std::make_pair(0x262E30, (int) StateColor::Normal)));
- } else {
+ else
GetTextCtrl()->Bind(wxEVT_KEY_DOWN, &ComboBox::keyDown, this);
+
+ SetBorderColor(TextInput::GetBorderColor());
+ if (parent) {
+ SetBackgroundColour(parent->GetBackgroundColour());
+ SetForegroundColour(parent->GetForegroundColour());
}
+
drop.Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &e) {
SetSelection(e.GetInt());
e.SetEventObject(this);
@@ -75,6 +73,8 @@ void ComboBox::SetSelection(int n)
void ComboBox::Rescale()
{
+ SetFont(Slic3r::GUI::wxGetApp().normal_font());
+
TextInput::Rescale();
drop.Rescale();
}
@@ -120,27 +120,74 @@ wxString ComboBox::GetTextLabel() const
bool ComboBox::SetFont(wxFont const& font)
{
+ const bool set_drop_font = drop.SetFont(font);
if (GetTextCtrl() && GetTextCtrl()->IsShown())
- return GetTextCtrl()->SetFont(font);
- else
- return TextInput::SetFont(font);
+ return GetTextCtrl()->SetFont(font) && set_drop_font;
+ return TextInput::SetFont(font) && set_drop_font;
}
-int ComboBox::Append(const wxString &item, const wxBitmap &bitmap)
+bool ComboBox::SetBackgroundColour(const wxColour& colour)
+{
+ TextInput::SetBackgroundColour(colour);
+
+ drop.SetBackgroundColour(colour);
+ drop.SetSelectorBackgroundColor(background_color);
+
+ return true;
+}
+
+bool ComboBox::SetForegroundColour(const wxColour& colour)
+{
+ TextInput::SetForegroundColour(colour);
+
+ drop.SetTextColor(TextInput::GetTextColor());
+
+ return true;
+}
+
+void ComboBox::SetBorderColor(StateColor const& color)
+{
+ TextInput::SetBorderColor(color);
+ drop.SetBorderColor(color);
+ drop.SetSelectorBorderColor(color);
+}
+
+int ComboBox::Append(const wxString &item, const wxBitmapBundle &bitmap)
{
return Append(item, bitmap, nullptr);
}
-int ComboBox::Append(const wxString &item,
- const wxBitmap &bitmap,
- void * clientData)
+int ComboBox::Append(const wxString &item,
+ const wxBitmapBundle &bitmap,
+ void * clientData)
{
texts.push_back(item);
icons.push_back(bitmap);
datas.push_back(clientData);
types.push_back(wxClientData_None);
drop.Invalidate();
- return texts.size() - 1;
+ return int(texts.size()) - 1;
+}
+
+int ComboBox::Insert(const wxString& item,
+ const wxBitmapBundle& bitmap,
+ unsigned int pos)
+{
+ return Insert(item, bitmap, pos, nullptr);
+}
+
+int ComboBox::Insert(const wxString& item, const wxBitmapBundle& bitmap,
+ unsigned int pos, void* clientData)
+{
+ const int n = wxItemContainer::Insert(item, pos);
+ if (n != wxNOT_FOUND) {
+ texts.insert(texts.begin() + n, item);
+ icons.insert(icons.begin() + n, bitmap);
+ datas.insert(datas.begin() + n, clientData);
+ types.insert(types.begin() + n, wxClientData_None);
+ drop.Invalidate();
+ }
+ return n;
}
void ComboBox::DoClear()
@@ -174,10 +221,13 @@ void ComboBox::SetString(unsigned int n, wxString const &value)
if (n >= texts.size()) return;
texts[n] = value;
drop.Invalidate();
- if (n == drop.GetSelection()) SetLabel(value);
+ if (int(n) == drop.GetSelection()) SetLabel(value);
}
-wxBitmap ComboBox::GetItemBitmap(unsigned int n) { return icons[n]; }
+wxBitmap ComboBox::GetItemBitmap(unsigned int n)
+{
+ return icons[n].GetBitmapFor(m_parent);
+}
int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
unsigned int pos,
@@ -185,7 +235,7 @@ int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
wxClientDataType type)
{
if (pos > texts.size()) return -1;
- for (int i = 0; i < items.GetCount(); ++i) {
+ for (size_t i = 0; i < items.GetCount(); ++i) {
texts.insert(texts.begin() + pos, items[i]);
icons.insert(icons.begin() + pos, wxNullBitmap);
datas.insert(datas.begin() + pos, clientData ? clientData[i] : NULL);
@@ -193,7 +243,7 @@ int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
++pos;
}
drop.Invalidate(true);
- return pos - 1;
+ return int(pos) - 1;
}
void *ComboBox::DoGetItemClientData(unsigned int n) const { return n < texts.size() ? datas[n] : NULL; }
@@ -232,8 +282,11 @@ void ComboBox::mouseWheelMoved(wxMouseEvent &event)
void ComboBox::keyDown(wxKeyEvent& event)
{
- switch (event.GetKeyCode()) {
+ int key_code = event.GetKeyCode();
+ switch (key_code) {
+#ifndef __WXOSX__
case WXK_RETURN:
+#endif
case WXK_SPACE:
if (drop_down) {
drop.DismissAndNotify();
@@ -251,7 +304,7 @@ void ComboBox::keyDown(wxKeyEvent& event)
case WXK_RIGHT:
if ((event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_LEFT) && GetSelection() > 0) {
SetSelection(GetSelection() - 1);
- } else if ((event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_RIGHT) && GetSelection() + 1 < texts.size()) {
+ } else if ((event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_RIGHT) && GetSelection() + 1 < int(texts.size())) {
SetSelection(GetSelection() + 1);
} else {
break;
diff --git a/src/slic3r/GUI/Widgets/ComboBox.hpp b/src/slic3r/GUI/Widgets/ComboBox.hpp
index 0a8e018dce..7ba9911228 100644
--- a/src/slic3r/GUI/Widgets/ComboBox.hpp
+++ b/src/slic3r/GUI/Widgets/ComboBox.hpp
@@ -4,13 +4,13 @@
#include "TextInput.hpp"
#include "DropDown.hpp"
-#define CB_NO_DROP_ICON DD_NO_CHECK_ICON
+#define CB_NO_DROP_ICON DD_NO_DROP_ICON
#define CB_NO_TEXT DD_NO_TEXT
class ComboBox : public wxWindowWithItems
{
std::vector texts;
- std::vector icons;
+ std::vector icons;
std::vector datas;
std::vector types;
@@ -32,10 +32,18 @@ public:
virtual bool SetFont(wxFont const & font) override;
-public:
- int Append(const wxString &item, const wxBitmap &bitmap = wxNullBitmap);
+ bool SetBackgroundColour(const wxColour& colour) override;
+ bool SetForegroundColour(const wxColour& colour) override;
- int Append(const wxString &item, const wxBitmap &bitmap, void *clientData);
+ void SetBorderColor(StateColor const& color);
+
+ int Append(const wxString &item, const wxBitmapBundle &bitmap = wxNullBitmap);
+
+ int Append(const wxString &item, const wxBitmapBundle &bitmap, void *clientData);
+
+ int Insert(const wxString& item, const wxBitmapBundle& bitmap, unsigned int pos);
+ int Insert(const wxString& item, const wxBitmapBundle& bitmap,
+ unsigned int pos, void* clientData);
unsigned int GetCount() const override;
diff --git a/src/slic3r/GUI/Widgets/DropDown.cpp b/src/slic3r/GUI/Widgets/DropDown.cpp
index c0074b531d..873a734e80 100644
--- a/src/slic3r/GUI/Widgets/DropDown.cpp
+++ b/src/slic3r/GUI/Widgets/DropDown.cpp
@@ -1,7 +1,15 @@
#include "DropDown.hpp"
-#include "Label.hpp"
+#include "../GUI_App.hpp"
+#include "../OptionsGroup.hpp"
#include
+#include
+#include
+#include
+#include
+#include
+
+#include
wxDEFINE_EVENT(EVT_DISMISS, wxCommandEvent);
@@ -25,12 +33,13 @@ END_EVENT_TABLE()
*/
DropDown::DropDown(std::vector &texts,
- std::vector &icons)
+ std::vector &icons)
: texts(texts)
, icons(icons)
+ , radius(Slic3r::GUI::wxGetApp().suppress_round_corners() ? 0 : 5)
, state_handler(this)
- , border_color(0xDBDBDB)
, text_color(0x363636)
+ , border_color(0xDBDBDB)
, selector_border_color(std::make_pair(0x00AE42, (int) StateColor::Hovered),
std::make_pair(*wxWHITE, (int) StateColor::Normal))
, selector_background_color(std::make_pair(0xEDFAF2, (int) StateColor::Checked),
@@ -40,7 +49,7 @@ DropDown::DropDown(std::vector &texts,
DropDown::DropDown(wxWindow * parent,
std::vector &texts,
- std::vector &icons,
+ std::vector &icons,
long style)
: DropDown(texts, icons)
{
@@ -51,16 +60,14 @@ void DropDown::Create(wxWindow * parent,
long style)
{
wxPopupTransientWindow::Create(parent);
- SetBackgroundStyle(wxBG_STYLE_PAINT);
- SetBackgroundColour(*wxWHITE);
+ if (!wxOSX) SetBackgroundStyle(wxBG_STYLE_PAINT);
state_handler.attach({&border_color, &text_color, &selector_border_color, &selector_background_color});
state_handler.update_binds();
- if ((style & DD_NO_CHECK_ICON) == 0)
+ if (!(style & DD_NO_CHECK_ICON))
check_bitmap = ScalableBitmap(this, "checked", 16);
text_off = style & DD_NO_TEXT;
- // BBS set default font
- SetFont(Label::Body_14);
+ SetFont(parent->GetFont());
#ifdef __WXOSX__
// wxPopupTransientWindow releases mouse on idle, which may cause various problems,
// such as losting mouse move, and dismissing soon on first LEFT_DOWN event.
@@ -99,9 +106,9 @@ void DropDown::SetValue(const wxString &value)
selection = i == texts.end() ? -1 : std::distance(texts.begin(), i);
}
-void DropDown::SetCornerRadius(double radius)
+void DropDown::SetCornerRadius(double radius_in)
{
- this->radius = radius;
+ radius = radius_in;
paintNow();
}
@@ -179,6 +186,28 @@ void DropDown::paintNow()
Refresh();
}
+void DropDown::SetTransparentBG(wxDC& dc, wxWindow* win)
+{
+ const wxSize size = win->GetSize();
+ const wxPoint screen_pos = win->GetScreenPosition();
+ wxScreenDC screen_dc;
+
+#ifdef __WXMSW__
+ // Draw screen_dc to dc for transparent background
+ dc.Blit(0, 0, size.x, size.y, &screen_dc, screen_pos.x, screen_pos.y);
+#else
+ // See https://forums.wxwidgets.org/viewtopic.php?f=1&t=49318
+ wxClientDC client_dc(win);
+ client_dc.Blit(0, 0, size.x, size.y, &screen_dc, screen_pos.x, screen_pos.y);
+
+ wxBitmap bmp(size.x, size.y);
+ wxMemoryDC mem_dc(bmp);
+ mem_dc.Blit(0, 0, size.x, size.y, &client_dc, 0, 0);
+ mem_dc.SelectObject(wxNullBitmap);
+ dc.DrawBitmap(bmp, 0, 0);
+#endif //__WXMSW__
+}
+
/*
* Here we do the actual rendering. I put it in a separate
* method so that it can work no matter what type of DC
@@ -188,17 +217,26 @@ void DropDown::render(wxDC &dc)
{
if (texts.size() == 0) return;
int states = state_handler.states();
+
+ const wxSize size = GetSize();
+ if (radius > 0. && !wxOSX)
+ SetTransparentBG(dc, this);
+
dc.SetPen(wxPen(border_color.colorForStates(states)));
dc.SetBrush(wxBrush(GetBackgroundColour()));
// if (GetWindowStyle() & wxBORDER_NONE)
// dc.SetPen(wxNullPen);
+ wxRect rc(0, 0, size.x, size.y);
+ if (wxOSX && dc.GetContentScaleFactor() > 1.0)
+ // On Retina displays all controls are cut on 1px
+ rc.x = rc.y = 1;
+
// draw background
- wxSize size = GetSize();
- if (radius == 0)
- dc.DrawRectangle(0, 0, size.x, size.y);
+ if (radius == 0.0 || wxOSX)
+ dc.DrawRectangle(rc);
else
- dc.DrawRoundedRectangle(0, 0, size.x, size.y, radius);
+ dc.DrawRoundedRectangle(rc, radius);
// draw hover rectangle
wxRect rcContent = {{0, offset.y}, rowSize};
@@ -233,8 +271,9 @@ void DropDown::render(wxDC &dc)
}
// draw position bar
- if (rowSize.y * texts.size() > size.y) {
- int height = rowSize.y * texts.size();
+ const int text_size = int(texts.size());
+ if (rowSize.y * text_size > size.y) {
+ int height = rowSize.y * text_size;
wxRect rect = {size.x - 6, -offset.y * size.y / height, 4,
size.y * size.y / height};
dc.SetPen(wxPen(border_color.defaultColor()));
@@ -247,13 +286,13 @@ void DropDown::render(wxDC &dc)
rcContent.x += 5;
rcContent.width -= 5;
if (check_bitmap.bmp().IsOk()) {
- auto szBmp = check_bitmap.GetBmpSize();
+ auto szBmp = check_bitmap.GetSize();
if (selection >= 0) {
wxPoint pt = rcContent.GetLeftTop();
pt.y += (rcContent.height - szBmp.y) / 2;
pt.y += rowSize.y * selection;
if (pt.y + szBmp.y > 0 && pt.y < size.y)
- dc.DrawBitmap(check_bitmap.bmp(), pt);
+ dc.DrawBitmap(check_bitmap.get_bitmap(), pt);
}
rcContent.x += szBmp.x + 5;
rcContent.width -= szBmp.x + 5;
@@ -268,17 +307,26 @@ void DropDown::render(wxDC &dc)
if (rcContent.y > size.y) break;
wxPoint pt = rcContent.GetLeftTop();
auto & icon = icons[i];
+ const wxSize pref_icon_sz = get_preferred_size(icon, m_parent);
if (iconSize.x > 0) {
if (icon.IsOk()) {
- pt.y += (rcContent.height - icon.GetSize().y) / 2;
- dc.DrawBitmap(icon, pt);
+ pt.y += (rcContent.height - pref_icon_sz.y) / 2;
+#ifdef __WXGTK3__
+ dc.DrawBitmap(icon.GetBitmap(pref_icon_sz), pt);
+#else
+ dc.DrawBitmap(icon.GetBitmapFor(m_parent), pt);
+#endif
}
pt.x += iconSize.x + 5;
pt.y = rcContent.y;
} else if (icon.IsOk()) {
- pt.y += (rcContent.height - icon.GetSize().y) / 2;
- dc.DrawBitmap(icon, pt);
- pt.x += icon.GetWidth() + 5;
+ pt.y += (rcContent.height - pref_icon_sz.y) / 2;
+#ifdef __WXGTK3__
+ dc.DrawBitmap(icon.GetBitmap(pref_icon_sz), pt);
+#else
+ dc.DrawBitmap(icon.GetBitmapFor(m_parent), pt);
+#endif
+ pt.x += pref_icon_sz.GetWidth() + 5;
pt.y = rcContent.y;
}
auto text = texts[i];
@@ -305,7 +353,7 @@ void DropDown::messureSize()
for (size_t i = 0; i < texts.size(); ++i) {
wxSize size1 = text_off ? wxSize() : dc.GetMultiLineTextExtent(texts[i]);
if (icons[i].IsOk()) {
- wxSize size2 = icons[i].GetSize();
+ wxSize size2 = get_preferred_size(icons[i], m_parent);
if (size2.x > iconSize.x) iconSize = size2;
if (!align_icon) {
size1.x += size2.x + (text_off ? 0 : 5);
@@ -317,7 +365,7 @@ void DropDown::messureSize()
wxSize szContent = textSize;
szContent.x += 10;
if (check_bitmap.bmp().IsOk()) {
- auto szBmp = check_bitmap.bmp().GetSize();
+ auto szBmp = check_bitmap.GetSize();
szContent.x += szBmp.x + 5;
}
if (iconSize.x > 0) szContent.x += iconSize.x + (text_off ? 0 : 5);
diff --git a/src/slic3r/GUI/Widgets/DropDown.hpp b/src/slic3r/GUI/Widgets/DropDown.hpp
index b2b7eaa73e..87eccd0238 100644
--- a/src/slic3r/GUI/Widgets/DropDown.hpp
+++ b/src/slic3r/GUI/Widgets/DropDown.hpp
@@ -2,24 +2,29 @@
#define slic3r_GUI_DropDown_hpp_
#include
+#include
+
+#include
+
#include "../wxExtensions.hpp"
#include "StateHandler.hpp"
#define DD_NO_CHECK_ICON 0x0001
-#define DD_NO_TEXT 0x0002
-#define DD_STYLE_MASK 0x0003
+#define DD_NO_DROP_ICON 0x0002
+#define DD_NO_TEXT 0x0004
+#define DD_STYLE_MASK 0x0008
wxDECLARE_EVENT(EVT_DISMISS, wxCommandEvent);
class DropDown : public wxPopupTransientWindow
{
std::vector & texts;
- std::vector & icons;
+ std::vector & icons;
bool need_sync = false;
int selection = -1;
int hover_item = -1;
- double radius = 0;
+ double radius;
bool use_content_width = false;
bool align_icon = false;
bool text_off = false;
@@ -42,17 +47,16 @@ class DropDown : public wxPopupTransientWindow
public:
DropDown(std::vector &texts,
- std::vector &icons);
+ std::vector &icons);
DropDown(wxWindow * parent,
std::vector &texts,
- std::vector &icons,
+ std::vector &icons,
long style = 0);
void Create(wxWindow * parent,
long style = 0);
-public:
void Invalidate(bool clear = false);
int GetSelection() const { return selection; }
@@ -62,7 +66,6 @@ public:
wxString GetValue() const;
void SetValue(const wxString &value);
-public:
void SetCornerRadius(double radius);
void SetBorderColor(StateColor const & color);
@@ -77,10 +80,11 @@ public:
void SetAlignIcon(bool align);
-public:
void Rescale();
bool HasDismissLongTime();
+
+ static void SetTransparentBG(wxDC& dc, wxWindow* win);
protected:
void OnDismiss() override;
diff --git a/src/slic3r/GUI/Widgets/Label.cpp b/src/slic3r/GUI/Widgets/Label.cpp
index 4a541f3478..c0bc2278fc 100644
--- a/src/slic3r/GUI/Widgets/Label.cpp
+++ b/src/slic3r/GUI/Widgets/Label.cpp
@@ -1,6 +1,8 @@
#include "Label.hpp"
#include "StaticBox.hpp"
+#include
+
wxFont Label::sysFont(int size, bool bold)
{
//#ifdef __linux__
diff --git a/src/slic3r/GUI/Widgets/Label.hpp b/src/slic3r/GUI/Widgets/Label.hpp
index 1d3d387fb7..90ce81a338 100644
--- a/src/slic3r/GUI/Widgets/Label.hpp
+++ b/src/slic3r/GUI/Widgets/Label.hpp
@@ -2,6 +2,7 @@
#define slic3r_GUI_Label_hpp_
#include
+#include
#define LB_HYPERLINK 0x0001
diff --git a/src/slic3r/GUI/Widgets/SpinInput.cpp b/src/slic3r/GUI/Widgets/SpinInput.cpp
index 9bea97dcdc..1dce77bb8a 100644
--- a/src/slic3r/GUI/Widgets/SpinInput.cpp
+++ b/src/slic3r/GUI/Widgets/SpinInput.cpp
@@ -1,8 +1,14 @@
#include "SpinInput.hpp"
-#include "Label.hpp"
#include "Button.hpp"
+#include "UIColors.hpp"
+
+#include "../GUI_App.hpp"
+
#include
+#include
+#include
+#include
BEGIN_EVENT_TABLE(SpinInput, wxPanel)
@@ -23,11 +29,9 @@ SpinInput::SpinInput()
: label_color(std::make_pair(0x909090, (int) StateColor::Disabled), std::make_pair(0x6B6B6B, (int) StateColor::Normal))
, text_color(std::make_pair(0x909090, (int) StateColor::Disabled), std::make_pair(0x262E30, (int) StateColor::Normal))
{
- radius = 0;
+ if (Slic3r::GUI::wxGetApp().suppress_round_corners())
+ radius = 0;
border_width = 1;
- border_color = StateColor(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), std::make_pair(0x00AE42, (int) StateColor::Hovered),
- std::make_pair(0xDBDBDB, (int) StateColor::Normal));
- background_color = StateColor(std::make_pair(0xF0F0F0, (int) StateColor::Disabled), std::make_pair(*wxWHITE, (int) StateColor::Normal));
}
@@ -52,17 +56,20 @@ void SpinInput::Create(wxWindow *parent,
int min, int max, int initial)
{
StaticBox::Create(parent, wxID_ANY, pos, size);
- SetFont(Label::Body_12);
wxWindow::SetLabel(label);
+
state_handler.attach({&label_color, &text_color});
state_handler.update_binds();
+
text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {20, 4}, wxDefaultSize, style | wxBORDER_NONE | wxTE_PROCESS_ENTER, wxTextValidator(wxFILTER_DIGITS));
- text_ctrl->SetFont(Label::Body_14);
- text_ctrl->SetBackgroundColour(background_color.colorForStates(state_handler.states()));
- text_ctrl->SetForegroundColour(text_color.colorForStates(state_handler.states()));
+#ifdef __WXOSX__
+ text_ctrl->OSXDisableAllSmartSubstitutions();
+#endif // __WXOSX__
text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
state_handler.attach_child(text_ctrl);
+
text_ctrl->Bind(wxEVT_KILL_FOCUS, &SpinInput::onTextLostFocus, this);
+ text_ctrl->Bind(wxEVT_TEXT, &SpinInput::onText, this);
text_ctrl->Bind(wxEVT_TEXT_ENTER, &SpinInput::onTextEnter, this);
text_ctrl->Bind(wxEVT_KEY_DOWN, &SpinInput::keyPressed, this);
text_ctrl->Bind(wxEVT_RIGHT_DOWN, [this](auto &e) {}); // disable context menu
@@ -71,6 +78,12 @@ void SpinInput::Create(wxWindow *parent,
delta = 0;
timer.Bind(wxEVT_TIMER, &SpinInput::onTimer, this);
+ SetFont(Slic3r::GUI::wxGetApp().normal_font());
+ if (parent) {
+ SetBackgroundColour(parent->GetBackgroundColour());
+ SetForegroundColour(parent->GetForegroundColour());
+ }
+
long initialFromText;
if (text.ToLong(&initialFromText)) initial = initialFromText;
SetRange(min, max);
@@ -114,6 +127,8 @@ void SpinInput::SetValue(const wxString &text)
long value;
if ( text.ToLong(&value) )
SetValue(value);
+ else
+ text_ctrl->SetValue(text);
}
void SpinInput::SetValue(int value)
@@ -129,12 +144,76 @@ int SpinInput::GetValue()const
return val;
}
+wxString SpinInput::GetTextValue() const
+{
+ return text_ctrl->GetValue();
+}
+
void SpinInput::SetRange(int min, int max)
{
this->min = min;
this->max = max;
}
+void SpinInput::SetSelection(long from, long to)
+{
+ if (text_ctrl)
+ text_ctrl->SetSelection(from, to);
+}
+
+bool SpinInput::SetFont(wxFont const& font)
+{
+ if (text_ctrl)
+ return text_ctrl->SetFont(font);
+ return StaticBox::SetFont(font);
+}
+
+bool SpinInput::SetBackgroundColour(const wxColour& colour)
+{
+ const int clr_background_disabled = Slic3r::GUI::wxGetApp().dark_mode() ? clr_background_disabled_dark : clr_background_disabled_light;
+ StateColor clr_state(std::make_pair(clr_background_disabled, (int)StateColor::Disabled),
+ std::make_pair(clr_background_focused, (int)StateColor::Checked),
+ std::make_pair(colour, (int)StateColor::Focused),
+ std::make_pair(colour, (int)StateColor::Normal));
+
+ StaticBox::SetBackgroundColor(clr_state);
+ if (text_ctrl)
+ text_ctrl->SetBackgroundColour(colour);
+ if (button_inc)
+ button_inc->SetBackgroundColor(clr_state);
+ if (button_dec)
+ button_dec->SetBackgroundColor(clr_state);
+
+ return true;
+}
+
+bool SpinInput::SetForegroundColour(const wxColour& colour)
+{
+ StateColor clr_state(std::make_pair(clr_foreground_disabled, (int)StateColor::Disabled),
+ std::make_pair(colour, (int)StateColor::Normal));
+
+ SetLabelColor(clr_state);
+ SetTextColor(clr_state);
+
+ if (text_ctrl)
+ text_ctrl->SetForegroundColour(colour);
+ if (button_inc)
+ button_inc->SetTextColor(clr_state);
+ if (button_dec)
+ button_dec->SetTextColor(clr_state);
+
+ return true;
+}
+
+void SpinInput::SetBorderColor(StateColor const &color)
+{
+ StaticBox::SetBorderColor(color);
+ if (button_inc)
+ button_inc->SetBorderColor(color);
+ if (button_dec)
+ button_dec->SetBorderColor(color);
+}
+
void SpinInput::DoSetToolTipText(wxString const &tip)
{
wxWindow::DoSetToolTipText(tip);
@@ -143,6 +222,9 @@ void SpinInput::DoSetToolTipText(wxString const &tip)
void SpinInput::Rescale()
{
+ SetFont(Slic3r::GUI::wxGetApp().normal_font());
+ text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
+
button_inc->Rescale();
button_dec->Rescale();
messureSize();
@@ -183,8 +265,11 @@ void SpinInput::render(wxDC& dc)
// draw seperator of buttons
wxPoint pt = button_inc->GetPosition();
pt.y = size.y / 2;
+ pt.x += 1;
dc.SetPen(wxPen(border_color.defaultColor()));
- dc.DrawLine(pt, pt + wxSize{button_inc->GetSize().x - 2, 0});
+
+ const double scale = dc.GetContentScaleFactor();
+ dc.DrawLine(pt, pt + wxSize{button_inc->GetSize().x - int(3. * scale), 0});
// draw label
auto label = GetLabel();
if (!label.IsEmpty()) {
@@ -201,31 +286,36 @@ void SpinInput::messureSize()
wxSize size = GetSize();
wxSize textSize = text_ctrl->GetSize();
int h = textSize.y + 8;
- if (size.y < h) {
+ if (size.y != h) {
size.y = h;
SetSize(size);
SetMinSize(size);
- } else {
- textSize.y = size.y * 14 / 24;
}
+
wxSize btnSize = {14, (size.y - 4) / 2};
btnSize.x = btnSize.x * btnSize.y / 10;
+
+ const double scale = this->GetContentScaleFactor();
+
wxClientDC dc(this);
labelSize = dc.GetMultiLineTextExtent(GetLabel());
textSize.x = size.x - labelSize.x - btnSize.x - 16;
text_ctrl->SetSize(textSize);
- text_ctrl->SetPosition({6 + btnSize.x, (size.y - textSize.y) / 2});
+ text_ctrl->SetPosition({int(3. * scale), (size.y - textSize.y) / 2});
button_inc->SetSize(btnSize);
button_dec->SetSize(btnSize);
- button_inc->SetPosition({3, size.y / 2 - btnSize.y - 1});
- button_dec->SetPosition({3, size.y / 2 + 1});
+ button_inc->SetPosition({size.x - btnSize.x - int(3. * scale), size.y / 2 - btnSize.y/* - 1*/});
+ button_dec->SetPosition({size.x - btnSize.x - int(3. * scale), size.y / 2 + 1});
}
Button *SpinInput::createButton(bool inc)
{
- auto btn = new Button(this, "", inc ? "spin_inc" : "spin_dec", wxBORDER_NONE, 6);
+ auto btn = new Button(this, "", inc ? "spin_inc_act" : "spin_dec_act", wxBORDER_NONE, wxSize(12, 7));
btn->SetCornerRadius(0);
+ btn->SetInactiveIcon(inc ? "spin_inc" : "spin_dec");
btn->DisableFocusFromKeyboard();
+ btn->SetSelected(false);
+
btn->Bind(wxEVT_LEFT_DOWN, [=](auto &e) {
delta = inc ? 1 : -1;
SetValue(val + delta);
@@ -286,6 +376,13 @@ void SpinInput::onTextEnter(wxCommandEvent &event)
ProcessEventLocally(event);
}
+void SpinInput::onText(wxCommandEvent &event)
+{
+ sendSpinEvent();
+ event.SetId(GetId());
+ ProcessEventLocally(event);
+}
+
void SpinInput::mouseWheelMoved(wxMouseEvent &event)
{
auto delta = (event.GetWheelRotation() < 0 == event.IsWheelInverted()) ? 1 : -1;
diff --git a/src/slic3r/GUI/Widgets/SpinInput.hpp b/src/slic3r/GUI/Widgets/SpinInput.hpp
index 5b0868880c..932958e138 100644
--- a/src/slic3r/GUI/Widgets/SpinInput.hpp
+++ b/src/slic3r/GUI/Widgets/SpinInput.hpp
@@ -11,9 +11,9 @@ class SpinInput : public wxNavigationEnabled
wxSize labelSize;
StateColor label_color;
StateColor text_color;
- wxTextCtrl * text_ctrl;
- Button * button_inc;
- Button * button_dec;
+ wxTextCtrl * text_ctrl{nullptr};
+ Button * button_inc {nullptr};
+ Button * button_dec {nullptr};
wxTimer timer;
int val;
@@ -59,16 +59,27 @@ public:
virtual bool Enable(bool enable = true) wxOVERRIDE;
- wxTextCtrl * GetTextCtrl() { return text_ctrl; }
+ wxTextCtrl * GetText() { return text_ctrl; }
void SetValue(const wxString &text);
void SetValue (int value);
int GetValue () const;
+ wxString GetTextValue() const;
void SetRange(int min, int max);
+ bool SetFont(wxFont const& font) override;
+
+ bool SetBackgroundColour(const wxColour& colour) override;
+ bool SetForegroundColour(const wxColour& colour) override;
+ void SetBorderColor(StateColor const& color);
+
+ int GetMin() const { return this->min; }
+ int GetMax() const { return this->max; }
+ void SetSelection(long from, long to);
+
protected:
void DoSetToolTipText(wxString const &tip) override;
@@ -86,6 +97,7 @@ private:
void keyPressed(wxKeyEvent& event);
void onTimer(wxTimerEvent &evnet);
void onTextLostFocus(wxEvent &event);
+ void onText(wxCommandEvent &event);
void onTextEnter(wxCommandEvent &event);
void sendSpinEvent();
diff --git a/src/slic3r/GUI/Widgets/StateHandler.cpp b/src/slic3r/GUI/Widgets/StateHandler.cpp
index 72616ed8fd..87d14674cc 100644
--- a/src/slic3r/GUI/Widgets/StateHandler.cpp
+++ b/src/slic3r/GUI/Widgets/StateHandler.cpp
@@ -1,5 +1,7 @@
#include "StateHandler.hpp"
+#include
+
wxDEFINE_EVENT(EVT_ENABLE_CHANGED, wxCommandEvent);
StateHandler::StateHandler(wxWindow * owner)
diff --git a/src/slic3r/GUI/Widgets/StateHandler.hpp b/src/slic3r/GUI/Widgets/StateHandler.hpp
index 9ef155c7db..d7d6faeb40 100644
--- a/src/slic3r/GUI/Widgets/StateHandler.hpp
+++ b/src/slic3r/GUI/Widgets/StateHandler.hpp
@@ -2,6 +2,7 @@
#define slic3r_GUI_StateHandler_hpp_
#include
+#include
#include "StateColor.hpp"
diff --git a/src/slic3r/GUI/Widgets/StaticBox.cpp b/src/slic3r/GUI/Widgets/StaticBox.cpp
index 1a806e0007..29d5ff69e3 100644
--- a/src/slic3r/GUI/Widgets/StaticBox.cpp
+++ b/src/slic3r/GUI/Widgets/StaticBox.cpp
@@ -1,11 +1,13 @@
#include "StaticBox.hpp"
#include "../GUI.hpp"
#include
+#include
+
+#include "DropDown.hpp"
+#include "UIColors.hpp"
BEGIN_EVENT_TABLE(StaticBox, wxWindow)
-// catch paint events
-//EVT_ERASE_BACKGROUND(StaticBox::eraseEvent)
EVT_PAINT(StaticBox::paintEvent)
END_EVENT_TABLE()
@@ -20,9 +22,9 @@ StaticBox::StaticBox()
: state_handler(this)
, radius(8)
{
- border_color = StateColor(
- std::make_pair(*wxLIGHT_GREY, (int) StateColor::Disabled),
- std::make_pair(0x303A3C, (int) StateColor::Normal));
+ border_color = StateColor(std::make_pair(clr_border_disabled, (int) StateColor::Disabled),
+ std::make_pair(clr_border_hovered, (int) StateColor::Hovered),
+ std::make_pair(clr_border_nornal, (int) StateColor::Normal));
}
StaticBox::StaticBox(wxWindow* parent,
@@ -41,7 +43,8 @@ bool StaticBox::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, cons
wxWindow::Create(parent, id, pos, size, style);
state_handler.attach({&border_color, &background_color, &background_color2});
state_handler.update_binds();
- SetBackgroundColour(GetParentBackgroundColor(parent));
+// SetBackgroundColour(GetParentBackgroundColor(parent));
+// SetForegroundColour(parent->GetParent()->GetForegroundColour());
return true;
}
@@ -109,21 +112,10 @@ wxColor StaticBox::GetParentBackgroundColor(wxWindow* parent)
return *wxWHITE;
}
-void StaticBox::eraseEvent(wxEraseEvent& evt)
-{
- // for transparent background, but not work
-#ifdef __WXMSW__
- wxDC *dc = evt.GetDC();
- wxSize size = GetSize();
- wxClientDC dc2(GetParent());
- dc->Blit({0, 0}, size, &dc2, GetPosition());
-#endif
-}
-
void StaticBox::paintEvent(wxPaintEvent& evt)
{
// depending on your system you may need to look at double-buffered dcs
- wxPaintDC dc(this);
+ wxBufferedPaintDC dc(this);//wxPaintDC dc(this);
render(dc);
}
@@ -134,29 +126,7 @@ void StaticBox::paintEvent(wxPaintEvent& evt)
*/
void StaticBox::render(wxDC& dc)
{
-#ifdef __WXMSW__
- if (radius == 0) {
- doRender(dc);
- return;
- }
-
- wxSize size = GetSize();
- wxMemoryDC memdc;
- wxBitmap bmp(size.x, size.y);
- memdc.SelectObject(bmp);
- //memdc.Blit({0, 0}, size, &dc, {0, 0});
- memdc.SetBackground(wxBrush(GetBackgroundColour()));
- memdc.Clear();
- {
- wxGCDC dc2(memdc);
- doRender(dc2);
- }
-
- memdc.SelectObject(wxNullBitmap);
- dc.DrawBitmap(bmp, 0, 0);
-#else
doRender(dc);
-#endif
}
void StaticBox::doRender(wxDC& dc)
@@ -166,35 +136,53 @@ void StaticBox::doRender(wxDC& dc)
if (background_color2.count() == 0) {
if ((border_width && border_color.count() > 0) || background_color.count() > 0) {
wxRect rc(0, 0, size.x, size.y);
- if (border_width && border_color.count() > 0) {
- if (dc.GetContentScaleFactor() == 1.0) {
- int d = floor(border_width / 2.0);
- int d2 = floor(border_width - 1);
- rc.x += d;
- rc.width -= d2;
- rc.y += d;
- rc.height -= d2;
- } else {
- int d = 1;
- rc.x += d;
- rc.width -= d;
- rc.y += d;
- rc.height -= d;
- }
- dc.SetPen(wxPen(border_color.colorForStates(states), border_width));
- } else {
- dc.SetPen(wxPen(background_color.colorForStates(states)));
+#ifdef __WXOSX__
+ // On Retina displays all controls are cut on 1px
+ if (dc.GetContentScaleFactor() > 1.)
+ rc.Deflate(1, 1);
+#endif //__WXOSX__
+
+ if (radius > 0.) {
+#if 0
+ DropDown::SetTransparentBG(dc, this);
+#else
+#ifdef __WXMSW__
+ wxColour bg_clr = GetParentBackgroundColor(m_parent);
+ dc.SetBrush(wxBrush(bg_clr));
+ dc.SetPen(wxPen(bg_clr));
+ dc.DrawRectangle(rc);
+#endif
+#endif
}
+
if (background_color.count() > 0)
dc.SetBrush(wxBrush(background_color.colorForStates(states)));
else
dc.SetBrush(wxBrush(GetBackgroundColour()));
- if (radius == 0) {
+
+ if (border_width && border_color.count() > 0) {
+#ifdef __WXOSX__
+ const double bw = (double)border_width;
+#else
+ const double bw = dc.GetContentScaleFactor() * (double)border_width;
+#endif //__WXOSX__
+ {
+ int d = floor(bw / 2.0);
+ int d2 = floor(bw - 1);
+ rc.x += d;
+ rc.width -= d2;
+ rc.y += d;
+ rc.height -= d2;
+ }
+ dc.SetPen(wxPen(border_color.colorForStates(states), bw));
+ } else {
+ dc.SetPen(wxPen(background_color.colorForStates(states)));
+ }
+
+ if (radius == 0.)
dc.DrawRectangle(rc);
- }
- else {
+ else
dc.DrawRoundedRectangle(rc, radius - border_width);
- }
}
}
else {
diff --git a/src/slic3r/GUI/Widgets/StaticBox.hpp b/src/slic3r/GUI/Widgets/StaticBox.hpp
index 871c5651d9..9cfddaef24 100644
--- a/src/slic3r/GUI/Widgets/StaticBox.hpp
+++ b/src/slic3r/GUI/Widgets/StaticBox.hpp
@@ -31,7 +31,7 @@ public:
void SetBorderColorNormal(wxColor const &color);
- void SetBackgroundColor(StateColor const &color);
+ virtual void SetBackgroundColor(StateColor const &color);
void SetBackgroundColorNormal(wxColor const &color);
@@ -40,15 +40,12 @@ public:
static wxColor GetParentBackgroundColor(wxWindow * parent);
protected:
- void eraseEvent(wxEraseEvent& evt);
-
void paintEvent(wxPaintEvent& evt);
void render(wxDC& dc);
virtual void doRender(wxDC& dc);
-protected:
double radius;
int border_width = 1;
StateHandler state_handler;
diff --git a/src/slic3r/GUI/Widgets/SwitchButton.cpp b/src/slic3r/GUI/Widgets/SwitchButton.cpp
index 8ae1165dcb..c87d302037 100644
--- a/src/slic3r/GUI/Widgets/SwitchButton.cpp
+++ b/src/slic3r/GUI/Widgets/SwitchButton.cpp
@@ -1,23 +1,20 @@
#include "SwitchButton.hpp"
-#include "Label.hpp"
-#include "StaticBox.hpp"
#include "../wxExtensions.hpp"
-#include "../Utils/MacDarkMode.hpp"
+#include "../../Utils/MacDarkMode.hpp"
#include
+#include
+#include
-SwitchButton::SwitchButton(wxWindow* parent, wxWindowID id)
- : wxBitmapToggleButton(parent, id, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxBU_EXACTFIT)
- , m_on(this, "toggle_on", 16)
- , m_off(this, "toggle_off", 16)
+SwitchButton::SwitchButton(wxWindow* parent, const wxString& name, wxWindowID id)
+ : BitmapToggleButton(parent, name, id)
+ , m_on(this, "toggle_on", 28, 16)
+ , m_off(this, "toggle_off", 28, 16)
, text_color(std::pair{*wxWHITE, (int) StateColor::Checked}, std::pair{0x6B6B6B, (int) StateColor::Normal})
, track_color(0xD9D9D9)
, thumb_color(std::pair{0x00AE42, (int) StateColor::Checked}, std::pair{0xD9D9D9, (int) StateColor::Normal})
{
- SetBackgroundColour(StaticBox::GetParentBackgroundColor(parent));
- Bind(wxEVT_TOGGLEBUTTON, [this](auto& e) { update(); e.Skip(); });
- SetFont(Label::Body_12);
Rescale();
}
@@ -52,11 +49,7 @@ void SwitchButton::SetValue(bool value)
void SwitchButton::Rescale()
{
- if (labels[0].IsEmpty()) {
- m_on.msw_rescale();
- m_off.msw_rescale();
- }
- else {
+ if (!labels[0].IsEmpty()) {
#ifdef __WXOSX__
auto scale = Slic3r::GUI::mac_max_scaling_factor();
int BS = (int) scale;
@@ -121,14 +114,23 @@ void SwitchButton::Rescale()
#ifdef __WXOSX__
bmp = wxBitmap(bmp.ConvertToImage(), -1, scale);
#endif
- (i == 0 ? m_off : m_on).bmp() = bmp;
+ (i == 0 ? m_off : m_on).SetBitmap(bmp);
}
}
- SetSize(m_on.GetBmpSize());
+
+ update();
+}
+
+void SwitchButton::SysColorChange()
+{
+ m_on.sys_color_changed();
+ m_off.sys_color_changed();
+
update();
}
void SwitchButton::update()
{
SetBitmap((GetValue() ? m_on : m_off).bmp());
+ update_size();
}
diff --git a/src/slic3r/GUI/Widgets/SwitchButton.hpp b/src/slic3r/GUI/Widgets/SwitchButton.hpp
index 25581f3762..5c1859e9c2 100644
--- a/src/slic3r/GUI/Widgets/SwitchButton.hpp
+++ b/src/slic3r/GUI/Widgets/SwitchButton.hpp
@@ -4,12 +4,12 @@
#include "../wxExtensions.hpp"
#include "StateColor.hpp"
-#include
+#include "BitmapToggleButton.hpp"
-class SwitchButton : public wxBitmapToggleButton
+class SwitchButton : public BitmapToggleButton
{
public:
- SwitchButton(wxWindow * parent = NULL, wxWindowID id = wxID_ANY);
+ SwitchButton(wxWindow * parent = NULL, const wxString& name = wxEmptyString, wxWindowID id = wxID_ANY);
public:
void SetLabels(wxString const & lbl_on, wxString const & lbl_off);
@@ -24,8 +24,10 @@ public:
void Rescale();
+ void SysColorChange();
+
private:
- void update();
+ void update() override;
private:
ScalableBitmap m_on;
diff --git a/src/slic3r/GUI/Widgets/TextInput.cpp b/src/slic3r/GUI/Widgets/TextInput.cpp
index 823dd5512d..4b7dd44ddc 100644
--- a/src/slic3r/GUI/Widgets/TextInput.cpp
+++ b/src/slic3r/GUI/Widgets/TextInput.cpp
@@ -1,7 +1,10 @@
#include "TextInput.hpp"
-#include "Label.hpp"
+#include "UIColors.hpp"
#include
+#include
+
+#include "slic3r/GUI/GUI_App.hpp"
BEGIN_EVENT_TABLE(TextInput, wxPanel)
@@ -21,12 +24,9 @@ TextInput::TextInput()
, text_color(std::make_pair(0x909090, (int) StateColor::Disabled),
std::make_pair(0x262E30, (int) StateColor::Normal))
{
- radius = 0;
+ if (Slic3r::GUI::wxGetApp().suppress_round_corners())
+ radius = 0;
border_width = 1;
- border_color = StateColor(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), std::make_pair(0x00AE42, (int) StateColor::Hovered),
- std::make_pair(0xDBDBDB, (int) StateColor::Normal));
- background_color = StateColor(std::make_pair(0xF0F0F0, (int) StateColor::Disabled), std::make_pair(*wxWHITE, (int) StateColor::Normal));
- SetFont(Label::Body_12);
}
TextInput::TextInput(wxWindow * parent,
@@ -52,15 +52,21 @@ void TextInput::Create(wxWindow * parent,
text_ctrl = nullptr;
StaticBox::Create(parent, wxID_ANY, pos, size, style);
wxWindow::SetLabel(label);
- style &= ~wxRIGHT;
- state_handler.attach({&label_color, & text_color});
+
+ state_handler.attach({&label_color, &text_color});
state_handler.update_binds();
- text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {4, 4}, wxDefaultSize, style | wxBORDER_NONE | wxTE_PROCESS_ENTER);
- text_ctrl->SetFont(Label::Body_14);
+
+ text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {4, 4}, wxDefaultSize, style | wxBORDER_NONE);
+#ifdef __WXOSX__
+ text_ctrl->OSXDisableAllSmartSubstitutions();
+#endif // __WXOSX__
text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
- text_ctrl->SetBackgroundColour(background_color.colorForStates(state_handler.states()));
- text_ctrl->SetForegroundColour(text_color.colorForStates(state_handler.states()));
+ if (parent) {
+ SetBackgroundColour(parent->GetBackgroundColour());
+ SetForegroundColour(parent->GetForegroundColour());
+ }
state_handler.attach_child(text_ctrl);
+
text_ctrl->Bind(wxEVT_KILL_FOCUS, [this](auto &e) {
OnEdit();
e.SetId(GetId());
@@ -73,8 +79,9 @@ void TextInput::Create(wxWindow * parent,
ProcessEventLocally(e);
});
text_ctrl->Bind(wxEVT_RIGHT_DOWN, [this](auto &e) {}); // disable context menu
+
if (!icon.IsEmpty()) {
- this->icon = ScalableBitmap(this, icon.ToStdString(), 16);
+ this->drop_down_icon = ScalableBitmap(this, icon.ToStdString(), 16);
}
messureSize();
}
@@ -92,10 +99,54 @@ void TextInput::SetLabel(const wxString& label)
Refresh();
}
-void TextInput::SetIcon(const wxBitmap &icon)
+bool TextInput::SetBackgroundColour(const wxColour& colour)
{
- this->icon.bmp() = icon;
- Rescale();
+ const int clr_background_disabled = Slic3r::GUI::wxGetApp().dark_mode() ? clr_background_disabled_dark : clr_background_disabled_light;
+ const StateColor clr_state( std::make_pair(clr_background_disabled, (int)StateColor::Disabled),
+ std::make_pair(clr_background_focused, (int)StateColor::Checked),
+ std::make_pair(colour, (int)StateColor::Focused),
+ std::make_pair(colour, (int)StateColor::Normal));
+
+ SetBackgroundColor(clr_state);
+ if (text_ctrl)
+ text_ctrl->SetBackgroundColour(colour);
+
+ return true;
+}
+
+bool TextInput::SetForegroundColour(const wxColour& colour)
+{
+ const StateColor clr_state( std::make_pair(clr_foreground_disabled, (int)StateColor::Disabled),
+ std::make_pair(colour, (int)StateColor::Normal));
+
+ SetLabelColor(clr_state);
+ SetTextColor (clr_state);
+
+ return true;
+}
+
+void TextInput::SetValue(const wxString& value)
+{
+ if (text_ctrl)
+ text_ctrl->SetValue(value);
+}
+
+wxString TextInput::GetValue()
+{
+ if (text_ctrl)
+ return text_ctrl->GetValue();
+ return wxEmptyString;
+}
+
+void TextInput::SetSelection(long from, long to)
+{
+ if (text_ctrl)
+ text_ctrl->SetSelection(from, to);
+}
+
+void TextInput::SetIcon(const wxBitmapBundle& icon_in)
+{
+ icon = icon_in;
}
void TextInput::SetLabelColor(StateColor const &color)
@@ -106,18 +157,41 @@ void TextInput::SetLabelColor(StateColor const &color)
void TextInput::SetTextColor(StateColor const& color)
{
- text_color= color;
+ text_color = color;
state_handler.update_binds();
+ if (text_ctrl)
+ text_ctrl->SetForegroundColour(text_color.colorForStates(state_handler.states()));
+}
+
+void TextInput::SetBGColor(StateColor const& color)
+{
+ background_color = color;
+ state_handler.update_binds();
+}
+
+void TextInput::SetCtrlSize(wxSize const& size)
+{
+ StaticBox::SetInitialSize(size);
+ Rescale();
}
void TextInput::Rescale()
{
- if (!this->icon.name().empty())
- this->icon.msw_rescale();
+ if (text_ctrl)
+ text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
+
messureSize();
Refresh();
}
+bool TextInput::SetFont(const wxFont& font)
+{
+ bool ret = StaticBox::SetFont(font);
+ if (text_ctrl)
+ return ret && text_ctrl->SetFont(font);
+ return ret;
+}
+
bool TextInput::Enable(bool enable)
{
bool result = text_ctrl->Enable(enable) && wxWindow::Enable(enable);
@@ -149,16 +223,22 @@ void TextInput::DoSetSize(int x, int y, int width, int height, int sizeFlags)
if (sizeFlags & wxSIZE_USE_EXISTING) return;
wxSize size = GetSize();
wxPoint textPos = {5, 0};
- if (this->icon.bmp().IsOk()) {
- wxSize szIcon = this->icon.GetBmpSize();
+ if (this->icon.IsOk()) {
+ wxSize szIcon = get_preferred_size(icon, m_parent);
textPos.x += szIcon.x;
}
+ wxSize dd_icon_size = wxSize(0,0);
+ if (this->drop_down_icon.bmp().IsOk())
+ dd_icon_size = this->drop_down_icon.GetSize();
+
bool align_right = GetWindowStyle() & wxRIGHT;
if (align_right)
textPos.x += labelSize.x;
if (text_ctrl) {
wxSize textSize = text_ctrl->GetSize();
- textSize.x = size.x - textPos.x - labelSize.x - 10;
+ wxClientDC dc(this);
+ const int r_shift = int((dd_icon_size.x == 0 ? 3. : 2.) * dc.GetContentScaleFactor());
+ textSize.x = size.x - textPos.x - labelSize.x - dd_icon_size.x - r_shift;
text_ctrl->SetSize(textSize);
text_ctrl->SetPosition({textPos.x, (size.y - textSize.y) / 2});
}
@@ -190,22 +270,36 @@ void TextInput::render(wxDC& dc)
bool align_right = GetWindowStyle() & wxRIGHT;
// start draw
wxPoint pt = {5, 0};
- if (icon.bmp().IsOk()) {
- wxSize szIcon = icon.GetBmpSize();
+ if (icon.IsOk()) {
+ wxSize szIcon = get_preferred_size(icon, m_parent);
pt.y = (size.y - szIcon.y) / 2;
- dc.DrawBitmap(icon.bmp(), pt);
- pt.x += szIcon.x + 0;
+#ifdef __WXGTK3__
+ dc.DrawBitmap(icon.GetBitmap(szIcon), pt);
+#else
+ dc.DrawBitmap(icon.GetBitmapFor(m_parent), pt);
+#endif
+ pt.x += szIcon.x + 5;
}
+
+ // drop_down_icon draw
+ wxPoint pt_r = {size.x, 0};
+ if (drop_down_icon.bmp().IsOk()) {
+ wxSize szIcon = drop_down_icon.GetSize();
+ pt_r.x -= szIcon.x + 2;
+ pt_r.y = (size.y - szIcon.y) / 2;
+ dc.DrawBitmap(drop_down_icon.get_bitmap(), pt_r);
+ }
+
auto text = wxWindow::GetLabel();
if (!text.IsEmpty()) {
wxSize textSize = text_ctrl->GetSize();
if (align_right) {
- if (pt.x + labelSize.x > size.x)
- text = wxControl::Ellipsize(text, dc, wxELLIPSIZE_END, size.x - pt.x);
- pt.y = (size.y - labelSize.y) / 2;
- } else {
pt.x += textSize.x;
pt.y = (size.y + textSize.y) / 2 - labelSize.y;
+ } else {
+ if (pt.x + labelSize.x > pt_r.x)
+ text = wxControl::Ellipsize(text, dc, wxELLIPSIZE_END, pt_r.x - pt.x);
+ pt.y = (size.y - labelSize.y) / 2;
}
dc.SetTextForeground(label_color.colorForStates(states));
dc.SetFont(GetFont());
@@ -218,11 +312,11 @@ void TextInput::messureSize()
wxSize size = GetSize();
wxClientDC dc(this);
labelSize = dc.GetTextExtent(wxWindow::GetLabel());
- wxSize textSize = text_ctrl->GetSize();
- int h = textSize.y + 8;
- if (size.y < h) {
- size.y = h;
- }
+
+ const wxSize textSize = text_ctrl->GetSize();
+ const wxSize iconSize = drop_down_icon.bmp().IsOk() ? drop_down_icon.GetSize() : wxSize(0, 0);
+ size.y = ((textSize.y > iconSize.y) ? textSize.y : iconSize.y) + 8;
+
wxSize minSize = size;
minSize.x = GetMinWidth();
SetMinSize(minSize);
diff --git a/src/slic3r/GUI/Widgets/TextInput.hpp b/src/slic3r/GUI/Widgets/TextInput.hpp
index 152fb88f3d..84bdf7126b 100644
--- a/src/slic3r/GUI/Widgets/TextInput.hpp
+++ b/src/slic3r/GUI/Widgets/TextInput.hpp
@@ -8,10 +8,11 @@ class TextInput : public wxNavigationEnabled
{
wxSize labelSize;
- ScalableBitmap icon;
+ wxBitmapBundle icon;
+ ScalableBitmap drop_down_icon;
StateColor label_color;
StateColor text_color;
- wxTextCtrl * text_ctrl;
+ wxTextCtrl* text_ctrl{nullptr};
static const int TextInputWidth = 200;
static const int TextInputHeight = 50;
@@ -40,22 +41,38 @@ public:
void SetLabel(const wxString& label);
- void SetIcon(const wxBitmap & icon);
+ void SetIcon(const wxBitmapBundle& icon);
void SetLabelColor(StateColor const &color);
+ void SetBGColor(StateColor const &color);
+
void SetTextColor(StateColor const &color);
+ void SetCtrlSize(wxSize const& size);
+
virtual void Rescale();
+ bool SetFont(const wxFont &font) override;
+
virtual bool Enable(bool enable = true) override;
virtual void SetMinSize(const wxSize& size) override;
+ bool SetBackgroundColour(const wxColour &colour) override;
+
+ bool SetForegroundColour(const wxColour &colour) override;
+
wxTextCtrl *GetTextCtrl() { return text_ctrl; }
wxTextCtrl const *GetTextCtrl() const { return text_ctrl; }
+ void SetValue(const wxString& value);
+
+ wxString GetValue();
+
+ void SetSelection(long from, long to);
+
protected:
virtual void OnEdit() {}
@@ -64,6 +81,9 @@ protected:
void DoSetToolTipText(wxString const &tip) override;
+ StateColor GetTextColor() const { return text_color; }
+ StateColor GetBorderColor() const { return border_color; }
+
private:
void paintEvent(wxPaintEvent& evt);
diff --git a/src/slic3r/GUI/Widgets/UIColors.hpp b/src/slic3r/GUI/Widgets/UIColors.hpp
new file mode 100644
index 0000000000..fefa6efd71
--- /dev/null
+++ b/src/slic3r/GUI/Widgets/UIColors.hpp
@@ -0,0 +1,18 @@
+#ifndef slic3r_UI_Colors_hpp_
+#define slic3r_UI_Colors_hpp_
+
+static const int clr_border_nornal = 0x646464;//0xDBDBDB;
+static const int clr_border_hovered = 0xED6B21;//0x00AE42;
+static const int clr_border_disabled = 0x646464;//0xDBDBDB;
+
+static const int clr_background_nornal_light = 0xFFFFFF;
+static const int clr_background_nornal_dark = 0x2B2B2B;//0x434343;
+static const int clr_background_focused = 0xED6B21;//0xEDFAF2;
+static const int clr_background_disabled_dark = 0x404040;//0xF0F0F0;
+static const int clr_background_disabled_light = 0xD9D9D9;//0xF0F0F0;
+
+static const int clr_foreground_nornal = 0x262E30;
+static const int clr_foreground_focused = 0x00AE42;
+static const int clr_foreground_disabled = 0x909090;
+
+#endif // !slic3r_UI_Colors_hpp_
\ No newline at end of file
diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp
index 87f6a0ac02..0984c82c57 100644
--- a/src/slic3r/GUI/wxExtensions.cpp
+++ b/src/slic3r/GUI/wxExtensions.cpp
@@ -422,10 +422,12 @@ static int scale()
}
#endif // __WXGTK2__
-wxBitmapBundle* get_bmp_bundle(const std::string& bmp_name_in, int px_cnt/* = 16*/, const std::string& new_color/* = std::string()*/)
+wxBitmapBundle* get_bmp_bundle(const std::string& bmp_name_in, int width/* = 16*/, int height/* = -1*/, const std::string& new_color/* = std::string()*/)
{
#ifdef __WXGTK2__
- px_cnt *= scale();
+ width *= scale();
+ if (height > 0)
+ height *= scale();
#endif // __WXGTK2__
static Slic3r::GUI::BitmapCache cache;
@@ -433,10 +435,13 @@ wxBitmapBundle* get_bmp_bundle(const std::string& bmp_name_in, int px_cnt/* = 16
std::string bmp_name = bmp_name_in;
boost::replace_last(bmp_name, ".png", "");
+ if (height < 0)
+ height = width;
+
// Try loading an SVG first, then PNG if SVG is not found:
- wxBitmapBundle* bmp = cache.from_svg(bmp_name, px_cnt, px_cnt, Slic3r::GUI::wxGetApp().dark_mode(), new_color);
+ wxBitmapBundle* bmp = cache.from_svg(bmp_name, width, height, Slic3r::GUI::wxGetApp().dark_mode(), new_color);
if (bmp == nullptr) {
- bmp = cache.from_png(bmp_name, px_cnt, px_cnt);
+ bmp = cache.from_png(bmp_name, width, height);
if (!bmp)
// Neither SVG nor PNG has been found, raise error
throw Slic3r::RuntimeError("Could not load bitmap: " + bmp_name);
@@ -658,7 +663,7 @@ void ModeButton::SetState(const bool state)
void ModeButton::update_bitmap()
{
- m_bmp = *get_bmp_bundle("mode", m_px_cnt, Slic3r::GUI::wxGetApp().get_mode_btn_color(m_mode_id));
+ m_bmp = *get_bmp_bundle("mode", m_bmp_width, m_bmp_height, Slic3r::GUI::wxGetApp().get_mode_btn_color(m_mode_id));
SetBitmap(m_bmp);
SetBitmapCurrent(m_bmp);
@@ -785,19 +790,28 @@ void MenuWithSeparators::SetSecondSeparator()
// PrusaBitmap
// ----------------------------------------------------------------------------
ScalableBitmap::ScalableBitmap( wxWindow *parent,
- const std::string& icon_name/* = ""*/,
- const int px_cnt/* = 16*/,
+ const std::string& icon_name,
+ const int width/* = 16*/,
+ const int height/* = -1*/,
const bool grayscale/* = false*/):
m_parent(parent), m_icon_name(icon_name),
- m_px_cnt(px_cnt)
+ m_bmp_width(width), m_bmp_height(height)
{
- m_bmp = *get_bmp_bundle(icon_name, px_cnt);
+ m_bmp = *get_bmp_bundle(icon_name, width, height);
m_bitmap = m_bmp.GetBitmapFor(m_parent);
}
+ScalableBitmap::ScalableBitmap( wxWindow* parent,
+ const std::string& icon_name,
+ const wxSize icon_size,
+ const bool grayscale/* = false*/) :
+ScalableBitmap(parent, icon_name, icon_size.x, icon_size.y, grayscale)
+{
+}
+
void ScalableBitmap::sys_color_changed()
{
- m_bmp = *get_bmp_bundle(m_icon_name, m_px_cnt);
+ m_bmp = *get_bmp_bundle(m_icon_name, m_bmp_width, m_bmp_height);
}
// ----------------------------------------------------------------------------
@@ -811,17 +825,19 @@ ScalableButton::ScalableButton( wxWindow * parent,
const wxSize& size /* = wxDefaultSize*/,
const wxPoint& pos /* = wxDefaultPosition*/,
long style /*= wxBU_EXACTFIT | wxNO_BORDER*/,
- int bmp_px_cnt/* = 16*/) :
+ int width/* = 16*/,
+ int height/* = -1*/) :
m_parent(parent),
m_current_icon_name(icon_name),
- m_px_cnt(bmp_px_cnt),
+ m_bmp_width(width),
+ m_bmp_height(height),
m_has_border(!(style & wxNO_BORDER))
{
Create(parent, id, label, pos, size, style);
Slic3r::GUI::wxGetApp().UpdateDarkUI(this);
if (!icon_name.empty()) {
- SetBitmap(*get_bmp_bundle(icon_name, m_px_cnt));
+ SetBitmap(*get_bmp_bundle(icon_name, width, height));
if (!label.empty())
SetBitmapMargins(int(0.5* em_unit(parent)), 0);
}
@@ -842,7 +858,8 @@ ScalableButton::ScalableButton( wxWindow * parent,
long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) :
m_parent(parent),
m_current_icon_name(bitmap.name()),
- m_px_cnt(bitmap.px_cnt()),
+ m_bmp_width(bitmap.px_size().x),
+ m_bmp_height(bitmap.px_size().y),
m_has_border(!(style& wxNO_BORDER))
{
Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style);
@@ -863,7 +880,7 @@ bool ScalableButton::SetBitmap_(const std::string& bmp_name)
if (m_current_icon_name.empty())
return false;
- wxBitmapBundle bmp = *get_bmp_bundle(m_current_icon_name, m_px_cnt);
+ wxBitmapBundle bmp = *get_bmp_bundle(m_current_icon_name, m_bmp_width, m_bmp_height);
SetBitmap(bmp);
SetBitmapCurrent(bmp);
SetBitmapPressed(bmp);
@@ -891,13 +908,13 @@ void ScalableButton::sys_color_changed()
{
Slic3r::GUI::wxGetApp().UpdateDarkUI(this, m_has_border);
- wxBitmapBundle bmp = *get_bmp_bundle(m_current_icon_name, m_px_cnt);
+ wxBitmapBundle bmp = *get_bmp_bundle(m_current_icon_name, m_bmp_width, m_bmp_height);
SetBitmap(bmp);
SetBitmapCurrent(bmp);
SetBitmapPressed(bmp);
SetBitmapFocus(bmp);
if (!m_disabled_icon_name.empty())
- SetBitmapDisabled(*get_bmp_bundle(m_disabled_icon_name, m_px_cnt));
+ SetBitmapDisabled(*get_bmp_bundle(m_disabled_icon_name, m_bmp_width, m_bmp_height));
if (!GetLabelText().IsEmpty())
SetBitmapMargins(int(0.5 * em_unit(m_parent)), 0);
}
diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp
index 8b33d902f5..a0ed1bbd4c 100644
--- a/src/slic3r/GUI/wxExtensions.hpp
+++ b/src/slic3r/GUI/wxExtensions.hpp
@@ -54,7 +54,7 @@ void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector<
int em_unit(wxWindow* win);
int mode_icon_px_size();
-wxBitmapBundle* get_bmp_bundle(const std::string& bmp_name, int px_cnt = 16, const std::string& new_color_rgb = std::string());
+wxBitmapBundle* get_bmp_bundle(const std::string& bmp_name, int width = 16, int height = -1, const std::string& new_color_rgb = std::string());
wxBitmapBundle* get_empty_bmp_bundle(int width, int height);
wxBitmapBundle* get_solid_bmp_bundle(int width, int height, const std::string& color);
@@ -131,6 +131,17 @@ public:
void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; }
};
+inline wxSize get_preferred_size(const wxBitmapBundle& bmp, wxWindow* parent)
+{
+ if (!bmp.IsOk())
+ return wxSize(0,0);
+#ifdef __WIN32__
+ return bmp.GetPreferredBitmapSizeFor(parent);
+#else
+ return bmp.GetDefaultSize();
+#endif
+}
+
// ----------------------------------------------------------------------------
// ScalableBitmap
@@ -141,8 +152,14 @@ class ScalableBitmap
public:
ScalableBitmap() {};
ScalableBitmap( wxWindow *parent,
- const std::string& icon_name = "",
- const int px_cnt = 16,
+ const std::string& icon_name,
+ const int width = 16,
+ const int height = -1 ,
+ const bool grayscale = false);
+
+ ScalableBitmap( wxWindow *parent,
+ const std::string& icon_name,
+ const wxSize icon_size,
const bool grayscale = false);
~ScalableBitmap() {}
@@ -153,15 +170,10 @@ public:
wxBitmap get_bitmap() { return m_bmp.GetBitmapFor(m_parent); }
wxWindow* parent() const { return m_parent;}
const std::string& name() const { return m_icon_name; }
- int px_cnt() const { return m_px_cnt;}
+ wxSize px_size() const { return wxSize(m_bmp_width, m_bmp_height);}
- wxSize GetSize() const {
-#ifdef __WIN32__
- return m_bmp.GetPreferredBitmapSizeFor(m_parent);
-#else
- return m_bmp.GetDefaultSize();
-#endif
- }
+ void SetBitmap(const wxBitmapBundle& bmp) { m_bmp = bmp; }
+ wxSize GetSize() const { return get_preferred_size(m_bmp, m_parent); }
int GetWidth() const { return GetSize().GetWidth(); }
int GetHeight() const { return GetSize().GetHeight(); }
@@ -170,7 +182,8 @@ private:
wxBitmapBundle m_bmp = wxBitmapBundle();
wxBitmap m_bitmap = wxBitmap();
std::string m_icon_name = "";
- int m_px_cnt {16};
+ int m_bmp_width{ 16 };
+ int m_bmp_height{ -1 };
};
@@ -229,7 +242,8 @@ public:
const wxSize& size = wxDefaultSize,
const wxPoint& pos = wxDefaultPosition,
long style = wxBU_EXACTFIT | wxNO_BORDER,
- int bmp_px_cnt = 16);
+ int width = 16,
+ int height = -1);
ScalableButton(
wxWindow * parent,
@@ -256,7 +270,8 @@ private:
protected:
// bitmap dimensions
- int m_px_cnt{ 16 };
+ int m_bmp_width{ 16 };
+ int m_bmp_height{ -1 };
bool m_has_border {false};
};