DarkMode for MSW (#6632)

* MSW specific: Dark Mode: First implementation

* Use menu instead of NoteBook

* Implemented MessageDialog
+ Fixed DarkMode for all dialogs and ColorPicker

* MSW DarkMode: Added missed updates for the switching between modes

* MSW DarkMode: Updated all existed context menus after switching of the mode
+ Added markers for the menu item witch is related to the selected tab

* Used wxFrame instead of wxDialog for SettingsDialog
(this change allow us to use menu bar in SettingsDialog)

+ fix for #6548 - Prusa Slicer 2.3.1 not activating non-modal settings window if settings window is minimized

* Implemented "Always use Dark mode colors" preference option

* Fixes for non_MSW build

* Next fixes for non-MSW builds

* Preferences: Fixed selection of the Settings Layout for non-MSW platforms
+ Updated DarkMode for colorpickers

* Windows DarkMode next fixes

* MSWDarkMode: Suppress to use system color to the PrusaSlicer
Select "Preferences -> Use Dark color mode (experimental)" to allow dark mode for the application

* Fixed MSW build

* MSWDarkMode: Upadteed color mode for ExtruderSequenceDialog and for dialogs related to the DoubleSlider

* Implemented Auto recreation of the PrusaSlicer when color mode is changed.

* Preferences: Added option "Set settings tabs as menu items (experimental)"
This commit is contained in:
Oleksandra Yushchenko 2021-06-18 19:46:04 +02:00 committed by GitHub
parent 65f440c2ba
commit fd071421cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 2011 additions and 443 deletions

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
<g id="compare_1_">
<g id="compare">
<path fill="#ED6B21" d="M7.87,2.23c-1.54-1.54-4.04-1.54-5.59,0s-1.54,4.04,0,5.59c1.43,1.43,3.69,1.53,5.24,0.31l1.33,1.33
c0,0-0.33,0.33,0,0.66c0.33,0.33,3.29,3.29,3.29,3.29s0.33,0.33,0.66,0c0.33-0.33,0.66-0.66,0.66-0.66s0.33-0.33,0-0.66
c-0.33-0.33-3.29-3.29-3.29-3.29c-0.33-0.33-0.66,0-0.66,0L8.18,7.47C9.41,5.92,9.3,3.67,7.87,2.23z M7.52,7.47
c-1.35,1.35-3.54,1.35-4.89,0s-1.35-3.54,0-4.89s3.54-1.35,4.89,0S8.87,6.12,7.52,7.47z"/>
</g>
<path fill="#FFFFFF" d="M7.49,4.35C7.43,4.16,7.36,3.97,7.26,3.8l0.18-0.54L6.85,2.67L6.31,2.85c-0.17-0.1-0.36-0.17-0.56-0.23
L5.5,2.11H4.66L4.41,2.62c-0.2,0.05-0.38,0.13-0.56,0.23L3.31,2.67L2.72,3.26L2.9,3.8C2.8,3.97,2.72,4.16,2.67,4.35L2.16,4.61v0.83
L2.67,5.7C2.72,5.9,2.8,6.08,2.9,6.26L2.72,6.8l0.59,0.59l0.54-0.18c0.17,0.1,0.36,0.17,0.56,0.23l0.26,0.51H5.5l0.26-0.51
c0.2-0.05,0.38-0.13,0.56-0.23l0.54,0.18L7.44,6.8L7.26,6.26C7.36,6.08,7.43,5.9,7.49,5.7L8,5.45V4.61L7.49,4.35z M5.08,6.33
c-0.72,0-1.3-0.58-1.3-1.3c0-0.72,0.58-1.3,1.3-1.3s1.3,0.58,1.3,1.3C6.38,5.75,5.8,6.33,5.08,6.33z"/>
<path fill="#FFFFFF" d="M14.56,4.45c-0.05-0.17-0.11-0.33-0.2-0.48l0.15-0.46l-0.51-0.51l-0.46,0.15c-0.15-0.08-0.31-0.15-0.48-0.2
l-0.22-0.44h-0.71l-0.22,0.44c-0.17,0.05-0.33,0.11-0.48,0.2l-0.46-0.15l-0.51,0.51l0.15,0.46c-0.08,0.15-0.15,0.31-0.2,0.48
L10,4.67v0.71l0.44,0.22c0.05,0.17,0.11,0.33,0.2,0.48l-0.15,0.46l0.51,0.51l0.46-0.15c0.15,0.08,0.31,0.15,0.48,0.2l0.22,0.44
h0.71l0.22-0.44c0.17-0.05,0.33-0.11,0.48-0.2l0.46,0.15l0.51-0.51l-0.15-0.46c0.08-0.15,0.15-0.31,0.2-0.48L15,5.39V4.67
L14.56,4.45z M12.5,6.14c-0.62,0-1.11-0.5-1.11-1.11c0-0.62,0.5-1.11,1.11-1.11s1.11,0.5,1.11,1.11
C13.61,5.64,13.11,6.14,12.5,6.14z"/>
<path fill="#FFFFFF" d="M7.14,11.91c-0.05-0.17-0.11-0.33-0.2-0.48l0.15-0.46l-0.51-0.51l-0.46,0.15c-0.15-0.08-0.31-0.15-0.48-0.2
L5.44,9.99H4.72L4.5,10.43c-0.17,0.05-0.33,0.11-0.48,0.2l-0.46-0.15l-0.51,0.51l0.15,0.46c-0.08,0.15-0.15,0.31-0.2,0.48
l-0.44,0.22v0.71l0.44,0.22c0.05,0.17,0.11,0.33,0.2,0.48L3.06,14l0.51,0.51l0.46-0.15c0.15,0.08,0.31,0.15,0.48,0.2l0.22,0.44
h0.71l0.22-0.44c0.17-0.05,0.33-0.11,0.48-0.2l0.46,0.15L7.1,14l-0.15-0.46c0.08-0.15,0.15-0.31,0.2-0.48l0.44-0.22v-0.71
L7.14,11.91z M5.08,13.6c-0.62,0-1.11-0.5-1.11-1.11c0-0.62,0.5-1.11,1.11-1.11s1.11,0.5,1.11,1.11C6.19,13.11,5.69,13.6,5.08,13.6
z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="121.805px" height="121.805px" viewBox="0 0 121.805 121.805" style="enable-background:new 0 0 121.805 121.805;"
xml:space="preserve">
<g>
<g>
<path fill="#FFFFFF" d="M7.308,85.264h107.188c4.037,0,7.309-3.271,7.309-7.31s-3.271-7.309-7.309-7.309H7.308C3.271,70.646,0,73.916,0,77.954
S3.271,85.264,7.308,85.264z"/>
<path fill="#FFFFFF" d="M7.308,51.158h107.188c4.037,0,7.309-3.272,7.309-7.309c0-4.037-3.271-7.308-7.309-7.308H7.308
C3.271,36.541,0,39.812,0,43.849C0,47.886,3.271,51.158,7.308,51.158z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 901 B

View File

@ -75,6 +75,12 @@ void AppConfig::set_defaults()
set("associate_3mf", "0"); set("associate_3mf", "0");
if (get("associate_stl").empty()) if (get("associate_stl").empty())
set("associate_stl", "0"); set("associate_stl", "0");
if (get("dark_color_mode").empty())
set("dark_color_mode", "0");
if (get("tabs_as_menu").empty())
set("tabs_as_menu", "0");
#endif // _WIN32 #endif // _WIN32
// remove old 'use_legacy_opengl' parameter from this config, if present // remove old 'use_legacy_opengl' parameter from this config, if present

View File

@ -91,6 +91,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Plater.hpp GUI/Plater.hpp
GUI/PresetComboBoxes.hpp GUI/PresetComboBoxes.hpp
GUI/PresetComboBoxes.cpp GUI/PresetComboBoxes.cpp
GUI/BitmapComboBox.hpp
GUI/BitmapComboBox.cpp
GUI/SavePresetDialog.hpp GUI/SavePresetDialog.hpp
GUI/SavePresetDialog.cpp GUI/SavePresetDialog.cpp
GUI/PhysicalPrinterDialog.hpp GUI/PhysicalPrinterDialog.hpp

View File

@ -33,7 +33,11 @@ void Bed_2D::repaint(const std::vector<Vec2d>& shape)
// On MacOS the background is erased, on Windows the background is not erased // On MacOS the background is erased, on Windows the background is not erased
// and on Linux / GTK the background is erased to gray color. // and on Linux / GTK the background is erased to gray color.
// Fill DC with the background on Windows & Linux / GTK. // Fill DC with the background on Windows & Linux / GTK.
#ifdef _WIN32
auto color = wxGetApp().get_highlight_default_clr();
#else
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); //GetSystemColour auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); //GetSystemColour
#endif
dc.SetPen(*new wxPen(color, 1, wxPENSTYLE_SOLID)); dc.SetPen(*new wxPen(color, 1, wxPENSTYLE_SOLID));
dc.SetBrush(*new wxBrush(color, wxBRUSHSTYLE_SOLID)); dc.SetBrush(*new wxBrush(color, wxBRUSHSTYLE_SOLID));
auto rect = GetUpdateRegion().GetBox(); auto rect = GetUpdateRegion().GetBox();

View File

@ -46,7 +46,11 @@ CopyrightsDialog::CopyrightsDialog()
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
this->SetFont(wxGetApp().normal_font()); this->SetFont(wxGetApp().normal_font());
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this);
#else
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
auto sizer = new wxBoxSizer(wxVERTICAL); auto sizer = new wxBoxSizer(wxVERTICAL);
@ -68,6 +72,7 @@ CopyrightsDialog::CopyrightsDialog()
m_html->Bind(wxEVT_HTML_LINK_CLICKED, &CopyrightsDialog::onLinkClicked, this); m_html->Bind(wxEVT_HTML_LINK_CLICKED, &CopyrightsDialog::onLinkClicked, this);
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE); wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CLOSE, this)));
this->SetEscapeId(wxID_CLOSE); this->SetEscapeId(wxID_CLOSE);
this->Bind(wxEVT_BUTTON, &CopyrightsDialog::onCloseDialog, this, wxID_CLOSE); this->Bind(wxEVT_BUTTON, &CopyrightsDialog::onCloseDialog, this, wxID_CLOSE);
@ -124,9 +129,9 @@ void CopyrightsDialog::fill_entries()
wxString CopyrightsDialog::get_html_text() wxString CopyrightsDialog::get_html_text()
{ {
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); wxColour bgr_clr = wxGetApp().get_window_default_clr();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); const auto text_clr = wxGetApp().get_label_clr_default();// wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
@ -206,7 +211,7 @@ AboutDialog::AboutDialog()
{ {
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); wxColour bgr_clr = wxGetApp().get_window_default_clr();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
SetBackgroundColour(bgr_clr); SetBackgroundColour(bgr_clr);
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
@ -250,7 +255,7 @@ AboutDialog::AboutDialog()
{ {
m_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit())); m_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
wxFont font = get_default_font(this); wxFont font = get_default_font(this);
const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); const auto text_clr = wxGetApp().get_label_clr_default();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
@ -292,6 +297,7 @@ AboutDialog::AboutDialog()
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE); wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CLOSE, this)));
m_copy_rights_btn_id = NewControlId(); m_copy_rights_btn_id = NewControlId();
auto copy_rights_btn = new wxButton(this, m_copy_rights_btn_id, _L("Portions copyright")+dots); auto copy_rights_btn = new wxButton(this, m_copy_rights_btn_id, _L("Portions copyright")+dots);
@ -303,6 +309,9 @@ AboutDialog::AboutDialog()
buttons->Insert(1, copy_version_btn, 0, wxLEFT, 5); buttons->Insert(1, copy_version_btn, 0, wxLEFT, 5);
copy_version_btn->Bind(wxEVT_BUTTON, &AboutDialog::onCopyToClipboard, this); copy_version_btn->Bind(wxEVT_BUTTON, &AboutDialog::onCopyToClipboard, this);
wxGetApp().UpdateDarkUI(copy_rights_btn);
wxGetApp().UpdateDarkUI(copy_version_btn);
this->SetEscapeId(wxID_CLOSE); this->SetEscapeId(wxID_CLOSE);
this->Bind(wxEVT_BUTTON, &AboutDialog::onCloseDialog, this, wxID_CLOSE); this->Bind(wxEVT_BUTTON, &AboutDialog::onCloseDialog, this, wxID_CLOSE);
vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3); vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);

View File

@ -177,6 +177,8 @@ void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup)
void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model) void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
{ {
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
// wxGetApp().UpdateDarkUI(this);
m_panel = new BedShapePanel(this); m_panel = new BedShapePanel(this);
m_panel->build_panel(default_pt, custom_texture, custom_model); m_panel->build_panel(default_pt, custom_texture, custom_model);
@ -184,6 +186,9 @@ void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const Co
main_sizer->Add(m_panel, 1, wxEXPAND); main_sizer->Add(m_panel, 1, wxEXPAND);
main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10); main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_OK, this)), true);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)), true);
SetSizer(main_sizer); SetSizer(main_sizer);
SetMinSize(GetSize()); SetMinSize(GetSize());
main_sizer->SetSizeHints(this); main_sizer->SetSizeHints(this);
@ -214,15 +219,19 @@ const std::string BedShapePanel::EMPTY_STRING = "";
void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model) void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
{ {
wxGetApp().UpdateDarkUI(this);
m_shape = default_pt.values; m_shape = default_pt.values;
m_custom_texture = custom_texture.value.empty() ? NONE : custom_texture.value; m_custom_texture = custom_texture.value.empty() ? NONE : custom_texture.value;
m_custom_model = custom_model.value.empty() ? NONE : custom_model.value; m_custom_model = custom_model.value.empty() ? NONE : custom_model.value;
auto sbsizer = new wxStaticBoxSizer(wxVERTICAL, this, _(L("Shape"))); auto sbsizer = new wxStaticBoxSizer(wxVERTICAL, this, _(L("Shape")));
sbsizer->GetStaticBox()->SetFont(wxGetApp().bold_font()); sbsizer->GetStaticBox()->SetFont(wxGetApp().bold_font());
wxGetApp().UpdateDarkUI(sbsizer->GetStaticBox());
// shape options // shape options
m_shape_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(25*wxGetApp().em_unit(), -1), wxCHB_TOP); m_shape_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(25*wxGetApp().em_unit(), -1), wxCHB_TOP);
wxGetApp().UpdateDarkUI(m_shape_options_book->GetChoiceCtrl());
sbsizer->Add(m_shape_options_book); sbsizer->Add(m_shape_options_book);
auto optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Rectangular)); auto optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Rectangular));
@ -240,6 +249,7 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
line.full_width = 1; line.full_width = 1;
line.widget = [this](wxWindow* parent) { line.widget = [this](wxWindow* parent) {
wxButton* shape_btn = new wxButton(parent, wxID_ANY, _L("Load shape from STL...")); wxButton* shape_btn = new wxButton(parent, wxID_ANY, _L("Load shape from STL..."));
wxGetApp().UpdateDarkUI(shape_btn, true);
wxSizer* shape_sizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* shape_sizer = new wxBoxSizer(wxHORIZONTAL);
shape_sizer->Add(shape_btn, 1, wxEXPAND); shape_sizer->Add(shape_btn, 1, wxEXPAND);
@ -311,6 +321,7 @@ void BedShapePanel::activate_options_page(ConfigOptionsGroupShp options_group)
wxPanel* BedShapePanel::init_texture_panel() wxPanel* BedShapePanel::init_texture_panel()
{ {
wxPanel* panel = new wxPanel(this); wxPanel* panel = new wxPanel(this);
wxGetApp().UpdateDarkUI(panel, true);
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Texture"))); ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Texture")));
optgroup->label_width = 10; optgroup->label_width = 10;
@ -322,21 +333,24 @@ wxPanel* BedShapePanel::init_texture_panel()
line.full_width = 1; line.full_width = 1;
line.widget = [this](wxWindow* parent) { line.widget = [this](wxWindow* parent) {
wxButton* load_btn = new wxButton(parent, wxID_ANY, _(L("Load..."))); wxButton* load_btn = new wxButton(parent, wxID_ANY, _(L("Load...")));
wxGetApp().UpdateDarkUI(load_btn, true);
wxSizer* load_sizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* load_sizer = new wxBoxSizer(wxHORIZONTAL);
load_sizer->Add(load_btn, 1, wxEXPAND); load_sizer->Add(load_btn, 1, wxEXPAND);
wxStaticText* filename_lbl = new wxStaticText(parent, wxID_ANY, _(NONE)); wxStaticText* filename_lbl = new wxStaticText(parent, wxID_ANY, _(NONE));
wxSizer* filename_sizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* filename_sizer = new wxBoxSizer(wxHORIZONTAL);
filename_sizer->Add(filename_lbl, 1, wxEXPAND); filename_sizer->Add(filename_lbl, 1, wxEXPAND);
wxButton* remove_btn = new wxButton(parent, wxID_ANY, _(L("Remove"))); wxButton* remove_btn = new wxButton(parent, wxID_ANY, _(L("Remove")));
wxGetApp().UpdateDarkUI(remove_btn, true);
wxSizer* remove_sizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* remove_sizer = new wxBoxSizer(wxHORIZONTAL);
remove_sizer->Add(remove_btn, 1, wxEXPAND); remove_sizer->Add(remove_btn, 1, wxEXPAND);
wxSizer* sizer = new wxBoxSizer(wxVERTICAL); wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(filename_sizer, 1, wxEXPAND); sizer->Add(filename_sizer, 1, wxEXPAND);
sizer->Add(load_sizer, 1, wxEXPAND); sizer->Add(load_sizer, 1, wxEXPAND);
sizer->Add(remove_sizer, 1, wxEXPAND); sizer->Add(remove_sizer, 1, wxEXPAND | wxTOP, 2);
load_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e) load_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e)
{ {
@ -356,7 +370,7 @@ wxPanel* BedShapePanel::init_texture_panel()
if (lbl != nullptr) if (lbl != nullptr)
{ {
bool exists = (m_custom_texture == NONE) || boost::filesystem::exists(m_custom_texture); bool exists = (m_custom_texture == NONE) || boost::filesystem::exists(m_custom_texture);
lbl->SetForegroundColour(exists ? wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) : wxColor(*wxRED)); lbl->SetForegroundColour(exists ? /*wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)*/wxGetApp().get_label_clr_default() : wxColor(*wxRED));
wxString tooltip_text = ""; wxString tooltip_text = "";
if (m_custom_texture != NONE) if (m_custom_texture != NONE)
@ -391,6 +405,7 @@ wxPanel* BedShapePanel::init_texture_panel()
wxPanel* BedShapePanel::init_model_panel() wxPanel* BedShapePanel::init_model_panel()
{ {
wxPanel* panel = new wxPanel(this); wxPanel* panel = new wxPanel(this);
wxGetApp().UpdateDarkUI(panel, true);
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Model"))); ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Model")));
optgroup->label_width = 10; optgroup->label_width = 10;
@ -402,6 +417,7 @@ wxPanel* BedShapePanel::init_model_panel()
line.full_width = 1; line.full_width = 1;
line.widget = [this](wxWindow* parent) { line.widget = [this](wxWindow* parent) {
wxButton* load_btn = new wxButton(parent, wxID_ANY, _(L("Load..."))); wxButton* load_btn = new wxButton(parent, wxID_ANY, _(L("Load...")));
wxGetApp().UpdateDarkUI(load_btn, true);
wxSizer* load_sizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* load_sizer = new wxBoxSizer(wxHORIZONTAL);
load_sizer->Add(load_btn, 1, wxEXPAND); load_sizer->Add(load_btn, 1, wxEXPAND);
@ -410,13 +426,14 @@ wxPanel* BedShapePanel::init_model_panel()
filename_sizer->Add(filename_lbl, 1, wxEXPAND); filename_sizer->Add(filename_lbl, 1, wxEXPAND);
wxButton* remove_btn = new wxButton(parent, wxID_ANY, _(L("Remove"))); wxButton* remove_btn = new wxButton(parent, wxID_ANY, _(L("Remove")));
wxGetApp().UpdateDarkUI(remove_btn, true);
wxSizer* remove_sizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* remove_sizer = new wxBoxSizer(wxHORIZONTAL);
remove_sizer->Add(remove_btn, 1, wxEXPAND); remove_sizer->Add(remove_btn, 1, wxEXPAND);
wxSizer* sizer = new wxBoxSizer(wxVERTICAL); wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(filename_sizer, 1, wxEXPAND); sizer->Add(filename_sizer, 1, wxEXPAND);
sizer->Add(load_sizer, 1, wxEXPAND); sizer->Add(load_sizer, 1, wxEXPAND);
sizer->Add(remove_sizer, 1, wxEXPAND); sizer->Add(remove_sizer, 1, wxEXPAND | wxTOP, 2);
load_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e) load_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e)
{ {
@ -436,7 +453,7 @@ wxPanel* BedShapePanel::init_model_panel()
if (lbl != nullptr) if (lbl != nullptr)
{ {
bool exists = (m_custom_model == NONE) || boost::filesystem::exists(m_custom_model); bool exists = (m_custom_model == NONE) || boost::filesystem::exists(m_custom_model);
lbl->SetForegroundColour(exists ? wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) : wxColor(*wxRED)); lbl->SetForegroundColour(exists ? /*wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)*/wxGetApp().get_label_clr_default() : wxColor(*wxRED));
wxString tooltip_text = ""; wxString tooltip_text = "";
if (m_custom_model != NONE) if (m_custom_model != NONE)

View File

@ -0,0 +1,266 @@
#include "BitmapComboBox.hpp"
#include <cstddef>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/statbox.h>
#include <wx/colordlg.h>
#include <wx/wupdlock.h>
#include <wx/menu.h>
#include <wx/odcombo.h>
#include <wx/listbook.h>
#include <wx/window.h>
#ifdef _WIN32
#include <wx/msw/dcclient.h>
#include <wx/msw/private.h>
#ifdef _MSW_DARK_MODE
#include <wx/msw/dark_mode.h>
#endif //_MSW_DARK_MODE
#endif
#include "libslic3r/libslic3r.h"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "MainFrame.hpp"
#include "format.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__)
#include <glib-2.0/glib-object.h>
#include <pango-1.0/pango/pango-layout.h>
#include <gtk/gtk.h>
#endif
using Slic3r::GUI::format_wxstr;
#define BORDER_W 10
// ---------------------------------
// *** BitmapComboBox ***
// ---------------------------------
namespace Slic3r {
namespace GUI {
/* For PresetComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina
* (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean
* "please scale this to such and such" but rather
* "the wxImage is already sized for backing scale such and such". )
* Unfortunately, the constructor changes the size of wxBitmap too.
* Thus We need to use unscaled size value for bitmaps that we use
* to avoid scaled size of control items.
* For this purpose control drawing methods and
* control size calculation methods (virtual) are overridden.
**/
BitmapComboBox::BitmapComboBox(wxWindow* parent,
wxWindowID id/* = wxID_ANY*/,
const wxString& value/* = wxEmptyString*/,
const wxPoint& pos/* = wxDefaultPosition*/,
const wxSize& size/* = wxDefaultSize*/,
int n/* = 0*/,
const wxString choices[]/* = NULL*/,
long style/* = 0*/) :
wxBitmapComboBox(parent, id, value, pos, size, n, choices, style)
{
SetFont(Slic3r::GUI::wxGetApp().normal_font());
#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);
wxGetApp().UpdateDarkUI(this);
if (!HasFlag(wxCB_READONLY))
wxTextEntry::SetMargins(0,0);
#endif /* _WIN32 */
}
BitmapComboBox::~BitmapComboBox()
{
}
#ifdef __APPLE__
bool BitmapComboBox::OnAddBitmap(const wxBitmap& bitmap)
{
if (bitmap.IsOk())
{
// we should use scaled! size values of bitmap
int width = (int)bitmap.GetScaledWidth();
int height = (int)bitmap.GetScaledHeight();
if (m_usedImgSize.x < 0)
{
// If size not yet determined, get it from this image.
m_usedImgSize.x = width;
m_usedImgSize.y = height;
// Adjust control size to vertically fit the bitmap
wxWindow* ctrl = GetControl();
ctrl->InvalidateBestSize();
wxSize newSz = ctrl->GetBestSize();
wxSize sz = ctrl->GetSize();
if (newSz.y > sz.y)
ctrl->SetSize(sz.x, newSz.y);
else
DetermineIndent();
}
wxCHECK_MSG(width == m_usedImgSize.x && height == m_usedImgSize.y,
false,
"you can only add images of same size");
return true;
}
return false;
}
void BitmapComboBox::OnDrawItem(wxDC& dc,
const wxRect& rect,
int item,
int flags) const
{
const wxBitmap& bmp = *(static_cast<wxBitmap*>(m_bitmaps[item]));
if (bmp.IsOk())
{
// we should use scaled! size values of bitmap
wxCoord w = bmp.GetScaledWidth();
wxCoord h = bmp.GetScaledHeight();
const int imgSpacingLeft = 4;
// Draw the image centered
dc.DrawBitmap(bmp,
rect.x + (m_usedImgSize.x - w) / 2 + imgSpacingLeft,
rect.y + (rect.height - h) / 2,
true);
}
wxString text = GetString(item);
if (!text.empty())
dc.DrawText(text,
rect.x + m_imgAreaWidth + 1,
rect.y + (rect.height - dc.GetCharHeight()) / 2);
}
#endif
#ifdef _WIN32
int BitmapComboBox::Append(const wxString& item)
{
// Workaround for a correct rendering of the control without Bitmap (under MSW):
//1. We should create small Bitmap to fill Bitmaps RefData,
// ! in this case wxBitmap.IsOK() return true.
//2. But then set width to 0 value for no using of bitmap left and right spacing
//3. Set this empty bitmap to the at list one item and BitmapCombobox will be recreated correct
wxBitmap bitmap(1, this->GetFont().GetPixelSize().y + 2);
bitmap.SetWidth(0);
OnAddBitmap(bitmap);
const int n = wxComboBox::Append(item);
if (n != wxNOT_FOUND)
DoSetItemBitmap(n, bitmap);
return n;
}
enum OwnerDrawnComboBoxPaintingFlags
{
ODCB_PAINTING_DISABLED = 0x0004,
};
bool BitmapComboBox::MSWOnDraw(WXDRAWITEMSTRUCT* item)
{
LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT)item;
int pos = lpDrawItem->itemID;
// Draw default for item -1, which means 'focus rect only'
if (pos == -1)
return false;
int flags = 0;
if (lpDrawItem->itemState & ODS_COMBOBOXEDIT)
flags |= wxODCB_PAINTING_CONTROL;
if (lpDrawItem->itemState & ODS_SELECTED)
flags |= wxODCB_PAINTING_SELECTED;
if (lpDrawItem->itemState & ODS_DISABLED)
flags |= ODCB_PAINTING_DISABLED;
wxPaintDCEx dc(this, lpDrawItem->hDC);
wxRect rect = wxRectFromRECT(lpDrawItem->rcItem);
DrawBackground_(dc, rect, pos, flags);
wxString text;
if (flags & wxODCB_PAINTING_CONTROL)
{
// Don't draw anything in the editable selection field.
//if (!HasFlag(wxCB_READONLY))
// return true;
pos = GetSelection();
// Skip drawing if there is nothing selected.
if (pos < 0)
return true;
text = GetValue();
}
else
{
text = GetString(pos);
}
wxBitmapComboBoxBase::DrawItem(dc, rect, pos, text, flags);
return true;
}
void BitmapComboBox::DrawBackground_(wxDC& dc, const wxRect& rect, int WXUNUSED(item), int flags) const
{
if (flags & wxODCB_PAINTING_SELECTED)
{
const int vSizeDec = 0; // Vertical size reduction of selection rectangle edges
dc.SetTextForeground(wxGetApp().get_label_highlight_clr());
wxColour selCol = wxGetApp().get_highlight_default_clr();
dc.SetPen(selCol);
dc.SetBrush(selCol);
dc.DrawRectangle(rect.x,
rect.y + vSizeDec,
rect.width,
rect.height - (vSizeDec * 2));
}
else
{
dc.SetTextForeground(flags & ODCB_PAINTING_DISABLED ? wxColour(108,108,108) : wxGetApp().get_label_clr_default());
wxColour selCol = flags & ODCB_PAINTING_DISABLED ?
#ifdef _MSW_DAEK_MODE
wxRGBToColour(NppDarkMode::InvertLightnessSofter(NppDarkMode::GetBackgroundColor())) :
#else
wxGetApp().get_highlight_default_clr() :
#endif
wxGetApp().get_window_default_clr();
dc.SetPen(selCol);
dc.SetBrush(selCol);
dc.DrawRectangle(rect);
}
}
#endif
}}

View File

@ -0,0 +1,62 @@
#ifndef slic3r_BitmapComboBox_hpp_
#define slic3r_BitmapComboBox_hpp_
#include <wx/bmpcbox.h>
#include <wx/gdicmn.h>
#include "GUI_Utils.hpp"
// ---------------------------------
// *** BitmapComboBox ***
// ---------------------------------
namespace Slic3r {
namespace GUI {
// BitmapComboBox used to presets list on Sidebar and Tabs
class BitmapComboBox : public wxBitmapComboBox
{
public:
BitmapComboBox(wxWindow* parent,
wxWindowID id = wxID_ANY,
const wxString& value = wxEmptyString,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
int n = 0,
const wxString choices[] = NULL,
long style = 0);
~BitmapComboBox();
#ifdef _WIN32
int Append(const wxString& item);
#endif
int Append(const wxString& item, const wxBitmap& bitmap)
{
return wxBitmapComboBox::Append(item, bitmap);
}
protected:
#ifdef __APPLE__
/* For PresetComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina
* (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean
* "please scale this to such and such" but rather
* "the wxImage is already sized for backing scale such and such". )
* Unfortunately, the constructor changes the size of wxBitmap too.
* Thus We need to use unscaled size value for bitmaps that we use
* to avoid scaled size of control items.
* For this purpose control drawing methods and
* control size calculation methods (virtual) are overridden.
**/
bool OnAddBitmap(const wxBitmap& bitmap) override;
void OnDrawItem(wxDC& dc, const wxRect& rect, int item, int flags) const override;
#endif
#ifdef _WIN32
bool MSWOnDraw(WXDRAWITEMSTRUCT* item) override;
void DrawBackground_(wxDC& dc, const wxRect& rect, int WXUNUSED(item), int flags) const;
#endif
};
}}
#endif

View File

@ -16,6 +16,8 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, const std::vector<Entry
wxDialog(parent, wxID_ANY, _(L("Buttons And Text Colors Description")), wxDefaultPosition, wxDefaultSize), wxDialog(parent, wxID_ANY, _(L("Buttons And Text Colors Description")), wxDefaultPosition, wxDefaultSize),
m_entries(entries) m_entries(entries)
{ {
wxGetApp().UpdateDarkUI(this);
auto grid_sizer = new wxFlexGridSizer(3, 20, 20); auto grid_sizer = new wxFlexGridSizer(3, 20, 20);
auto main_sizer = new wxBoxSizer(wxVERTICAL); auto main_sizer = new wxBoxSizer(wxVERTICAL);
@ -36,6 +38,7 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, const std::vector<Entry
auto sys_label = new wxStaticText(this, wxID_ANY, _(L("Value is the same as the system value"))); auto sys_label = new wxStaticText(this, wxID_ANY, _(L("Value is the same as the system value")));
sys_label->SetForegroundColour(wxGetApp().get_label_clr_sys()); sys_label->SetForegroundColour(wxGetApp().get_label_clr_sys());
auto sys_colour = new wxColourPickerCtrl(this, wxID_ANY, wxGetApp().get_label_clr_sys()); auto sys_colour = new wxColourPickerCtrl(this, wxID_ANY, wxGetApp().get_label_clr_sys());
wxGetApp().UpdateDarkUI(sys_colour->GetPickerCtrl(), true);
sys_colour->Bind(wxEVT_COLOURPICKER_CHANGED, ([sys_colour, sys_label](wxCommandEvent e) sys_colour->Bind(wxEVT_COLOURPICKER_CHANGED, ([sys_colour, sys_label](wxCommandEvent e)
{ {
sys_label->SetForegroundColour(sys_colour->GetColour()); sys_label->SetForegroundColour(sys_colour->GetColour());
@ -53,6 +56,7 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, const std::vector<Entry
auto mod_label = new wxStaticText(this, wxID_ANY, _(L("Value was changed and is not equal to the system value or the last saved preset"))); auto mod_label = new wxStaticText(this, wxID_ANY, _(L("Value was changed and is not equal to the system value or the last saved preset")));
mod_label->SetForegroundColour(wxGetApp().get_label_clr_modified()); mod_label->SetForegroundColour(wxGetApp().get_label_clr_modified());
auto mod_colour = new wxColourPickerCtrl(this, wxID_ANY, wxGetApp().get_label_clr_modified()); auto mod_colour = new wxColourPickerCtrl(this, wxID_ANY, wxGetApp().get_label_clr_modified());
wxGetApp().UpdateDarkUI(mod_colour->GetPickerCtrl(), true);
mod_colour->Bind(wxEVT_COLOURPICKER_CHANGED, ([mod_colour, mod_label](wxCommandEvent e) mod_colour->Bind(wxEVT_COLOURPICKER_CHANGED, ([mod_colour, mod_label](wxCommandEvent e)
{ {
mod_label->SetForegroundColour(mod_colour->GetColour()); mod_label->SetForegroundColour(mod_colour->GetColour());
@ -67,6 +71,8 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, const std::vector<Entry
main_sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10); main_sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this)); wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
wxGetApp().UpdateDarkUI(btn);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
btn->Bind(wxEVT_BUTTON, [sys_colour, mod_colour, this](wxCommandEvent&) { btn->Bind(wxEVT_BUTTON, [sys_colour, mod_colour, this](wxCommandEvent&) {
wxGetApp().set_label_clr_sys(sys_colour->GetColour()); wxGetApp().set_label_clr_sys(sys_colour->GetColour());
wxGetApp().set_label_clr_modified(mod_colour->GetColour()); wxGetApp().set_label_clr_modified(mod_colour->GetColour());

View File

@ -5,6 +5,7 @@
#include "format.hpp" #include "format.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
#include "libslic3r/PresetBundle.hpp" #include "libslic3r/PresetBundle.hpp"
#include "MsgDialog.hpp"
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
@ -46,7 +47,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
if (config->opt_float("layer_height") < EPSILON) if (config->opt_float("layer_height") < EPSILON)
{ {
const wxString msg_text = _(L("Layer height is not valid.\n\nThe layer height will be reset to 0.01.")); const wxString msg_text = _(L("Layer height is not valid.\n\nThe layer height will be reset to 0.01."));
wxMessageDialog dialog(nullptr, msg_text, _(L("Layer height")), wxICON_WARNING | wxOK); //wxMessageDialog dialog(nullptr, msg_text, _(L("Layer height")), wxICON_WARNING | wxOK);
MessageDialog dialog(nullptr, msg_text, _(L("Layer height")), wxICON_WARNING | wxOK);
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
is_msg_dlg_already_exist = true; is_msg_dlg_already_exist = true;
dialog.ShowModal(); dialog.ShowModal();
@ -58,7 +60,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
if (config->option<ConfigOptionFloatOrPercent>("first_layer_height")->value < EPSILON) if (config->option<ConfigOptionFloatOrPercent>("first_layer_height")->value < EPSILON)
{ {
const wxString msg_text = _(L("First layer height is not valid.\n\nThe first layer height will be reset to 0.01.")); const wxString msg_text = _(L("First layer height is not valid.\n\nThe first layer height will be reset to 0.01."));
wxMessageDialog dialog(nullptr, msg_text, _(L("First layer height")), wxICON_WARNING | wxOK); //wxMessageDialog dialog(nullptr, msg_text, _(L("First layer height")), wxICON_WARNING | wxOK);
MessageDialog dialog(nullptr, msg_text, _(L("First layer height")), wxICON_WARNING | wxOK);
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
is_msg_dlg_already_exist = true; is_msg_dlg_already_exist = true;
dialog.ShowModal(); dialog.ShowModal();
@ -87,7 +90,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
"- Detect thin walls disabled")); "- Detect thin walls disabled"));
if (is_global_config) if (is_global_config)
msg_text += "\n\n" + _(L("Shall I adjust those settings in order to enable Spiral Vase?")); msg_text += "\n\n" + _(L("Shall I adjust those settings in order to enable Spiral Vase?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Spiral Vase")), //wxMessageDialog dialog(nullptr, msg_text, _(L("Spiral Vase")),
MessageDialog dialog(nullptr, msg_text, _(L("Spiral Vase")),
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK)); wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal(); auto answer = dialog.ShowModal();
@ -122,7 +126,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
"(both support_material_extruder and support_material_interface_extruder need to be set to 0).")); "(both support_material_extruder and support_material_interface_extruder need to be set to 0)."));
if (is_global_config) if (is_global_config)
msg_text += "\n\n" + _(L("Shall I adjust those settings in order to enable the Wipe Tower?")); msg_text += "\n\n" + _(L("Shall I adjust those settings in order to enable the Wipe Tower?"));
wxMessageDialog dialog (nullptr, msg_text, _(L("Wipe Tower")), //wxMessageDialog dialog (nullptr, msg_text, _(L("Wipe Tower")),
MessageDialog dialog (nullptr, msg_text, _(L("Wipe Tower")),
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK)); wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal(); auto answer = dialog.ShowModal();
@ -142,7 +147,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
"need to be synchronized with the object layers.")); "need to be synchronized with the object layers."));
if (is_global_config) if (is_global_config)
msg_text += "\n\n" + _(L("Shall I synchronize support layers in order to enable the Wipe Tower?")); msg_text += "\n\n" + _(L("Shall I synchronize support layers in order to enable the Wipe Tower?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Wipe Tower")), //wxMessageDialog dialog(nullptr, msg_text, _(L("Wipe Tower")),
MessageDialog dialog(nullptr, msg_text, _(L("Wipe Tower")),
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK)); wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal(); auto answer = dialog.ShowModal();
@ -165,7 +171,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
"- Detect bridging perimeters")); "- Detect bridging perimeters"));
if (is_global_config) if (is_global_config)
msg_text += "\n\n" + _(L("Shall I adjust those settings for supports?")); msg_text += "\n\n" + _(L("Shall I adjust those settings for supports?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Support Generator")), //wxMessageDialog dialog(nullptr, msg_text, _(L("Support Generator")),
MessageDialog dialog(nullptr, msg_text, _(L("Support Generator")),
wxICON_WARNING | (is_global_config ? wxYES | wxNO | wxCANCEL : wxOK)); wxICON_WARNING | (is_global_config ? wxYES | wxNO | wxCANCEL : wxOK));
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal(); auto answer = dialog.ShowModal();
@ -204,7 +211,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
_(fill_pattern_def->enum_labels[it_pattern - fill_pattern_def->enum_values.begin()])); _(fill_pattern_def->enum_labels[it_pattern - fill_pattern_def->enum_values.begin()]));
if (is_global_config) if (is_global_config)
msg_text += "\n\n" + _L("Shall I switch to rectilinear fill pattern?"); msg_text += "\n\n" + _L("Shall I switch to rectilinear fill pattern?");
wxMessageDialog dialog(nullptr, msg_text, _L("Infill"), //wxMessageDialog dialog(nullptr, msg_text, _L("Infill"),
MessageDialog dialog(nullptr, msg_text, _L("Infill"),
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) ); wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) );
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal(); auto answer = dialog.ShowModal();
@ -333,7 +341,8 @@ void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, con
if (head_penetration > head_width) { if (head_penetration > head_width) {
wxString msg_text = _(L("Head penetration should not be greater than the head width.")); wxString msg_text = _(L("Head penetration should not be greater than the head width."));
wxMessageDialog dialog(nullptr, msg_text, _(L("Invalid Head penetration")), wxICON_WARNING | wxOK); //wxMessageDialog dialog(nullptr, msg_text, _(L("Invalid Head penetration")), wxICON_WARNING | wxOK);
MessageDialog dialog(nullptr, msg_text, _(L("Invalid Head penetration")), wxICON_WARNING | wxOK);
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
if (dialog.ShowModal() == wxID_OK) { if (dialog.ShowModal() == wxID_OK) {
new_conf.set_key_value("support_head_penetration", new ConfigOptionFloat(head_width)); new_conf.set_key_value("support_head_penetration", new ConfigOptionFloat(head_width));
@ -346,7 +355,8 @@ void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, con
if (pinhead_d > pillar_d) { if (pinhead_d > pillar_d) {
wxString msg_text = _(L("Pinhead diameter should be smaller than the pillar diameter.")); wxString msg_text = _(L("Pinhead diameter should be smaller than the pillar diameter."));
wxMessageDialog dialog(nullptr, msg_text, _(L("Invalid pinhead diameter")), wxICON_WARNING | wxOK); //wxMessageDialog dialog(nullptr, msg_text, _(L("Invalid pinhead diameter")), wxICON_WARNING | wxOK);
MessageDialog dialog(nullptr, msg_text, _(L("Invalid pinhead diameter")), wxICON_WARNING | wxOK);
DynamicPrintConfig new_conf = *config; DynamicPrintConfig new_conf = *config;
if (dialog.ShowModal() == wxID_OK) { if (dialog.ShowModal() == wxID_OK) {

View File

@ -42,7 +42,7 @@ static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_eve
wxString text = "<tr bgcolor=\""; wxString text = "<tr bgcolor=\"";
text += snapshot_active ? text += snapshot_active ?
dark_mode ? "#208a20" : "#B3FFCB" : dark_mode ? "#208a20" : "#B3FFCB" :
(row_even ? get_color(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) : dark_mode ? "#656565" : "#D5D5D5" ); (row_even ? get_color(wxGetApp().get_window_default_clr()/*wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)*/) : dark_mode ? "#656565" : "#D5D5D5" );
text += "\">"; text += "\">";
text += "<td>"; text += "<td>";
@ -104,8 +104,8 @@ static wxString generate_html_page(const Config::SnapshotDB &snapshot_db, const
bool dark_mode = wxGetApp().dark_mode(); bool dark_mode = wxGetApp().dark_mode();
wxString text = wxString text =
"<html>" "<html>"
"<body bgcolor=\"" + get_color(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) + "\" cellspacing=\"2\" cellpadding=\"0\" border=\"0\" link=\"#800000\">" "<body bgcolor=\"" + get_color(wxGetApp().get_window_default_clr()/*wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)*/) + "\" cellspacing=\"2\" cellpadding=\"0\" border=\"0\" link=\"#800000\">"
"<font color=\"" + get_color(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)) + "\">"; "<font color=\"" + get_color(wxGetApp().get_label_clr_default()/*wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)*/) + "\">";
text += "<table style=\"width:100%\">"; text += "<table style=\"width:100%\">";
for (size_t i_row = 0; i_row < snapshot_db.snapshots().size(); ++ i_row) { for (size_t i_row = 0; i_row < snapshot_db.snapshots().size(); ++ i_row) {
const Config::Snapshot &snapshot = snapshot_db.snapshots()[snapshot_db.snapshots().size() - i_row - 1]; const Config::Snapshot &snapshot = snapshot_db.snapshots()[snapshot_db.snapshots().size() - i_row - 1];
@ -125,7 +125,11 @@ ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX) wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
{ {
this->SetFont(wxGetApp().normal_font()); this->SetFont(wxGetApp().normal_font());
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this);
#else
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
this->SetSizer(vsizer); this->SetSizer(vsizer);
@ -152,6 +156,7 @@ ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db
} }
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE); wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CLOSE, this)));
this->SetEscapeId(wxID_CLOSE); this->SetEscapeId(wxID_CLOSE);
this->Bind(wxEVT_BUTTON, &ConfigSnapshotDialog::onCloseDialog, this, wxID_CLOSE); this->Bind(wxEVT_BUTTON, &ConfigSnapshotDialog::onCloseDialog, this, wxID_CLOSE);
vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3); vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);

View File

@ -21,6 +21,7 @@
#include <wx/statline.h> #include <wx/statline.h>
#include <wx/dataview.h> #include <wx/dataview.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/listbook.h>
#include <wx/display.h> #include <wx/display.h>
#include <wx/filefn.h> #include <wx/filefn.h>
#include <wx/wupdlock.h> #include <wx/wupdlock.h>
@ -38,6 +39,7 @@
#include "slic3r/Config/Snapshot.hpp" #include "slic3r/Config/Snapshot.hpp"
#include "slic3r/Utils/PresetUpdater.hpp" #include "slic3r/Utils/PresetUpdater.hpp"
#include "format.hpp" #include "format.hpp"
#include "MsgDialog.hpp"
#if defined(__linux__) && defined(__WXGTK3__) #if defined(__linux__) && defined(__WXGTK3__)
#define wxLinux_gtk3 true #define wxLinux_gtk3 true
@ -177,6 +179,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
, vendor_id(vendor.id) , vendor_id(vendor.id)
, width(0) , width(0)
{ {
wxGetApp().UpdateDarkUI(this);
const auto &models = vendor.models; const auto &models = vendor.models;
auto *sizer = new wxBoxSizer(wxVERTICAL); auto *sizer = new wxBoxSizer(wxVERTICAL);
@ -235,6 +238,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
bitmaps.push_back(bitmap_widget); bitmaps.push_back(bitmap_widget);
auto *variants_panel = new wxPanel(this); auto *variants_panel = new wxPanel(this);
wxGetApp().UpdateDarkUI(variants_panel);
auto *variants_sizer = new wxBoxSizer(wxVERTICAL); auto *variants_sizer = new wxBoxSizer(wxVERTICAL);
variants_panel->SetSizer(variants_sizer); variants_panel->SetSizer(variants_sizer);
const auto model_id = model.id; const auto model_id = model.id;
@ -323,6 +327,10 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
title_sizer->Add(sel_all, 0, wxRIGHT, BTN_SPACING); title_sizer->Add(sel_all, 0, wxRIGHT, BTN_SPACING);
title_sizer->Add(sel_none); title_sizer->Add(sel_none);
wxGetApp().UpdateDarkUI(sel_all_std);
wxGetApp().UpdateDarkUI(sel_all);
wxGetApp().UpdateDarkUI(sel_none);
// fill button indexes used later for buttons rescaling // fill button indexes used later for buttons rescaling
if (is_variants) if (is_variants)
m_button_indexes = { sel_all_std->GetId(), sel_all->GetId(), sel_none->GetId() }; m_button_indexes = { sel_all_std->GetId(), sel_all->GetId(), sel_none->GetId() };
@ -412,6 +420,8 @@ ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxStrin
, shortname(std::move(shortname)) , shortname(std::move(shortname))
, indent(indent) , indent(indent)
{ {
wxGetApp().UpdateDarkUI(this);
auto *sizer = new wxBoxSizer(wxVERTICAL); auto *sizer = new wxBoxSizer(wxVERTICAL);
auto *text = new wxStaticText(this, wxID_ANY, std::move(title), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); auto *text = new wxStaticText(this, wxID_ANY, std::move(title), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
@ -637,6 +647,11 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
btn_sizer->Add(sel_all, 0, wxRIGHT, em / 2); btn_sizer->Add(sel_all, 0, wxRIGHT, em / 2);
btn_sizer->Add(sel_none); btn_sizer->Add(sel_none);
wxGetApp().UpdateDarkUI(list_printer);
wxGetApp().UpdateDarkUI(list_type);
wxGetApp().UpdateDarkUI(list_vendor);
wxGetApp().UpdateDarkUI(sel_all);
wxGetApp().UpdateDarkUI(sel_none);
grid->Add(new wxBoxSizer(wxHORIZONTAL)); grid->Add(new wxBoxSizer(wxHORIZONTAL));
grid->Add(new wxBoxSizer(wxHORIZONTAL)); grid->Add(new wxBoxSizer(wxHORIZONTAL));
@ -717,12 +732,16 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
{ {
const auto bgr_clr = const auto bgr_clr =
#if defined(__APPLE__) #if defined(__APPLE__)
wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); html_window->GetParent()->GetBackgroundColour();
#else
#if defined(_WIN32)
wxGetApp().get_window_default_clr();
#else #else
wxSystemSettings::GetColour(wxSYS_COLOUR_MENU); wxSystemSettings::GetColour(wxSYS_COLOUR_MENU);
#endif
#endif #endif
const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); const auto text_clr = wxGetApp().get_label_clr_default();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
wxString first_line = _L("Filaments marked with <b>*</b> are <b>not</b> compatible with some installed printers."); wxString first_line = _L("Filaments marked with <b>*</b> are <b>not</b> compatible with some installed printers.");
wxString text; wxString text;
@ -1003,6 +1022,7 @@ void PageMaterials::update_lists(int sel_type, int sel_vendor, int last_selected
sel_vendor_prev = sel_vendor; sel_vendor_prev = sel_vendor;
} }
wxGetApp().UpdateDarkUI(list_profile);
} }
void PageMaterials::sort_list_data(StringList* list, bool add_All_item, bool material_type_ordering) void PageMaterials::sort_list_data(StringList* list, bool add_All_item, bool material_type_ordering)
@ -1150,6 +1170,8 @@ PageCustom::PageCustom(ConfigWizard *parent)
tc_profile_name = new wxTextCtrl(this, wxID_ANY, default_profile_name); tc_profile_name = new wxTextCtrl(this, wxID_ANY, default_profile_name);
auto *label = new wxStaticText(this, wxID_ANY, _L("Custom profile name:")); auto *label = new wxStaticText(this, wxID_ANY, _L("Custom profile name:"));
wxGetApp().UpdateDarkUI(tc_profile_name);
tc_profile_name->Enable(false); tc_profile_name->Enable(false);
tc_profile_name->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &evt) { tc_profile_name->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &evt) {
if (tc_profile_name->GetValue().IsEmpty()) { if (tc_profile_name->GetValue().IsEmpty()) {
@ -1338,6 +1360,7 @@ PageFirmware::PageFirmware(ConfigWizard *parent)
} }
gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices); gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
wxGetApp().UpdateDarkUI(gcode_picker);
const auto &enum_values = gcode_opt.enum_values; const auto &enum_values = gcode_opt.enum_values;
auto needle = enum_values.cend(); auto needle = enum_values.cend();
if (gcode_opt.default_value) { if (gcode_opt.default_value) {
@ -1406,10 +1429,26 @@ static void focus_event(wxFocusEvent& e, wxTextCtrl* ctrl, double def_value)
ctrl->SetValue(double_to_string(val)); ctrl->SetValue(double_to_string(val));
} }
class DiamTextCtrl : public wxTextCtrl
{
public:
DiamTextCtrl(wxWindow* parent)
{
#ifdef _WIN32
long style = wxBORDER_SIMPLE;
#else
long style = 0;
#endif
Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(Field::def_width_thinner() * wxGetApp().em_unit(), wxDefaultCoord), style);
wxGetApp().UpdateDarkUI(this);
}
~DiamTextCtrl() {}
};
PageDiameters::PageDiameters(ConfigWizard *parent) PageDiameters::PageDiameters(ConfigWizard *parent)
: ConfigWizardPage(parent, _L("Filament and Nozzle Diameters"), _L("Print Diameters"), 1) : ConfigWizardPage(parent, _L("Filament and Nozzle Diameters"), _L("Print Diameters"), 1)
, diam_nozzle(new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(Field::def_width_thinner() * wxGetApp().em_unit(), wxDefaultCoord))) , diam_nozzle(new DiamTextCtrl(this))
, diam_filam (new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(Field::def_width_thinner() * wxGetApp().em_unit(), wxDefaultCoord))) , diam_filam (new DiamTextCtrl(this))
{ {
auto *default_nozzle = print_config_def.get("nozzle_diameter")->get_default_value<ConfigOptionFloats>(); auto *default_nozzle = print_config_def.get("nozzle_diameter")->get_default_value<ConfigOptionFloats>();
wxString value = double_to_string(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5); wxString value = double_to_string(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5);
@ -1477,10 +1516,29 @@ void PageDiameters::apply_custom_config(DynamicPrintConfig &config)
set_extrusion_width("solid_infill_extrusion_width", 0.45); set_extrusion_width("solid_infill_extrusion_width", 0.45);
} }
class SpinCtrlDouble: public wxSpinCtrlDouble
{
public:
SpinCtrlDouble(wxWindow* parent)
{
#ifdef _WIN32
long style = wxSP_ARROW_KEYS | wxBORDER_SIMPLE;
#else
long style = wxSP_ARROW_KEYS;
#endif
Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, style);
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this->GetText());
#endif
this->Refresh();
}
~SpinCtrlDouble() {}
};
PageTemperatures::PageTemperatures(ConfigWizard *parent) PageTemperatures::PageTemperatures(ConfigWizard *parent)
: ConfigWizardPage(parent, _L("Nozzle and Bed Temperatures"), _L("Temperatures"), 1) : ConfigWizardPage(parent, _L("Nozzle and Bed Temperatures"), _L("Temperatures"), 1)
, spin_extr(new wxSpinCtrlDouble(this, wxID_ANY)) , spin_extr(new SpinCtrlDouble(this))
, spin_bed(new wxSpinCtrlDouble(this, wxID_ANY)) , spin_bed (new SpinCtrlDouble(this))
{ {
spin_extr->SetIncrement(5.0); spin_extr->SetIncrement(5.0);
const auto &def_extr = *print_config_def.get("temperature"); const auto &def_extr = *print_config_def.get("temperature");
@ -1703,6 +1761,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
x += + bullet_w + em_w/2; x += + bullet_w + em_w/2;
const auto text_size = dc.GetTextExtent(item.label); const auto text_size = dc.GetTextExtent(item.label);
dc.SetTextForeground(wxGetApp().get_label_clr_default());
dc.DrawText(item.label, x, y + yoff_text); dc.DrawText(item.label, x, y + yoff_text);
y += yinc; y += yinc;
@ -2341,7 +2400,8 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo
const auto ask_and_select_default_materials = [this](const wxString &message, const std::set<const VendorProfile::PrinterModel*> &printer_models, Technology technology) const auto ask_and_select_default_materials = [this](const wxString &message, const std::set<const VendorProfile::PrinterModel*> &printer_models, Technology technology)
{ {
wxMessageDialog msg(q, message, _L("Notice"), wxYES_NO); //wxMessageDialog msg(q, message, _L("Notice"), wxYES_NO);
MessageDialog msg(q, message, _L("Notice"), wxYES_NO);
if (msg.ShowModal() == wxID_YES) if (msg.ShowModal() == wxID_YES)
select_default_materials_for_printer_models(technology, printer_models); select_default_materials_for_printer_models(technology, printer_models);
}; };
@ -2628,6 +2688,12 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
p->btnsizer->Add(p->btn_finish, 0, wxLEFT, BTN_SPACING); p->btnsizer->Add(p->btn_finish, 0, wxLEFT, BTN_SPACING);
p->btnsizer->Add(p->btn_cancel, 0, wxLEFT, BTN_SPACING); p->btnsizer->Add(p->btn_cancel, 0, wxLEFT, BTN_SPACING);
wxGetApp().UpdateDarkUI(p->btn_sel_all);
wxGetApp().UpdateDarkUI(p->btn_prev);
wxGetApp().UpdateDarkUI(p->btn_next);
wxGetApp().UpdateDarkUI(p->btn_finish);
wxGetApp().UpdateDarkUI(p->btn_cancel);
const auto prusa_it = p->bundles.find("PrusaResearch"); const auto prusa_it = p->bundles.find("PrusaResearch");
wxCHECK_RET(prusa_it != p->bundles.cend(), "Vendor PrusaResearch not found"); wxCHECK_RET(prusa_it != p->bundles.cend(), "Vendor PrusaResearch not found");
const VendorProfile *vendor_prusa = prusa_it->second.vendor_profile; const VendorProfile *vendor_prusa = prusa_it->second.vendor_profile;
@ -2798,5 +2864,11 @@ void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect)
Refresh(); Refresh();
} }
void ConfigWizard::on_sys_color_changed()
{
wxGetApp().UpdateDlgDarkUI(this);
Refresh();
}
} }
} }

View File

@ -47,6 +47,7 @@ public:
static const wxString& name(const bool from_menu = false); static const wxString& name(const bool from_menu = false);
protected: protected:
void on_dpi_changed(const wxRect &suggested_rect) override ; void on_dpi_changed(const wxRect &suggested_rect) override ;
void on_sys_color_changed() override;
private: private:
struct priv; struct priv;

View File

@ -165,6 +165,8 @@ void Control::msw_rescale()
void Control::sys_color_changed() void Control::sys_color_changed()
{ {
GUI::wxGetApp().UpdateDarkUI(GetParent());
m_bmp_add_tick_on .msw_rescale(); m_bmp_add_tick_on .msw_rescale();
m_bmp_add_tick_off.msw_rescale(); m_bmp_add_tick_off.msw_rescale();
m_bmp_del_tick_on .msw_rescale(); m_bmp_del_tick_on .msw_rescale();
@ -494,7 +496,7 @@ void Control::draw_focus_rect()
void Control::render() void Control::render()
{ {
#ifdef _WIN32 #ifdef _WIN32
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); GUI::wxGetApp().UpdateDarkUI(this);
#else #else
SetBackgroundColour(GetParent()->GetBackgroundColour()); SetBackgroundColour(GetParent()->GetBackgroundColour());
#endif // _WIN32 #endif // _WIN32
@ -990,11 +992,7 @@ void Control::draw_colored_band(wxDC& dc)
// don't color a band for MultiExtruder mode // don't color a band for MultiExtruder mode
if (m_ticks.empty() || m_mode == MultiExtruder) { if (m_ticks.empty() || m_mode == MultiExtruder) {
#ifdef _WIN32
draw_band(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW), main_band);
#else
draw_band(dc, GetParent()->GetBackgroundColour(), main_band); draw_band(dc, GetParent()->GetBackgroundColour(), main_band);
#endif // _WIN32
return; return;
} }
@ -1593,12 +1591,9 @@ void Control::append_change_extruder_menu_item(wxMenu* menu, bool switch_current
(switch_current_code ? _L("Switch code to Change extruder") : _L("Change extruder") ) : (switch_current_code ? _L("Switch code to Change extruder") : _L("Change extruder") ) :
_L("Change extruder (N/A)"); _L("Change extruder (N/A)");
wxMenuItem* change_extruder_menu_item = menu->AppendSubMenu(change_extruder_menu, change_extruder_menu_name, _L("Use another extruder")); append_submenu(menu, change_extruder_menu, wxID_ANY, change_extruder_menu_name, _L("Use another extruder"),
change_extruder_menu_item->SetBitmap(create_scaled_bitmap(active_extruders[1] > 0 ? "edit_uni" : "change_extruder")); active_extruders[1] > 0 ? "edit_uni" : "change_extruder",
[this]() {return m_mode == MultiAsSingle; }, GUI::wxGetApp().plater());
GUI::wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this, change_extruder_menu_item](wxUpdateUIEvent& evt) {
enable_menu_item(evt, [this]() {return m_mode == MultiAsSingle; }, change_extruder_menu_item, this); },
change_extruder_menu_item->GetId());
} }
} }
@ -1626,7 +1621,7 @@ void Control::append_add_color_change_menu_item(wxMenu* menu, bool switch_curren
format_wxstr(_L("Switch code to Color change (%1%) for:"), gcode(ColorChange)) : format_wxstr(_L("Switch code to Color change (%1%) for:"), gcode(ColorChange)) :
format_wxstr(_L("Add color change (%1%) for:"), gcode(ColorChange)); format_wxstr(_L("Add color change (%1%) for:"), gcode(ColorChange));
wxMenuItem* add_color_change_menu_item = menu->AppendSubMenu(add_color_change_menu, menu_name, ""); wxMenuItem* add_color_change_menu_item = menu->AppendSubMenu(add_color_change_menu, menu_name, "");
add_color_change_menu_item->SetBitmap(create_scaled_bitmap("colorchange_add_m")); add_color_change_menu_item->SetBitmap(create_menu_bitmap("colorchange_add_m"));
} }
} }
@ -2143,6 +2138,8 @@ static std::string get_new_color(const std::string& color)
* */ * */
static void upgrade_text_entry_dialog(wxTextEntryDialog* dlg, double min = -1.0, double max = -1.0) static void upgrade_text_entry_dialog(wxTextEntryDialog* dlg, double min = -1.0, double max = -1.0)
{ {
GUI::wxGetApp().UpdateDlgDarkUI(dlg);
// detect TextCtrl and OK button // detect TextCtrl and OK button
wxTextCtrl* textctrl {nullptr}; wxTextCtrl* textctrl {nullptr};
wxWindowList& dlg_items = dlg->GetChildren(); wxWindowList& dlg_items = dlg->GetChildren();
@ -2487,7 +2484,8 @@ bool Control::check_ticks_changed_event(Type type)
_L("Your current changes will delete all saved color changes.") + "\n\n\t" + _L("Your current changes will delete all saved color changes.") + "\n\n\t" +
_L("Are you sure you want to continue?"); _L("Are you sure you want to continue?");
wxMessageDialog msg(this, message, _L("Notice"), wxYES_NO); //wxMessageDialog msg(this, message, _L("Notice"), wxYES_NO);
GUI::MessageDialog msg(this, message, _L("Notice"), wxYES_NO);
if (msg.ShowModal() == wxID_YES) { if (msg.ShowModal() == wxID_YES) {
m_ticks.erase_all_ticks_with_code(ColorChange); m_ticks.erase_all_ticks_with_code(ColorChange);
post_ticks_changed_event(ColorChange); post_ticks_changed_event(ColorChange);
@ -2507,7 +2505,8 @@ bool Control::check_ticks_changed_event(Type type)
_L("Your current changes will delete all saved extruder (tool) changes.") + "\n\n\t" + _L("Your current changes will delete all saved extruder (tool) changes.") + "\n\n\t" +
_L("Are you sure you want to continue?") ) ; _L("Are you sure you want to continue?") ) ;
wxMessageDialog msg(this, message, _L("Notice"), wxYES_NO | (m_mode == SingleExtruder ? wxCANCEL : 0)); //wxMessageDialog msg(this, message, _L("Notice"), wxYES_NO | (m_mode == SingleExtruder ? wxCANCEL : 0));
GUI::MessageDialog msg(this, message, _L("Notice"), wxYES_NO | (m_mode == SingleExtruder ? wxCANCEL : 0));
const int answer = msg.ShowModal(); const int answer = msg.ShowModal();
if (answer == wxID_YES) { if (answer == wxID_YES) {
m_ticks.erase_all_ticks_with_code(ToolChange); m_ticks.erase_all_ticks_with_code(ToolChange);

View File

@ -139,7 +139,12 @@ bool BitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state)
} }
else else
#endif // SUPPORTS_MARKUP && wxHAS_GENERIC_DATAVIEWCTRL #endif // SUPPORTS_MARKUP && wxHAS_GENERIC_DATAVIEWCTRL
#ifdef _WIN32
// workaround for Windows DarkMode : Don't respect to the state & wxDATAVIEW_CELL_SELECTED to avoid update of the text color
RenderText(m_value.GetText(), xoffset, rect, dc, state & wxDATAVIEW_CELL_SELECTED ? 0 :state);
#else
RenderText(m_value.GetText(), xoffset, rect, dc, state); RenderText(m_value.GetText(), xoffset, rect, dc, state);
#endif
return true; return true;
} }
@ -258,7 +263,12 @@ bool BitmapChoiceRenderer::Render(wxRect rect, wxDC* dc, int state)
rect.height= icon.GetHeight(); rect.height= icon.GetHeight();
} }
#ifdef _WIN32
// workaround for Windows DarkMode : Don't respect to the state & wxDATAVIEW_CELL_SELECTED to avoid update of the text color
RenderText(m_value.GetText(), xoffset, rect, dc, state & wxDATAVIEW_CELL_SELECTED ? 0 : state);
#else
RenderText(m_value.GetText(), xoffset, rect, dc, state); RenderText(m_value.GetText(), xoffset, rect, dc, state);
#endif
return true; return true;
} }

View File

@ -16,6 +16,7 @@
#include "I18N.hpp" #include "I18N.hpp"
#include "OptionsGroup.hpp" #include "OptionsGroup.hpp"
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include "BitmapComboBox.hpp"
namespace Slic3r { namespace Slic3r {
@ -26,7 +27,11 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
m_sequence(sequence) m_sequence(sequence)
{ {
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this);
#else
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
SetDoubleBuffered(true); SetDoubleBuffered(true);
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
@ -39,13 +44,14 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
auto option_sizer = new wxBoxSizer(wxVERTICAL); auto option_sizer = new wxBoxSizer(wxVERTICAL);
auto intervals_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder change for every"))+ ": "); auto intervals_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder change for every"))+ ": ");
wxGetApp().UpdateDarkUI(intervals_box);
auto intervals_box_sizer = new wxStaticBoxSizer(intervals_box, wxVERTICAL); auto intervals_box_sizer = new wxStaticBoxSizer(intervals_box, wxVERTICAL);
m_intervals_grid_sizer = new wxFlexGridSizer(3, 5, em); m_intervals_grid_sizer = new wxFlexGridSizer(3, 5, em);
auto editor_sz = wxSize(4*em, wxDefaultCoord); auto editor_sz = wxSize(4*em, wxDefaultCoord);
auto ID_RADIO_BUTTON = wxWindow::NewControlId(1); auto ID_RADIO_BUTTON = wxID_ANY;// wxWindow::NewControlId(1);
wxRadioButton* rb_by_layers = new wxRadioButton(this, ID_RADIO_BUTTON, "", wxDefaultPosition, wxDefaultSize, wxRB_GROUP); wxRadioButton* rb_by_layers = new wxRadioButton(this, ID_RADIO_BUTTON, "", wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
rb_by_layers->Bind(wxEVT_RADIOBUTTON, [this](wxCommandEvent& event) { m_sequence.is_mm_intervals = false; }); rb_by_layers->Bind(wxEVT_RADIOBUTTON, [this](wxCommandEvent& event) { m_sequence.is_mm_intervals = false; });
@ -54,7 +60,12 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
wxStaticText* st_by_layers = new wxStaticText(this, wxID_ANY, _(L("layers"))); wxStaticText* st_by_layers = new wxStaticText(this, wxID_ANY, _(L("layers")));
m_interval_by_layers = new wxTextCtrl(this, wxID_ANY, m_interval_by_layers = new wxTextCtrl(this, wxID_ANY,
wxString::Format("%d", m_sequence.interval_by_layers), wxString::Format("%d", m_sequence.interval_by_layers),
wxDefaultPosition, editor_sz); wxDefaultPosition, editor_sz
#ifdef _WIN32
, wxBORDER_SIMPLE
#endif
);
wxGetApp().UpdateDarkUI(m_interval_by_layers);
m_interval_by_layers->Bind(wxEVT_TEXT, [this, rb_by_layers](wxEvent&) m_interval_by_layers->Bind(wxEVT_TEXT, [this, rb_by_layers](wxEvent&)
{ {
wxString str = m_interval_by_layers->GetValue(); wxString str = m_interval_by_layers->GetValue();
@ -89,7 +100,12 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
wxStaticText* st_by_mm = new wxStaticText(this, wxID_ANY, _(L("mm"))); wxStaticText* st_by_mm = new wxStaticText(this, wxID_ANY, _(L("mm")));
m_interval_by_mm = new wxTextCtrl(this, wxID_ANY, m_interval_by_mm = new wxTextCtrl(this, wxID_ANY,
double_to_string(sequence.interval_by_mm), double_to_string(sequence.interval_by_mm),
wxDefaultPosition, editor_sz, wxTE_PROCESS_ENTER); wxDefaultPosition, editor_sz, wxTE_PROCESS_ENTER
#ifdef _WIN32
| wxBORDER_SIMPLE
#endif
);
wxGetApp().UpdateDarkUI(m_interval_by_mm);
double min_layer_height = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("layer_height"); double min_layer_height = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("layer_height");
auto change_value = [this, min_layer_height]() auto change_value = [this, min_layer_height]()
@ -159,6 +175,8 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
m_color_repetition->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) {m_sequence.color_repetition = e.IsChecked(); }); m_color_repetition->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) {m_sequence.color_repetition = e.IsChecked(); });
auto extruders_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder(tool) sequence"))+ ": "); auto extruders_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder(tool) sequence"))+ ": ");
wxGetApp().UpdateDarkUI(extruders_box);
auto extruders_box_sizer = new wxStaticBoxSizer(extruders_box, wxVERTICAL); auto extruders_box_sizer = new wxStaticBoxSizer(extruders_box, wxVERTICAL);
m_extruders_grid_sizer = new wxFlexGridSizer(3, 5, em); m_extruders_grid_sizer = new wxFlexGridSizer(3, 5, em);
@ -173,6 +191,8 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
main_sizer->Add(option_sizer, 0, wxEXPAND | wxALL, em); main_sizer->Add(option_sizer, 0, wxEXPAND | wxALL, em);
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL); wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_OK, this)));
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
main_sizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, em); main_sizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, em);
SetSizer(main_sizer); SetSizer(main_sizer);
@ -195,7 +215,7 @@ void ExtruderSequenceDialog::apply_extruder_sequence()
for (size_t extruder=0; extruder < m_sequence.extruders.size(); ++extruder) for (size_t extruder=0; extruder < m_sequence.extruders.size(); ++extruder)
{ {
wxBitmapComboBox* extruder_selector = nullptr; BitmapComboBox* extruder_selector = nullptr;
apply_extruder_selector(&extruder_selector, this, "", wxDefaultPosition, wxSize(15*wxGetApp().em_unit(), -1)); apply_extruder_selector(&extruder_selector, this, "", wxDefaultPosition, wxSize(15*wxGetApp().em_unit(), -1));
extruder_selector->SetSelection(m_sequence.extruders[extruder]); extruder_selector->SetSelection(m_sequence.extruders[extruder]);

View File

@ -13,10 +13,12 @@
#include <wx/numformatter.h> #include <wx/numformatter.h>
#include <wx/tooltip.h> #include <wx/tooltip.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/listbook.h>
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include "OG_CustomCtrl.hpp" #include "OG_CustomCtrl.hpp"
#include "MsgDialog.hpp" #include "MsgDialog.hpp"
#include "BitmapComboBox.hpp"
#ifdef __WXOSX__ #ifdef __WXOSX__
#define wxOSX true #define wxOSX true
@ -411,6 +413,10 @@ void Field::msw_rescale()
void Field::sys_color_changed() void Field::sys_color_changed()
{ {
#ifdef _WIN32
if (wxWindow* win = this->getWindow())
wxGetApp().UpdateDarkUI(win);
#endif
} }
template<class T> template<class T>
@ -472,13 +478,17 @@ void TextCtrl::BUILD() {
break; break;
} }
const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/; 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 wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style);
if (parent_is_custom_ctrl && m_opt.height < 0) if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double)temp->GetSize().GetHeight()/m_em_unit; opt_height = (double)temp->GetSize().GetHeight()/m_em_unit;
temp->SetFont(m_opt.is_code ? temp->SetFont(m_opt.is_code ?
Slic3r::GUI::wxGetApp().code_font(): Slic3r::GUI::wxGetApp().code_font():
Slic3r::GUI::wxGetApp().normal_font()); Slic3r::GUI::wxGetApp().normal_font());
wxGetApp().UpdateDarkUI(temp);
if (! m_opt.multiline && !wxOSX) if (! m_opt.multiline && !wxOSX)
// Only disable background refresh for single line input fields, as they are completely painted over by the edit control. // Only disable background refresh for single line input fields, as they are completely painted over by the edit control.
@ -796,7 +806,12 @@ void SpinCtrl::BUILD() {
const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647; const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647;
auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size,
0|wxTE_PROCESS_ENTER, min_val, max_val, default_value); wxTE_PROCESS_ENTER | wxSP_ARROW_KEYS
#ifdef _WIN32
| wxBORDER_SIMPLE
#endif
, min_val, max_val, default_value);
#ifdef __WXGTK3__ #ifdef __WXGTK3__
wxSize best_sz = temp->GetBestSize(); wxSize best_sz = temp->GetBestSize();
if (best_sz.x > size.x) if (best_sz.x > size.x)
@ -804,6 +819,7 @@ void SpinCtrl::BUILD() {
#endif //__WXGTK3__ #endif //__WXGTK3__
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
wxGetApp().UpdateDarkUI(temp);
if (m_opt.height < 0 && parent_is_custom_ctrl) if (m_opt.height < 0 && parent_is_custom_ctrl)
opt_height = (double)temp->GetSize().GetHeight() / m_em_unit; opt_height = (double)temp->GetSize().GetHeight() / m_em_unit;
@ -904,7 +920,11 @@ void SpinCtrl::msw_rescale()
static_assert(wxMAJOR_VERSION >= 3, "Use of wxBitmapComboBox on Settings Tabs requires wxWidgets 3.0 and newer"); static_assert(wxMAJOR_VERSION >= 3, "Use of wxBitmapComboBox on Settings Tabs requires wxWidgets 3.0 and newer");
using choice_ctrl = wxBitmapComboBox; using choice_ctrl = wxBitmapComboBox;
#else #else
#ifdef _WIN32
using choice_ctrl = BitmapComboBox;
#else
using choice_ctrl = wxComboBox; using choice_ctrl = wxComboBox;
#endif
#endif // __WXOSX__ #endif // __WXOSX__
void Choice::BUILD() { void Choice::BUILD() {
@ -1299,6 +1319,8 @@ void ColourPicker::BUILD()
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
wxGetApp().UpdateDarkUI(temp->GetPickerCtrl());
// // recast as a wxWindow to fit the calling convention // // recast as a wxWindow to fit the calling convention
window = dynamic_cast<wxWindow*>(temp); window = dynamic_cast<wxWindow*>(temp);
@ -1372,6 +1394,15 @@ void ColourPicker::msw_rescale()
set_undef_value(field); set_undef_value(field);
} }
void ColourPicker::sys_color_changed()
{
#ifdef _WIN32
if (wxWindow* win = this->getWindow())
if (wxColourPickerCtrl* picker = dynamic_cast<wxColourPickerCtrl*>(win))
wxGetApp().UpdateDarkUI(picker->GetPickerCtrl(), true);
#endif
}
void PointCtrl::BUILD() void PointCtrl::BUILD()
{ {
auto temp = new wxBoxSizer(wxHORIZONTAL); auto temp = new wxBoxSizer(wxHORIZONTAL);
@ -1384,8 +1415,12 @@ void PointCtrl::BUILD()
val = default_pt(1); val = default_pt(1);
wxString Y = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None); wxString Y = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None);
x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); long style = wxTE_PROCESS_ENTER;
y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, 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);
if (parent_is_custom_ctrl && m_opt.height < 0) if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double)x_textctrl->GetSize().GetHeight() / m_em_unit; opt_height = (double)x_textctrl->GetSize().GetHeight() / m_em_unit;
@ -1401,6 +1436,11 @@ void PointCtrl::BUILD()
static_text_y->SetFont(Slic3r::GUI::wxGetApp().normal_font()); static_text_y->SetFont(Slic3r::GUI::wxGetApp().normal_font());
static_text_y->SetBackgroundStyle(wxBG_STYLE_PAINT); static_text_y->SetBackgroundStyle(wxBG_STYLE_PAINT);
wxGetApp().UpdateDarkUI(x_textctrl);
wxGetApp().UpdateDarkUI(y_textctrl);
wxGetApp().UpdateDarkUI(static_text_x, false, true);
wxGetApp().UpdateDarkUI(static_text_y, false, true);
temp->Add(static_text_x, 0, wxALIGN_CENTER_VERTICAL, 0); temp->Add(static_text_x, 0, wxALIGN_CENTER_VERTICAL, 0);
temp->Add(x_textctrl); temp->Add(x_textctrl);
temp->Add(static_text_y, 0, wxALIGN_CENTER_VERTICAL, 0); temp->Add(static_text_y, 0, wxALIGN_CENTER_VERTICAL, 0);
@ -1436,6 +1476,15 @@ void PointCtrl::msw_rescale()
} }
} }
void PointCtrl::sys_color_changed()
{
#ifdef _WIN32
for (wxSizerItem* item: sizer->GetChildren())
if (item->IsWindow())
wxGetApp().UpdateDarkUI(item->GetWindow());
#endif
}
bool PointCtrl::value_was_changed(wxTextCtrl* win) bool PointCtrl::value_was_changed(wxTextCtrl* win)
{ {
if (m_value.empty()) if (m_value.empty())
@ -1519,6 +1568,8 @@ void StaticText::BUILD()
temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
temp->SetFont(wxGetApp().bold_font()); temp->SetFont(wxGetApp().bold_font());
wxGetApp().UpdateDarkUI(temp);
// // recast as a wxWindow to fit the calling convention // // recast as a wxWindow to fit the calling convention
window = dynamic_cast<wxWindow*>(temp); window = dynamic_cast<wxWindow*>(temp);

View File

@ -177,7 +177,7 @@ public:
} }
virtual void msw_rescale(); virtual void msw_rescale();
void sys_color_changed(); virtual void sys_color_changed();
bool get_enter_pressed() const { return bEnterPressed; } bool get_enter_pressed() const { return bEnterPressed; }
void set_enter_pressed(bool pressed) { bEnterPressed = pressed; } void set_enter_pressed(bool pressed) { bEnterPressed = pressed; }
@ -394,6 +394,7 @@ public:
void set_value(const boost::any& value, bool change_event = false) override; void set_value(const boost::any& value, bool change_event = false) override;
boost::any& get_value() override; boost::any& get_value() override;
void msw_rescale() override; void msw_rescale() override;
void sys_color_changed() override;
void enable() override { dynamic_cast<wxColourPickerCtrl*>(window)->Enable(); } void enable() override { dynamic_cast<wxColourPickerCtrl*>(window)->Enable(); }
void disable() override{ dynamic_cast<wxColourPickerCtrl*>(window)->Disable(); } void disable() override{ dynamic_cast<wxColourPickerCtrl*>(window)->Disable(); }
@ -420,6 +421,7 @@ public:
boost::any& get_value() override; boost::any& get_value() override;
void msw_rescale() override; void msw_rescale() override;
void sys_color_changed() override;
void enable() override { void enable() override {
x_textctrl->Enable(); x_textctrl->Enable();

View File

@ -747,7 +747,8 @@ void FirmwareDialog::priv::on_avrdude(const wxCommandEvent &evt)
void FirmwareDialog::priv::on_async_dialog(const wxCommandEvent &evt) void FirmwareDialog::priv::on_async_dialog(const wxCommandEvent &evt)
{ {
wxMessageDialog dlg(this->q, evt.GetString(), wxMessageBoxCaptionStr, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); //wxMessageDialog dlg(this->q, evt.GetString(), wxMessageBoxCaptionStr, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
GUI::MessageDialog dlg(this->q, evt.GetString(), wxMessageBoxCaptionStr, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
modal_response = dlg.ShowModal(); modal_response = dlg.ShowModal();
@ -863,6 +864,8 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
bsizer->Add(p->btn_flash); bsizer->Add(p->btn_flash);
vsizer->Add(bsizer, 0, wxEXPAND); vsizer->Add(bsizer, 0, wxEXPAND);
GUI::wxGetApp().UpdateDlgDarkUI(this);
auto *topsizer = new wxBoxSizer(wxVERTICAL); auto *topsizer = new wxBoxSizer(wxVERTICAL);
topsizer->Add(panel, 1, wxEXPAND | wxALL, DIALOG_MARGIN); topsizer->Add(panel, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
SetMinSize(wxSize(p->min_width, p->min_height)); SetMinSize(wxSize(p->min_width, p->min_height));
@ -903,7 +906,8 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
p->btn_flash->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { p->btn_flash->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
if (this->p->avrdude) { if (this->p->avrdude) {
// Flashing is in progress, ask the user if they're really sure about canceling it // Flashing is in progress, ask the user if they're really sure about canceling it
wxMessageDialog dlg(this, //wxMessageDialog dlg(this,
GUI::MessageDialog dlg(this,
_(L("Are you sure you want to cancel firmware flashing?\nThis could leave your printer in an unusable state!")), _(L("Are you sure you want to cancel firmware flashing?\nThis could leave your printer in an unusable state!")),
_(L("Confirmation")), _(L("Confirmation")),
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);

View File

@ -225,7 +225,8 @@ void show_error_id(int id, const std::string& message)
void show_info(wxWindow* parent, const wxString& message, const wxString& title) void show_info(wxWindow* parent, const wxString& message, const wxString& title)
{ {
wxMessageDialog msg_wingow(parent, message, wxString(SLIC3R_APP_NAME " - ") + (title.empty() ? _L("Notice") : title), wxOK | wxICON_INFORMATION); //wxMessageDialog msg_wingow(parent, message, wxString(SLIC3R_APP_NAME " - ") + (title.empty() ? _L("Notice") : title), wxOK | wxICON_INFORMATION);
MessageDialog msg_wingow(parent, message, wxString(SLIC3R_APP_NAME " - ") + (title.empty() ? _L("Notice") : title), wxOK | wxICON_INFORMATION);
msg_wingow.ShowModal(); msg_wingow.ShowModal();
} }
@ -237,7 +238,8 @@ void show_info(wxWindow* parent, const char* message, const char* title)
void warning_catcher(wxWindow* parent, const wxString& message) void warning_catcher(wxWindow* parent, const wxString& message)
{ {
wxMessageDialog msg(parent, message, _L("Warning"), wxOK | wxICON_WARNING); //wxMessageDialog msg(parent, message, _L("Warning"), wxOK | wxICON_WARNING);
MessageDialog msg(parent, message, _L("Warning"), wxOK | wxICON_WARNING);
msg.ShowModal(); msg.ShowModal();
} }
@ -245,6 +247,7 @@ void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, cons
{ {
if (comboCtrl == nullptr) if (comboCtrl == nullptr)
return; return;
wxGetApp().UpdateDarkUI(comboCtrl);
wxCheckListBoxComboPopup* popup = new wxCheckListBoxComboPopup; wxCheckListBoxComboPopup* popup = new wxCheckListBoxComboPopup;
if (popup != nullptr) { if (popup != nullptr) {
@ -279,6 +282,7 @@ void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, cons
} }
comboCtrl->SetMinClientSize(wxSize(max_width, -1)); comboCtrl->SetMinClientSize(wxSize(max_width, -1));
wxGetApp().UpdateDarkUI(popup);
} }
} }

View File

@ -76,7 +76,10 @@
#ifdef __WXMSW__ #ifdef __WXMSW__
#include <dbt.h> #include <dbt.h>
#include <shlobj.h> #include <shlobj.h>
#endif // __WXMSW__ #ifdef _MSW_DARK_MODE
#include <wx/msw/dark_mode.h>
#endif // _MSW_DARK_MODE
#endif
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG #if ENABLE_THUMBNAIL_GENERATOR_DEBUG
#include <boost/beast/core/detail/base64.hpp> #include <boost/beast/core/detail/base64.hpp>
@ -816,6 +819,10 @@ bool GUI_App::on_init_inner()
wxInitAllImageHandlers(); wxInitAllImageHandlers();
#ifdef _MSW_DARK_MODE
if (app_config->get("dark_color_mode") == "1")
NppDarkMode::InitDarkMode();
#endif
SplashScreen* scrn = nullptr; SplashScreen* scrn = nullptr;
if (app_config->get("show_splash_screen") == "1") { if (app_config->get("show_splash_screen") == "1") {
// make a bitmap with dark grey banner on the left side // make a bitmap with dark grey banner on the left side
@ -1015,14 +1022,16 @@ bool GUI_App::dark_mode()
// proper dark mode was first introduced. // proper dark mode was first introduced.
return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode(); return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode();
#else #else
const unsigned luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); return wxGetApp().app_config->get("dark_color_mode") == "1" ? true : check_dark_mode();
return luma < 128; //const unsigned luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
//return luma < 128;
#endif #endif
} }
void GUI_App::init_label_colours() void GUI_App::init_label_colours()
{ {
if (dark_mode()) { bool is_dark_mode = dark_mode();
if (is_dark_mode) {
m_color_label_modified = wxColour(253, 111, 40); m_color_label_modified = wxColour(253, 111, 40);
m_color_label_sys = wxColour(115, 220, 103); m_color_label_sys = wxColour(115, 220, 103);
} }
@ -1030,7 +1039,15 @@ void GUI_App::init_label_colours()
m_color_label_modified = wxColour(252, 77, 1); m_color_label_modified = wxColour(252, 77, 1);
m_color_label_sys = wxColour(26, 132, 57); m_color_label_sys = wxColour(26, 132, 57);
} }
#ifdef _WIN32
m_color_label_default = is_dark_mode ? wxColour(250, 250, 250): wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
m_color_highlight_label_default = is_dark_mode ? wxColour(230, 230, 230): wxSystemSettings::GetColour(/*wxSYS_COLOUR_HIGHLIGHTTEXT*/wxSYS_COLOUR_WINDOWTEXT);
m_color_highlight_default = is_dark_mode ? wxColour(78, 78, 78) : wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
m_color_hovered_btn_label = is_dark_mode ? wxColour(253, 111, 40) : wxColour(252, 77, 1);
#else
m_color_label_default = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); m_color_label_default = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
#endif
m_color_window_default = is_dark_mode ? wxColour(43, 43, 43) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
} }
void GUI_App::update_label_colours_from_appconfig() void GUI_App::update_label_colours_from_appconfig()
@ -1054,6 +1071,103 @@ void GUI_App::update_label_colours()
tab->update_label_colours(); tab->update_label_colours();
} }
void GUI_App::UpdateDarkUI(wxWindow* window, bool highlited/* = false*/, bool just_font/* = false*/)
{
#ifdef _WIN32
if (wxButton* btn = dynamic_cast<wxButton*>(window)) {
if (!(btn->GetWindowStyle() & wxNO_BORDER)) {
btn->SetWindowStyle(btn->GetWindowStyle() | wxNO_BORDER);
highlited = true;
}
// hovering for buttons
{
auto focus_button = [this, btn](const bool focus) {
btn->SetForegroundColour(focus ? m_color_hovered_btn_label : m_color_label_default);
btn->Refresh();
btn->Update();
};
btn->Bind(wxEVT_ENTER_WINDOW, [focus_button](wxMouseEvent& event) { focus_button(true); event.Skip(); });
btn->Bind(wxEVT_LEAVE_WINDOW, [focus_button](wxMouseEvent& event) { focus_button(false); event.Skip(); });
}
}
else if (dark_mode()) {
if (wxTextCtrl* text = dynamic_cast<wxTextCtrl*>(window)) {
if (text->GetBorder() != wxBORDER_SIMPLE)
text->SetWindowStyle(text->GetWindowStyle() | wxBORDER_SIMPLE);
}
else if (wxCheckListBox* list = dynamic_cast<wxCheckListBox*>(window)) {
list->SetWindowStyle(list->GetWindowStyle() | wxBORDER_SIMPLE);
list->SetBackgroundColour(highlited ? m_color_highlight_default : m_color_window_default);
for (size_t i = 0; i < list->GetCount(); i++)
if (wxOwnerDrawn* item = list->GetItem(i)) {
item->SetBackgroundColour(highlited ? m_color_highlight_default : m_color_window_default);
item->SetTextColour(m_color_label_default);
}
return;
}
else if (dynamic_cast<wxListBox*>(window))
window->SetWindowStyle(window->GetWindowStyle() | wxBORDER_SIMPLE);
}
if (!just_font)
window->SetBackgroundColour(highlited ? m_color_highlight_default : m_color_window_default);
window->SetForegroundColour(m_color_label_default);
#endif
}
// recursive function for scaling fonts for all controls in Window
#ifdef _WIN32
static void update_dark_children_ui(wxWindow* window)
{
bool highlight_btn = dynamic_cast<wxButton*>(window) != nullptr;
wxGetApp().UpdateDarkUI(window, highlight_btn);
auto children = window->GetChildren();
for (auto child : children) {
update_dark_children_ui(child);
}
}
#endif
void GUI_App::UpdateDlgDarkUI(wxDialog* dlg)
{
#ifdef _WIN32
update_dark_children_ui(dlg);
#endif
}
void GUI_App::UpdateDVCDarkUI(wxDataViewCtrl* dvc, bool highlited/* = false*/)
{
#ifdef _WIN32
if (!dark_mode())
return;
UpdateDarkUI(dvc, highlited);
wxItemAttr attr(dark_mode() ? m_color_highlight_default : m_color_label_default,
m_color_window_default,
m_normal_font);
dvc->SetHeaderAttr(attr);
if (dvc->HasFlag(wxDV_ROW_LINES))
dvc->SetAlternateRowColour(m_color_highlight_default);
if (dvc->GetBorder() != wxBORDER_SIMPLE)
dvc->SetWindowStyle(dvc->GetWindowStyle() | wxBORDER_SIMPLE);
#endif
}
void GUI_App::UpdateAllStaticTextDarkUI(wxWindow* parent)
{
#ifdef _WIN32
if (!dark_mode())
return;
wxGetApp().UpdateDarkUI(parent);
auto children = parent->GetChildren();
for (auto child : children) {
if (dynamic_cast<wxStaticText*>(child))
child->SetForegroundColour(m_color_label_default);
}
#endif
}
void GUI_App::init_fonts() void GUI_App::init_fonts()
{ {
m_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); m_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
@ -1169,7 +1283,8 @@ void GUI_App::check_printer_presets()
_L("By default new Printer devices will be named as \"Printer N\" during its creation.\n" _L("By default new Printer devices will be named as \"Printer N\" during its creation.\n"
"Note: This name can be changed later from the physical printers settings"); "Note: This name can be changed later from the physical printers settings");
wxMessageDialog(nullptr, msg_text, _L("Information"), wxOK | wxICON_INFORMATION).ShowModal(); //wxMessageDialog(nullptr, msg_text, _L("Information"), wxOK | wxICON_INFORMATION).ShowModal();
MessageDialog(nullptr, msg_text, _L("Information"), wxOK | wxICON_INFORMATION).ShowModal();
preset_bundle->physical_printers.load_printers_from_presets(preset_bundle->printers); preset_bundle->physical_printers.load_printers_from_presets(preset_bundle->printers);
} }
@ -1258,6 +1373,16 @@ void GUI_App::update_ui_from_settings()
{ {
update_label_colours(); update_label_colours();
mainframe->update_ui_from_settings(); mainframe->update_ui_from_settings();
#if 0 //#ifdef _WIN32 // #ysDarkMSW - Use to force dark colors for SystemLightMode
if (m_force_sys_colors_update) {
m_force_sys_colors_update = false;
mainframe->force_sys_color_changed();
mainframe->diff_dialog.force_sys_color_changed();
if (m_wizard)
m_wizard->force_sys_color_changed();
}
#endif
} }
void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_maximized) void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_maximized)
@ -1395,6 +1520,22 @@ static const wxLanguageInfo* linux_get_existing_locale_language(const wxLanguage
} }
#endif #endif
static int GetSingleChoiceIndex(const wxString& message,
const wxString& caption,
const wxArrayString& choices,
int initialSelection)
{
#ifdef _WIN32
wxSingleChoiceDialog dialog(nullptr, message, caption, choices);
wxGetApp().UpdateDlgDarkUI(&dialog);
dialog.SetSelection(initialSelection);
return dialog.ShowModal() == wxID_OK ? dialog.GetSelection() : -1;
#else
return wxGetSingleChoiceIndex(message, caption, choices, initialSelection);
#endif
}
// select language from the list of installed languages // select language from the list of installed languages
bool GUI_App::select_language() bool GUI_App::select_language()
{ {
@ -1438,7 +1579,7 @@ bool GUI_App::select_language()
// This is the language to highlight in the choice dialog initially. // This is the language to highlight in the choice dialog initially.
init_selection_default = init_selection; init_selection_default = init_selection;
const long index = wxGetSingleChoiceIndex(_L("Select the language"), _L("Language"), names, init_selection_default); const long index = GetSingleChoiceIndex(_L("Select the language"), _L("Language"), names, init_selection_default);
// Try to load a new language. // Try to load a new language.
if (index != -1 && (init_selection == -1 || init_selection != index)) { if (index != -1 && (init_selection == -1 || init_selection != index)) {
const wxLanguageInfo *new_language_info = language_infos[index]; const wxLanguageInfo *new_language_info = language_infos[index];
@ -1700,6 +1841,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
if (check_unsaved_changes()) { if (check_unsaved_changes()) {
#endif // ENABLE_PROJECT_DIRTY_STATE #endif // ENABLE_PROJECT_DIRTY_STATE
wxTextEntryDialog dlg(nullptr, _L("Taking configuration snapshot"), _L("Snapshot name")); wxTextEntryDialog dlg(nullptr, _L("Taking configuration snapshot"), _L("Snapshot name"));
UpdateDlgDarkUI(&dlg);
// set current normal font for dialog children, // set current normal font for dialog children,
// because of just dlg.SetFont(normal_font()) has no result; // because of just dlg.SetFont(normal_font()) has no result;
@ -1753,6 +1895,17 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
if (dlg.seq_top_layer_only_changed()) if (dlg.seq_top_layer_only_changed())
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
this->plater_->refresh_print(); this->plater_->refresh_print();
if (dlg.recreate_GUI()) {
#ifdef _MSW_DARK_MODE
if (dlg.color_mode_changed()) {
NppDarkMode::SetDarkMode(app_config->get("dark_color_mode") == "1");
init_label_colours();
}
#endif
recreate_GUI(_L("Restart application") + dots);
return;
}
#ifdef _WIN32 #ifdef _WIN32
if (is_editor()) { if (is_editor()) {
if (app_config->get("associate_3mf") == "1") if (app_config->get("associate_3mf") == "1")
@ -1785,7 +1938,8 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
// so we put it into an inner scope // so we put it into an inner scope
wxString title = is_editor() ? wxString(SLIC3R_APP_NAME) : wxString(GCODEVIEWER_APP_NAME); wxString title = is_editor() ? wxString(SLIC3R_APP_NAME) : wxString(GCODEVIEWER_APP_NAME);
title += " - " + _L("Language selection"); title += " - " + _L("Language selection");
wxMessageDialog dialog(nullptr, //wxMessageDialog dialog(nullptr,
MessageDialog dialog(nullptr,
_L("Switching the language will trigger application restart.\n" _L("Switching the language will trigger application restart.\n"
"You will lose content of the plater.") + "\n\n" + "You will lose content of the plater.") + "\n\n" +
_L("Do you want to proceed?"), _L("Do you want to proceed?"),
@ -1918,7 +2072,8 @@ bool GUI_App::check_print_host_queue()
} }
wxString message; wxString message;
message += _(L("The uploads are still ongoing")) + ":\n\n" + job_string +"\n" + _(L("Stop them and continue anyway?")); message += _(L("The uploads are still ongoing")) + ":\n\n" + job_string +"\n" + _(L("Stop them and continue anyway?"));
wxMessageDialog dialog(mainframe, //wxMessageDialog dialog(mainframe,
MessageDialog dialog(mainframe,
message, message,
wxString(SLIC3R_APP_NAME) + " - " + _(L("Ongoing uploads")), wxString(SLIC3R_APP_NAME) + " - " + _(L("Ongoing uploads")),
wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT); wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
@ -2058,8 +2213,7 @@ Model& GUI_App::model()
{ {
return plater_->model(); return plater_->model();
} }
wxBookCtrlBase* GUI_App::tab_panel() const
wxNotebook* GUI_App::tab_panel() const
{ {
return mainframe->m_tabpanel; return mainframe->m_tabpanel;
} }

View File

@ -20,7 +20,8 @@
class wxMenuItem; class wxMenuItem;
class wxMenuBar; class wxMenuBar;
class wxTopLevelWindow; class wxTopLevelWindow;
class wxNotebook; class wxDataViewCtrl;
class wxBookCtrlBase;
struct wxLanguageInfo; struct wxLanguageInfo;
namespace Slic3r { namespace Slic3r {
@ -118,6 +119,13 @@ private:
wxColour m_color_label_modified; wxColour m_color_label_modified;
wxColour m_color_label_sys; wxColour m_color_label_sys;
wxColour m_color_label_default; wxColour m_color_label_default;
wxColour m_color_window_default;
#ifdef _WIN32
wxColour m_color_highlight_label_default;
wxColour m_color_hovered_btn_label;
wxColour m_color_highlight_default;
//bool m_force_sys_colors_update { false }; // #ysDarkMSW - Use to force dark colors for SystemLightMode
#endif
wxFont m_small_font; wxFont m_small_font;
wxFont m_bold_font; wxFont m_bold_font;
@ -170,6 +178,14 @@ public:
void init_label_colours(); void init_label_colours();
void update_label_colours_from_appconfig(); void update_label_colours_from_appconfig();
void update_label_colours(); void update_label_colours();
// update color mode for window
void UpdateDarkUI(wxWindow *window, bool highlited = false, bool just_font = false);
// update color mode for whole dialog including all children
void UpdateDlgDarkUI(wxDialog* dlg);
// update color mode for DataViewControl
void UpdateDVCDarkUI(wxDataViewCtrl* dvc, bool highlited = false);
// update color mode for panel including all static texts controls
void UpdateAllStaticTextDarkUI(wxWindow* parent);
void init_fonts(); void init_fonts();
void update_fonts(const MainFrame *main_frame = nullptr); void update_fonts(const MainFrame *main_frame = nullptr);
void set_label_clr_modified(const wxColour& clr); void set_label_clr_modified(const wxColour& clr);
@ -178,6 +194,14 @@ public:
const wxColour& get_label_clr_modified(){ return m_color_label_modified; } const wxColour& get_label_clr_modified(){ return m_color_label_modified; }
const wxColour& get_label_clr_sys() { return m_color_label_sys; } const wxColour& get_label_clr_sys() { return m_color_label_sys; }
const wxColour& get_label_clr_default() { return m_color_label_default; } const wxColour& get_label_clr_default() { return m_color_label_default; }
const wxColour& get_window_default_clr(){ return m_color_window_default; }
#ifdef _WIN32
const wxColour& get_label_highlight_clr() { return m_color_highlight_label_default; }
const wxColour& get_highlight_default_clr() { return m_color_highlight_default; }
// void force_sys_colors_update() { m_force_sys_colors_update = true; } // #ysDarkMSW - Use to force dark colors for SystemLightMode
#endif
const wxFont& small_font() { return m_small_font; } const wxFont& small_font() { return m_small_font; }
const wxFont& bold_font() { return m_bold_font; } const wxFont& bold_font() { return m_bold_font; }
@ -256,7 +280,7 @@ public:
PresetUpdater* get_preset_updater() { return preset_updater; } PresetUpdater* get_preset_updater() { return preset_updater; }
wxNotebook* tab_panel() const ; wxBookCtrlBase* tab_panel() const ;
int extruders_cnt() const; int extruders_cnt() const;
int extruders_edited_cnt() const; int extruders_edited_cnt() const;

View File

@ -138,11 +138,11 @@ std::map<std::string, std::string> SettingsFactory::CATEGORY_ICON =
{ L("Hollowing") , "hollowing" } { L("Hollowing") , "hollowing" }
}; };
wxBitmap SettingsFactory::get_category_bitmap(const std::string& category_name) wxBitmap SettingsFactory::get_category_bitmap(const std::string& category_name, bool menu_bmp /*= true*/)
{ {
if (CATEGORY_ICON.find(category_name) == CATEGORY_ICON.end()) if (CATEGORY_ICON.find(category_name) == CATEGORY_ICON.end())
return wxNullBitmap; return wxNullBitmap;
return create_scaled_bitmap(CATEGORY_ICON.at(category_name)); return menu_bmp ? create_menu_bitmap(CATEGORY_ICON.at(category_name)) : create_scaled_bitmap(CATEGORY_ICON.at(category_name));
} }
@ -206,6 +206,34 @@ static void get_full_settings_hierarchy(FullSettingsHierarchy& settings_menu, co
} }
} }
static int GetSelectedChoices( wxArrayInt& selections,
const wxString& message,
const wxString& caption,
const wxArrayString& choices)
{
#ifdef _WIN32
wxMultiChoiceDialog dialog(nullptr, message, caption, choices);
wxGetApp().UpdateDlgDarkUI(&dialog);
// call this even if selections array is empty and this then (correctly)
// deselects the first item which is selected by default
dialog.SetSelections(selections);
if (dialog.ShowModal() != wxID_OK)
{
// NB: intentionally do not clear the selections array here, the caller
// might want to preserve its original contents if the dialog was
// cancelled
return -1;
}
selections = dialog.GetSelections();
return static_cast<int>(selections.GetCount());
#else
return wxGetSelectedChoices(selections, message, caption, choices);
#endif
}
static wxMenu* create_settings_popupmenu(wxMenu* parent_menu, const bool is_object_settings, wxDataViewItem item/*, ModelConfig& config*/) static wxMenu* create_settings_popupmenu(wxMenu* parent_menu, const bool is_object_settings, wxDataViewItem item/*, ModelConfig& config*/)
{ {
wxMenu* menu = new wxMenu; wxMenu* menu = new wxMenu;
@ -236,7 +264,7 @@ static wxMenu* create_settings_popupmenu(wxMenu* parent_menu, const bool is_obje
} }
if (!category_options.empty() && if (!category_options.empty() &&
wxGetSelectedChoices(selections, _L("Select showing settings"), category_name, names) != -1) { GetSelectedChoices(selections, _L("Select showing settings"), category_name, names) != -1) {
for (auto sel : selections) for (auto sel : selections)
category_options[sel].second = true; category_options[sel].second = true;
} }
@ -374,7 +402,7 @@ std::vector<wxBitmap> MenuFactory::get_volume_bitmaps()
std::vector<wxBitmap> volume_bmps; std::vector<wxBitmap> volume_bmps;
volume_bmps.reserve(ADD_VOLUME_MENU_ITEMS.size()); volume_bmps.reserve(ADD_VOLUME_MENU_ITEMS.size());
for (auto item : ADD_VOLUME_MENU_ITEMS) for (auto item : ADD_VOLUME_MENU_ITEMS)
volume_bmps.push_back(create_scaled_bitmap(item.second)); volume_bmps.push_back(create_menu_bitmap(item.second));
return volume_bmps; return volume_bmps;
} }
@ -542,7 +570,7 @@ wxMenuItem* MenuFactory::append_menu_item_settings(wxMenu* menu_)
// Add full settings list // Add full settings list
auto menu_item = new wxMenuItem(menu, wxID_ANY, menu_name); auto menu_item = new wxMenuItem(menu, wxID_ANY, menu_name);
menu_item->SetBitmap(create_scaled_bitmap("cog")); menu_item->SetBitmap(create_menu_bitmap("cog"));
menu_item->SetSubMenu(create_settings_popupmenu(menu, is_object_settings, item)); menu_item->SetSubMenu(create_settings_popupmenu(menu, is_object_settings, item));
return menu->Append(menu_item); return menu->Append(menu_item);
@ -702,7 +730,10 @@ void MenuFactory::append_menu_item_change_extruder(wxMenu* menu)
} }
menu->AppendSubMenu(extruder_selection_menu, name); append_submenu(menu, extruder_selection_menu, wxID_ANY, name, _L("Use another extruder"),
"edit_uni"/* : "change_extruder"*/, []() {return true; }, GUI::wxGetApp().plater());
// menu->AppendSubMenu(extruder_selection_menu, name);
} }
void MenuFactory::append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu) void MenuFactory::append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu)
@ -1046,5 +1077,43 @@ void MenuFactory::msw_rescale()
msw_rescale_menu(dynamic_cast<wxMenu*>(menu)); msw_rescale_menu(dynamic_cast<wxMenu*>(menu));
} }
#ifdef _WIN32
// For this class is used code from stackoverflow:
// https://stackoverflow.com/questions/257288/is-it-possible-to-write-a-template-to-check-for-a-functions-existence
// Using this code we can to inspect of an existence of IsWheelInverted() function in class T
template <typename T>
class menu_has_update_def_colors
{
typedef char one;
struct two { char x[2]; };
template <typename C> static one test(decltype(&C::UpdateDefColors));
template <typename C> static two test(...);
public:
static constexpr bool value = sizeof(test<T>(0)) == sizeof(char);
};
template<typename T>
static void update_menu_item_def_colors(T* item)
{
if constexpr (menu_has_update_def_colors<wxMenuItem>::value) {
item->UpdateDefColors();
}
}
#endif
void MenuFactory::sys_color_changed()
{
for (MenuWithSeparators* menu : { &m_object_menu, &m_sla_object_menu, &m_part_menu, &m_default_menu }) {
msw_rescale_menu(dynamic_cast<wxMenu*>(menu));// msw_rescale_menu updates just icons, so use it
#ifdef _WIN32
// but under MSW we have to update item's bachground color
for (wxMenuItem* item : menu->GetMenuItems())
update_menu_item_def_colors(item);
#endif
}
}
} //namespace GUI } //namespace GUI
} //namespace Slic3r } //namespace Slic3r

View File

@ -25,7 +25,7 @@ struct SettingsFactory
typedef std::map<std::string, std::vector<std::string>> Bundle; typedef std::map<std::string, std::vector<std::string>> Bundle;
static std::map<std::string, std::string> CATEGORY_ICON; static std::map<std::string, std::string> CATEGORY_ICON;
static wxBitmap get_category_bitmap(const std::string& category_name); static wxBitmap get_category_bitmap(const std::string& category_name, bool menu_bmp = true);
static Bundle get_bundle(const DynamicPrintConfig* config, bool is_object_settings); static Bundle get_bundle(const DynamicPrintConfig* config, bool is_object_settings);
static std::vector<std::string> get_options(bool is_part); static std::vector<std::string> get_options(bool is_part);
}; };
@ -42,6 +42,7 @@ public:
void init(wxWindow* parent); void init(wxWindow* parent);
void update_object_menu(); void update_object_menu();
void msw_rescale(); void msw_rescale();
void sys_color_changed();
wxMenu* default_menu(); wxMenu* default_menu();
wxMenu* object_menu(); wxMenu* object_menu();

View File

@ -27,7 +27,7 @@ ObjectLayers::ObjectLayers(wxWindow* parent) :
// Legend for object layers // Legend for object layers
for (const std::string col : { L("Start at height"), L("Stop at height"), L("Layer height") }) { for (const std::string col : { L("Start at height"), L("Stop at height"), L("Layer height") }) {
auto temp = new wxStaticText(m_parent, wxID_ANY, _(col), wxDefaultPosition, /*size*/wxDefaultSize, wxST_ELLIPSIZE_MIDDLE); auto temp = new wxStaticText(m_parent, wxID_ANY, _(col), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_MIDDLE);
temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
temp->SetFont(wxGetApp().bold_font()); temp->SetFont(wxGetApp().bold_font());
@ -276,15 +276,12 @@ void ObjectLayers::sys_color_changed()
m_bmp_delete.msw_rescale(); m_bmp_delete.msw_rescale();
m_bmp_add.msw_rescale(); m_bmp_add.msw_rescale();
m_grid_sizer->SetHGap(wxGetApp().em_unit());
// rescale edit-boxes // rescale edit-boxes
const int cells_cnt = m_grid_sizer->GetCols() * m_grid_sizer->GetEffectiveRowsCount(); const int cells_cnt = m_grid_sizer->GetCols() * m_grid_sizer->GetEffectiveRowsCount();
for (int i = 0; i < cells_cnt; ++i) { for (int i = 0; i < cells_cnt; ++i) {
const wxSizerItem* item = m_grid_sizer->GetItem(i); const wxSizerItem* item = m_grid_sizer->GetItem(i);
if (item->IsSizer()) {// case when we have editor with buttons if (item->IsSizer()) {// case when we have editor with buttons
const std::vector<size_t> btns = {2, 3}; // del_btn, add_btn for (size_t btn : {2, 3}) { // del_btn, add_btn
for (auto btn : btns) {
wxSizerItem* b_item = item->GetSizer()->GetItem(btn); wxSizerItem* b_item = item->GetSizer()->GetItem(btn);
if (b_item->IsWindow()) { if (b_item->IsWindow()) {
auto button = dynamic_cast<PlusMinusButton*>(b_item->GetWindow()); auto button = dynamic_cast<PlusMinusButton*>(b_item->GetWindow());
@ -294,7 +291,24 @@ void ObjectLayers::sys_color_changed()
} }
} }
} }
m_grid_sizer->Layout();
#ifdef _WIN32
m_og->sys_color_changed();
for (int i = 0; i < cells_cnt; ++i) {
const wxSizerItem* item = m_grid_sizer->GetItem(i);
if (item->IsWindow()) {
if (LayerRangeEditor* editor = dynamic_cast<LayerRangeEditor*>(item->GetWindow()))
wxGetApp().UpdateDarkUI(editor);
}
else if (item->IsSizer()) {// case when we have editor with buttons
if (wxSizerItem* e_item = item->GetSizer()->GetItem(size_t(0)); e_item->IsWindow()) {
if (LayerRangeEditor* editor = dynamic_cast<LayerRangeEditor*>(e_item->GetWindow()))
wxGetApp().UpdateDarkUI(editor);
}
}
}
#endif
} }
void ObjectLayers::reset_selection() void ObjectLayers::reset_selection()
@ -313,9 +327,14 @@ LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent,
m_type(type), m_type(type),
m_set_focus_data(set_focus_data_fn), m_set_focus_data(set_focus_data_fn),
wxTextCtrl(parent->m_parent, wxID_ANY, value, wxDefaultPosition, wxTextCtrl(parent->m_parent, wxID_ANY, value, wxDefaultPosition,
wxSize(8 * em_unit(parent->m_parent), wxDefaultCoord), wxTE_PROCESS_ENTER) wxSize(8 * em_unit(parent->m_parent), wxDefaultCoord), wxTE_PROCESS_ENTER
#ifdef _WIN32
| wxBORDER_SIMPLE
#endif
)
{ {
this->SetFont(wxGetApp().normal_font()); this->SetFont(wxGetApp().normal_font());
wxGetApp().UpdateDarkUI(this);
// Reset m_enter_pressed flag to _false_, when value is editing // Reset m_enter_pressed flag to _false_, when value is editing
this->Bind(wxEVT_TEXT, [this](wxEvent&) { m_enter_pressed = false; }, this->GetId()); this->Bind(wxEVT_TEXT, [this](wxEvent&) { m_enter_pressed = false; }, this->GetId());

View File

@ -7,6 +7,7 @@
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include "I18N.hpp" #include "I18N.hpp"
#include "Plater.hpp" #include "Plater.hpp"
#include "BitmapComboBox.hpp"
#if ENABLE_PROJECT_DIRTY_STATE #if ENABLE_PROJECT_DIRTY_STATE
#include "MainFrame.hpp" #include "MainFrame.hpp"
#endif // ENABLE_PROJECT_DIRTY_STATE #endif // ENABLE_PROJECT_DIRTY_STATE
@ -21,6 +22,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <wx/progdlg.h> #include <wx/progdlg.h>
#include <wx/listbook.h>
#include <wx/numformatter.h> #include <wx/numformatter.h>
#include "slic3r/Utils/FixModelByWin10.hpp" #include "slic3r/Utils/FixModelByWin10.hpp"
@ -65,8 +67,14 @@ static void take_snapshot(const wxString& snapshot_name)
} }
ObjectList::ObjectList(wxWindow* parent) : ObjectList::ObjectList(wxWindow* parent) :
wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE) wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
#ifdef _WIN32
wxBORDER_SIMPLE |
#endif
wxDV_MULTIPLE)
{ {
wxGetApp().UpdateDVCDarkUI(this, true);
// create control // create control
create_objects_ctrl(); create_objects_ctrl();
@ -3789,10 +3797,9 @@ void ObjectList::msw_rescale()
void ObjectList::sys_color_changed() void ObjectList::sys_color_changed()
{ {
// update existing items with bitmaps wxGetApp().UpdateDVCDarkUI(this, true);
m_objects_model->Rescale();
Layout(); msw_rescale();
} }
void ObjectList::ItemValueChanged(wxDataViewEvent &event) void ObjectList::ItemValueChanged(wxDataViewEvent &event)

View File

@ -39,6 +39,7 @@ typedef std::map<t_layer_height_range, ModelConfig> t_layer_config_ranges;
namespace GUI { namespace GUI {
wxDECLARE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent); wxDECLARE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent);
class BitmapComboBox;
struct ItemForDelete struct ItemForDelete
{ {
@ -144,7 +145,7 @@ private:
ModelConfig *m_config {nullptr}; ModelConfig *m_config {nullptr};
std::vector<ModelObject*> *m_objects{ nullptr }; std::vector<ModelObject*> *m_objects{ nullptr };
wxBitmapComboBox *m_extruder_editor { nullptr }; BitmapComboBox *m_extruder_editor { nullptr };
std::vector<wxBitmap*> m_bmp_vector; std::vector<wxBitmap*> m_bmp_vector;

View File

@ -1,6 +1,7 @@
#include "GUI_ObjectManipulation.hpp" #include "GUI_ObjectManipulation.hpp"
#include "GUI_ObjectList.hpp" #include "GUI_ObjectList.hpp"
#include "I18N.hpp" #include "I18N.hpp"
#include "BitmapComboBox.hpp"
#include "GLCanvas3D.hpp" #include "GLCanvas3D.hpp"
#include "OptionsGroup.hpp" #include "OptionsGroup.hpp"
@ -12,6 +13,7 @@
#include "Selection.hpp" #include "Selection.hpp"
#include "Plater.hpp" #include "Plater.hpp"
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include "MsgDialog.hpp"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include "slic3r/Utils/FixModelByWin10.hpp" #include "slic3r/Utils/FixModelByWin10.hpp"
@ -64,7 +66,7 @@ static choice_ctrl* create_word_local_combo(wxWindow *parent)
temp->SetTextCtrlStyle(wxTE_READONLY); temp->SetTextCtrlStyle(wxTE_READONLY);
temp->Create(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr); temp->Create(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr);
#else #else
temp = new choice_ctrl(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY); temp = new choice_ctrl(parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY | wxBORDER_SIMPLE);
#endif //__WXOSX__ #endif //__WXOSX__
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
@ -198,7 +200,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
auto add_label = [this, height](wxStaticText** label, const std::string& name, wxSizer* reciver = nullptr) auto add_label = [this, height](wxStaticText** label, const std::string& name, wxSizer* reciver = nullptr)
{ {
*label = new wxStaticText(m_parent, wxID_ANY, _(name) + ":"); *label = new wxStaticText(m_parent, wxID_ANY, _(name) + ":");
set_font_and_background_style(m_move_Label, wxGetApp().normal_font()); set_font_and_background_style(*label, wxGetApp().normal_font());
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->SetMinSize(wxSize(-1, height)); sizer->SetMinSize(wxSize(-1, height));
@ -513,7 +515,14 @@ void ObjectManipulation::update_ui_from_settings()
int axis_id = 0; int axis_id = 0;
for (ManipulationEditor* editor : m_editors) { for (ManipulationEditor* editor : m_editors) {
// editor->SetForegroundColour(m_use_colors ? wxColour(axes_color_text[axis_id]) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); // editor->SetForegroundColour(m_use_colors ? wxColour(axes_color_text[axis_id]) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
#ifdef _WIN32
if (m_use_colors)
editor->SetBackgroundColour(wxColour(axes_color_back[axis_id]));
else
wxGetApp().UpdateDarkUI(editor);
#else
editor->SetBackgroundColour(m_use_colors ? wxColour(axes_color_back[axis_id]) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); editor->SetBackgroundColour(m_use_colors ? wxColour(axes_color_back[axis_id]) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif /* _WIN32 */
if (++axis_id == 3) if (++axis_id == 3)
axis_id = 0; axis_id = 0;
} }
@ -949,7 +958,8 @@ void ObjectManipulation::set_uniform_scaling(const bool new_value)
// Is the angle close to a multiple of 90 degrees? // Is the angle close to a multiple of 90 degrees?
if (! Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) { if (! Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) {
// Cannot apply scaling in the world coordinate system. // Cannot apply scaling in the world coordinate system.
wxMessageDialog dlg(GUI::wxGetApp().mainframe, //wxMessageDialog dlg(GUI::wxGetApp().mainframe,
MessageDialog dlg(GUI::wxGetApp().mainframe,
_L("The currently manipulated object is tilted (rotation angles are not multiples of 90°).\n" _L("The currently manipulated object is tilted (rotation angles are not multiples of 90°).\n"
"Non-uniform scaling of tilted objects is only possible in the World coordinate system,\n" "Non-uniform scaling of tilted objects is only possible in the World coordinate system,\n"
"once the rotation is embedded into the object coordinates.") + "\n" + "once the rotation is embedded into the object coordinates.") + "\n" +
@ -1015,6 +1025,14 @@ void ObjectManipulation::msw_rescale()
void ObjectManipulation::sys_color_changed() void ObjectManipulation::sys_color_changed()
{ {
#ifdef _WIN32
get_og()->sys_color_changed();
wxGetApp().UpdateDarkUI(m_word_local_combo);
wxGetApp().UpdateDarkUI(m_check_inch);
for (ManipulationEditor* editor : m_editors)
editor->sys_color_changed(this);
#endif
// btn...->msw_rescale() updates icon on button, so use it // btn...->msw_rescale() updates icon on button, so use it
m_mirror_bitmap_on.msw_rescale(); m_mirror_bitmap_on.msw_rescale();
m_mirror_bitmap_off.msw_rescale(); m_mirror_bitmap_off.msw_rescale();
@ -1026,8 +1044,6 @@ void ObjectManipulation::sys_color_changed()
for (int id = 0; id < 3; ++id) for (int id = 0; id < 3; ++id)
m_mirror_buttons[id].first->msw_rescale(); m_mirror_buttons[id].first->msw_rescale();
get_og()->sys_color_changed();
} }
static const char axes[] = { 'x', 'y', 'z' }; static const char axes[] = { 'x', 'y', 'z' };
@ -1035,7 +1051,11 @@ ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
const std::string& opt_key, const std::string& opt_key,
int axis) : int axis) :
wxTextCtrl(parent->parent(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxTextCtrl(parent->parent(), wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize((wxOSX ? 5 : 6)*int(wxGetApp().em_unit()), wxDefaultCoord), wxTE_PROCESS_ENTER), wxSize((wxOSX ? 5 : 6)*int(wxGetApp().em_unit()), wxDefaultCoord), wxTE_PROCESS_ENTER
#ifdef _WIN32
| wxBORDER_SIMPLE
#endif
),
m_opt_key(opt_key), m_opt_key(opt_key),
m_axis(axis) m_axis(axis)
{ {
@ -1044,8 +1064,9 @@ ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
this->OSXDisableAllSmartSubstitutions(); this->OSXDisableAllSmartSubstitutions();
#endif // __WXOSX__ #endif // __WXOSX__
if (parent->use_colors()) { if (parent->use_colors()) {
// this->SetForegroundColour(wxColour(axes_color_text[axis]));
this->SetBackgroundColour(wxColour(axes_color_back[axis])); this->SetBackgroundColour(wxColour(axes_color_back[axis]));
} else {
wxGetApp().UpdateDarkUI(this);
} }
// A name used to call handle_sidebar_focus_event() // A name used to call handle_sidebar_focus_event()
@ -1094,6 +1115,12 @@ void ManipulationEditor::msw_rescale()
SetMinSize(wxSize(5 * em, wxDefaultCoord)); SetMinSize(wxSize(5 * em, wxDefaultCoord));
} }
void ManipulationEditor::sys_color_changed(ObjectManipulation* parent)
{
if (!parent->use_colors())
wxGetApp().UpdateDarkUI(this);
}
double ManipulationEditor::get_value() double ManipulationEditor::get_value()
{ {
wxString str = GetValue(); wxString str = GetValue();

View File

@ -20,11 +20,19 @@ class wxCheckBox;
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
#ifdef _WIN32
class BitmapComboBox;
#endif
#ifdef __WXOSX__ #ifdef __WXOSX__
static_assert(wxMAJOR_VERSION >= 3, "Use of wxBitmapComboBox on Manipulation panel requires wxWidgets 3.0 and newer"); static_assert(wxMAJOR_VERSION >= 3, "Use of wxBitmapComboBox on Manipulation panel requires wxWidgets 3.0 and newer");
using choice_ctrl = wxBitmapComboBox; using choice_ctrl = wxBitmapComboBox;
#else
#ifdef _WIN32
using choice_ctrl = BitmapComboBox;
#else #else
using choice_ctrl = wxComboBox; using choice_ctrl = wxComboBox;
#endif
#endif // __WXOSX__ #endif // __WXOSX__
class Selection; class Selection;
@ -44,6 +52,7 @@ public:
~ManipulationEditor() {} ~ManipulationEditor() {}
void msw_rescale(); void msw_rescale();
void sys_color_changed(ObjectManipulation* parent);
void set_value(const wxString& new_value); void set_value(const wxString& new_value);
void kill_focus(ObjectManipulation *parent); void kill_focus(ObjectManipulation *parent);

View File

@ -281,5 +281,13 @@ void ObjectSettings::msw_rescale()
group->msw_rescale(); group->msw_rescale();
} }
void ObjectSettings::sys_color_changed()
{
m_og->sys_color_changed();
for (auto group : m_og_settings)
group->sys_color_changed();
}
} //namespace GUI } //namespace GUI
} //namespace Slic3r } //namespace Slic3r

View File

@ -57,6 +57,7 @@ public:
void update_config_values(ModelConfig *config); void update_config_values(ModelConfig *config);
void UpdateAndShow(const bool show) override; void UpdateAndShow(const bool show) override;
void msw_rescale(); void msw_rescale();
void sys_color_changed();
}; };
}} }}

View File

@ -14,6 +14,7 @@
#include "Plater.hpp" #include "Plater.hpp"
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include <wx/listbook.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/glcanvas.h> #include <wx/glcanvas.h>
#include <wx/sizer.h> #include <wx/sizer.h>
@ -28,6 +29,10 @@
#include "libslic3r/SLAPrint.hpp" #include "libslic3r/SLAPrint.hpp"
#include "NotificationManager.hpp" #include "NotificationManager.hpp"
#ifdef _WIN32
#include "BitmapComboBox.hpp"
#endif
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -186,7 +191,7 @@ bool Preview::init(wxWindow* parent, Model* model)
// to match the background of the sliders // to match the background of the sliders
#ifdef _WIN32 #ifdef _WIN32
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); wxGetApp().UpdateDarkUI(this);
#else #else
SetBackgroundColour(GetParent()->GetBackgroundColour()); SetBackgroundColour(GetParent()->GetBackgroundColour());
#endif // _WIN32 #endif // _WIN32
@ -206,9 +211,13 @@ bool Preview::init(wxWindow* parent, Model* model)
m_layers_slider_sizer = create_layers_slider_sizer(); m_layers_slider_sizer = create_layers_slider_sizer();
m_bottom_toolbar_panel = new wxPanel(this); wxGetApp().UpdateDarkUI(m_bottom_toolbar_panel = new wxPanel(this));
m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View")); m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View"));
#ifdef _WIN32
wxGetApp().UpdateDarkUI(m_choice_view_type = new BitmapComboBox(m_bottom_toolbar_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY));
#else
m_choice_view_type = new wxComboBox(m_bottom_toolbar_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); m_choice_view_type = new wxComboBox(m_bottom_toolbar_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
#endif
m_choice_view_type->Append(_L("Feature type")); m_choice_view_type->Append(_L("Feature type"));
m_choice_view_type->Append(_L("Height")); m_choice_view_type->Append(_L("Height"));
m_choice_view_type->Append(_L("Width")); m_choice_view_type->Append(_L("Width"));
@ -222,8 +231,13 @@ bool Preview::init(wxWindow* parent, Model* model)
m_label_show = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("Show")); m_label_show = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("Show"));
#ifdef _WIN32
long combo_style = wxCB_READONLY | wxBORDER_SIMPLE; //set border allows use default color instead of theme color wich is allways light under MSW
#else
long combo_style = wxCB_READONLY;
#endif
m_combochecklist_features = new wxComboCtrl(); m_combochecklist_features = new wxComboCtrl();
m_combochecklist_features->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); m_combochecklist_features->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, combo_style);
std::string feature_items = GUI::into_u8( std::string feature_items = GUI::into_u8(
_L("Unknown") + "|1|" + _L("Unknown") + "|1|" +
_L("Perimeter") + "|1|" + _L("Perimeter") + "|1|" +
@ -244,7 +258,7 @@ bool Preview::init(wxWindow* parent, Model* model)
Slic3r::GUI::create_combochecklist(m_combochecklist_features, GUI::into_u8(_L("Feature types")), feature_items); Slic3r::GUI::create_combochecklist(m_combochecklist_features, GUI::into_u8(_L("Feature types")), feature_items);
m_combochecklist_options = new wxComboCtrl(); m_combochecklist_options = new wxComboCtrl();
m_combochecklist_options->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY); m_combochecklist_options->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, combo_style);
std::string options_items = GUI::into_u8( std::string options_items = GUI::into_u8(
get_option_type_string(OptionType::Travel) + "|0|" + get_option_type_string(OptionType::Travel) + "|0|" +
get_option_type_string(OptionType::Wipe) + "|0|" + get_option_type_string(OptionType::Wipe) + "|0|" +
@ -401,6 +415,17 @@ void Preview::msw_rescale()
void Preview::sys_color_changed() void Preview::sys_color_changed()
{ {
#ifdef _WIN32
wxWindowUpdateLocker noUpdates(this);
wxGetApp().UpdateAllStaticTextDarkUI(m_bottom_toolbar_panel);
wxGetApp().UpdateDarkUI(m_choice_view_type);
wxGetApp().UpdateDarkUI(m_combochecklist_features);
wxGetApp().UpdateDarkUI(static_cast<wxCheckListBoxComboPopup*>(m_combochecklist_features->GetPopupControl()));
wxGetApp().UpdateDarkUI(m_combochecklist_options);
wxGetApp().UpdateDarkUI(static_cast<wxCheckListBoxComboPopup*>(m_combochecklist_options->GetPopupControl()));
#endif
if (m_layers_slider != nullptr) if (m_layers_slider != nullptr)
m_layers_slider->sys_color_changed(); m_layers_slider->sys_color_changed();
} }

View File

@ -15,7 +15,6 @@ class wxBoxSizer;
class wxStaticText; class wxStaticText;
class wxComboBox; class wxComboBox;
class wxComboCtrl; class wxComboCtrl;
class wxBitmapComboBox;
class wxCheckBox; class wxCheckBox;
namespace Slic3r { namespace Slic3r {
@ -36,6 +35,9 @@ class GLToolbar;
class Bed3D; class Bed3D;
struct Camera; struct Camera;
class Plater; class Plater;
#ifdef _WIN32
class BitmapComboBox;
#endif
class View3D : public wxPanel class View3D : public wxPanel
{ {
@ -82,7 +84,11 @@ class Preview : public wxPanel
wxBoxSizer* m_layers_slider_sizer { nullptr }; wxBoxSizer* m_layers_slider_sizer { nullptr };
wxPanel* m_bottom_toolbar_panel { nullptr }; wxPanel* m_bottom_toolbar_panel { nullptr };
wxStaticText* m_label_view_type { nullptr }; wxStaticText* m_label_view_type { nullptr };
#ifdef _WIN32
BitmapComboBox* m_choice_view_type { nullptr };
#else
wxComboBox* m_choice_view_type { nullptr }; wxComboBox* m_choice_view_type { nullptr };
#endif
wxStaticText* m_label_show { nullptr }; wxStaticText* m_label_show { nullptr };
wxComboCtrl* m_combochecklist_features { nullptr }; wxComboCtrl* m_combochecklist_features { nullptr };
size_t m_combochecklist_features_pos { 0 }; size_t m_combochecklist_features_pos { 0 };

View File

@ -6,6 +6,8 @@
#ifdef _WIN32 #ifdef _WIN32
#include <Windows.h> #include <Windows.h>
#include "GUI_App.hpp"
#include "libslic3r/AppConfig.hpp"
#endif #endif
#include <wx/toplevel.h> #include <wx/toplevel.h>
@ -14,6 +16,7 @@
#include <wx/dcclient.h> #include <wx/dcclient.h>
#include <wx/font.h> #include <wx/font.h>
#include <wx/fontutil.h> #include <wx/fontutil.h>
#include <wx/msw/registry.h>
#include "libslic3r/Config.hpp" #include "libslic3r/Config.hpp"
@ -149,6 +152,35 @@ wxFont get_default_font_for_dpi(const wxWindow *window, int dpi)
return wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); return wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
} }
bool check_dark_mode() {
#if 0 //#ifdef _WIN32 // #ysDarkMSW - Allow it when we deside to support the sustem colors for application
wxRegKey rk(wxRegKey::HKCU,
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
if (rk.Exists() && rk.HasValue("AppsUseLightTheme")) {
long value = -1;
rk.QueryValue("AppsUseLightTheme", &value);
return value <= 0;
}
#endif
#if wxCHECK_VERSION(3,1,3)
return wxSystemSettings::GetAppearance().IsDark();
#else
const unsigned luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
return luma < 128;
#endif
}
#ifdef _WIN32
void update_dark_ui(wxWindow* window)
{
bool is_dark = wxGetApp().app_config->get("dark_color_mode") == "1" ? true : check_dark_mode();
window->SetBackgroundColour(is_dark ? wxColour(43, 43, 43) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
window->SetForegroundColour(is_dark ? wxColour(250, 250, 250) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
}
#endif
CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent) CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent)
: wxPanel(parent, wxID_ANY) : wxPanel(parent, wxID_ANY)
{ {

View File

@ -55,6 +55,11 @@ int get_dpi_for_window(const wxWindow *window);
wxFont get_default_font_for_dpi(const wxWindow* window, int dpi); wxFont get_default_font_for_dpi(const wxWindow* window, int dpi);
inline wxFont get_default_font(const wxWindow* window) { return get_default_font_for_dpi(window, get_dpi_for_window(window)); } inline wxFont get_default_font(const wxWindow* window) { return get_default_font_for_dpi(window, get_dpi_for_window(window)); }
bool check_dark_mode();
#ifdef _WIN32
void update_dark_ui(wxWindow* window);
#endif
#if !wxVERSION_EQUAL_OR_GREATER_THAN(3,1,3) #if !wxVERSION_EQUAL_OR_GREATER_THAN(3,1,3)
struct DpiChangedEvent : public wxEvent { struct DpiChangedEvent : public wxEvent {
int dpi; int dpi;
@ -92,6 +97,9 @@ public:
this->SetFont(m_normal_font); this->SetFont(m_normal_font);
#endif #endif
this->CenterOnParent(); this->CenterOnParent();
#ifdef _WIN32
update_dark_ui(this);
#endif
// Linux specific issue : get_dpi_for_window(this) still doesn't responce to the Display's scale in new wxWidgets(3.1.3). // Linux specific issue : get_dpi_for_window(this) still doesn't responce to the Display's scale in new wxWidgets(3.1.3).
// So, calculate the m_em_unit value from the font size, as before // So, calculate the m_em_unit value from the font size, as before
@ -167,6 +175,14 @@ public:
const wxFont& normal_font() const { return m_normal_font; } const wxFont& normal_font() const { return m_normal_font; }
void enable_force_rescale() { m_force_rescale = true; } void enable_force_rescale() { m_force_rescale = true; }
#if 0 //#ifdef _WIN32 // #ysDarkMSW - Use to force dark colors for SystemLightMode
void force_sys_color_changed()
{
update_dark_ui(this);
on_sys_color_changed();
}
#endif
protected: protected:
virtual void on_dpi_changed(const wxRect &suggested_rect) = 0; virtual void on_dpi_changed(const wxRect &suggested_rect) = 0;
virtual void on_sys_color_changed() {}; virtual void on_sys_color_changed() {};
@ -243,6 +259,17 @@ private:
m_prev_scale_factor = m_scale_factor; m_prev_scale_factor = m_scale_factor;
} }
#if 0 //#ifdef _WIN32 // #ysDarkMSW - Allow it when we deside to support the sustem colors for application
bool HandleSettingChange(WXWPARAM wParam, WXLPARAM lParam) override
{
update_dark_ui(this);
on_sys_color_changed();
// let the system handle it
return false;
}
#endif
}; };
typedef DPIAware<wxFrame> DPIFrame; typedef DPIAware<wxFrame> DPIFrame;

View File

@ -17,6 +17,7 @@
#include "slic3r/GUI/GUI_ObjectList.hpp" #include "slic3r/GUI/GUI_ObjectList.hpp"
#include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/NotificationManager.hpp" #include "slic3r/GUI/NotificationManager.hpp"
#include "slic3r/GUI/MsgDialog.hpp"
#include "libslic3r/PresetBundle.hpp" #include "libslic3r/PresetBundle.hpp"
#include "libslic3r/SLAPrint.hpp" #include "libslic3r/SLAPrint.hpp"
@ -920,7 +921,8 @@ void GLGizmoSlaSupports::on_set_state()
wxGetApp().CallAfter([this]() { wxGetApp().CallAfter([this]() {
// Following is called through CallAfter, because otherwise there was a problem // Following is called through CallAfter, because otherwise there was a problem
// on OSX with the wxMessageDialog being shown several times when clicked into. // on OSX with the wxMessageDialog being shown several times when clicked into.
wxMessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually " //wxMessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually "
MessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually "
"edited support points?") + "\n",_L("Save changes?"), wxICON_QUESTION | wxYES | wxNO); "edited support points?") + "\n",_L("Save changes?"), wxICON_QUESTION | wxYES | wxNO);
if (dlg.ShowModal() == wxID_YES) if (dlg.ShowModal() == wxID_YES)
editing_mode_apply_changes(); editing_mode_apply_changes();
@ -1139,7 +1141,8 @@ void GLGizmoSlaSupports::get_data_from_backend()
void GLGizmoSlaSupports::auto_generate() void GLGizmoSlaSupports::auto_generate()
{ {
wxMessageDialog dlg(GUI::wxGetApp().plater(), //wxMessageDialog dlg(GUI::wxGetApp().plater(),
MessageDialog dlg(GUI::wxGetApp().plater(),
_L("Autogeneration will erase all manually edited points.") + "\n\n" + _L("Autogeneration will erase all manually edited points.") + "\n\n" +
_L("Are you sure you want to do it?") + "\n", _L("Are you sure you want to do it?") + "\n",
_L("Warning"), wxICON_WARNING | wxYES | wxNO); _L("Warning"), wxICON_WARNING | wxYES | wxNO);

View File

@ -9,6 +9,7 @@
#include "wxExtensions.hpp" #include "wxExtensions.hpp"
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/listbook.h>
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -17,7 +18,7 @@ KBShortcutsDialog::KBShortcutsDialog()
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, wxString(wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME) + " - " + _L("Keyboard Shortcuts"), : DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, wxString(wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME) + " - " + _L("Keyboard Shortcuts"),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); // SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
// fonts // fonts
const wxFont& font = wxGetApp().normal_font(); const wxFont& font = wxGetApp().normal_font();
@ -28,7 +29,18 @@ KBShortcutsDialog::KBShortcutsDialog()
main_sizer->Add(create_header(this, bold_font), 0, wxEXPAND | wxALL, 10); main_sizer->Add(create_header(this, bold_font), 0, wxEXPAND | wxALL, 10);
#ifdef _MSW_DARK_MODE
wxBookCtrlBase* book;
if (wxGetApp().dark_mode()) {
book = new wxListbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
wxGetApp().UpdateDarkUI(book);
wxGetApp().UpdateDarkUI(dynamic_cast<wxListbook*>(book)->GetListView());
}
else
book = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
#else
wxNotebook* book = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP); wxNotebook* book = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
#endif
main_sizer->Add(book, 1, wxEXPAND | wxALL, 10); main_sizer->Add(book, 1, wxEXPAND | wxALL, 10);
fill_shortcuts(); fill_shortcuts();
@ -39,6 +51,7 @@ KBShortcutsDialog::KBShortcutsDialog()
} }
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK); wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_OK, this)));
this->SetEscapeId(wxID_OK); this->SetEscapeId(wxID_OK);
main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5); main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5);
@ -248,6 +261,7 @@ void KBShortcutsDialog::fill_shortcuts()
wxPanel* KBShortcutsDialog::create_header(wxWindow* parent, const wxFont& bold_font) wxPanel* KBShortcutsDialog::create_header(wxWindow* parent, const wxFont& bold_font)
{ {
wxPanel* panel = new wxPanel(parent); wxPanel* panel = new wxPanel(parent);
wxGetApp().UpdateDarkUI(panel);
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
wxFont header_font = bold_font; wxFont header_font = bold_font;
@ -278,6 +292,7 @@ wxPanel* KBShortcutsDialog::create_header(wxWindow* parent, const wxFont& bold_f
wxPanel* KBShortcutsDialog::create_page(wxWindow* parent, const ShortcutsItem& shortcuts, const wxFont& font, const wxFont& bold_font) wxPanel* KBShortcutsDialog::create_page(wxWindow* parent, const ShortcutsItem& shortcuts, const wxFont& font, const wxFont& bold_font)
{ {
wxPanel* main_page = new wxPanel(parent); wxPanel* main_page = new wxPanel(parent);
wxGetApp().UpdateDarkUI(main_page);
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
if (!shortcuts.first.second.empty()) { if (!shortcuts.first.second.empty()) {
@ -294,6 +309,7 @@ wxPanel* KBShortcutsDialog::create_page(wxWindow* parent, const ShortcutsItem& s
int columns_count = 1 + static_cast<int>(shortcuts.second.size()) / max_items_per_column; int columns_count = 1 + static_cast<int>(shortcuts.second.size()) / max_items_per_column;
wxScrolledWindow* scrollable_panel = new wxScrolledWindow(main_page); wxScrolledWindow* scrollable_panel = new wxScrolledWindow(main_page);
wxGetApp().UpdateDarkUI(scrollable_panel);
scrollable_panel->SetScrollbars(20, 20, 50, 50); scrollable_panel->SetScrollbars(20, 20, 50, 50);
scrollable_panel->SetInitialSize(wxSize(850, 450)); scrollable_panel->SetInitialSize(wxSize(850, 450));

View File

@ -2,6 +2,8 @@
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/listbook.h>
#include <wx/simplebook.h>
#include <wx/icon.h> #include <wx/icon.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/menu.h> #include <wx/menu.h>
@ -38,6 +40,7 @@
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include "UnsavedChangesDialog.hpp" #include "UnsavedChangesDialog.hpp"
#include "MsgDialog.hpp"
#ifdef _WIN32 #ifdef _WIN32
#include <dbt.h> #include <dbt.h>
@ -265,6 +268,84 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
} }
} }
#ifdef _MSW_DARK_MODE
static wxString pref() { return " [ "; }
static wxString suff() { return " ] "; }
static void append_tab_menu_items_to_menubar(wxMenuBar* bar, PrinterTechnology pt, bool is_mainframe_menu)
{
if (is_mainframe_menu)
bar->Append(new wxMenu(), pref() + _L("Plater") + suff());
for (const wxString& title : { is_mainframe_menu ? _L("Print Settings") : pref() + _L("Print Settings") + suff(),
pt == ptSLA ? _L("Material Settings") : _L("Filament Settings"),
_L("Printer Settings") })
bar->Append(new wxMenu(), title);
}
// update markers for selected/unselected menu items
static void update_marker_for_tabs_menu(wxMenuBar* bar, const wxString& title, bool is_mainframe_menu)
{
if (!bar)
return;
size_t items_cnt = bar->GetMenuCount();
for (size_t id = items_cnt - (is_mainframe_menu ? 4 : 3); id < items_cnt; id++) {
wxString label = bar->GetMenuLabel(id);
if (label.First(pref()) == 0) {
if (label == pref() + title + suff())
return;
label.Remove(size_t(0), pref().Len());
label.RemoveLast(suff().Len());
bar->SetMenuLabel(id, label);
break;
}
}
if (int id = bar->FindMenu(title); id != wxNOT_FOUND)
bar->SetMenuLabel(id, pref() + title + suff());
}
static void add_tabs_as_menu(wxMenuBar* bar, MainFrame* main_frame, wxWindow* bar_parent)
{
PrinterTechnology pt = main_frame->plater() ? main_frame->plater()->printer_technology() : ptFFF;
bool is_mainframe_menu = bar_parent == main_frame;
if (!is_mainframe_menu)
append_tab_menu_items_to_menubar(bar, pt, is_mainframe_menu);
bar_parent->Bind(wxEVT_MENU_OPEN, [main_frame, bar, is_mainframe_menu](wxMenuEvent& event) {
wxMenu* const menu = event.GetMenu();
if (!menu || menu->GetMenuItemCount() > 0)
return;
// update tab selection
const wxString& title = menu->GetTitle();
if (title == _L("Plater"))
main_frame->select_tab(size_t(0));
else if (title == _L("Print Settings"))
main_frame->select_tab(wxGetApp().get_tab(main_frame->plater()->printer_technology() == ptFFF ? Preset::TYPE_PRINT : Preset::TYPE_SLA_PRINT));
else if (title == _L("Filament Settings"))
main_frame->select_tab(wxGetApp().get_tab(Preset::TYPE_FILAMENT));
else if (title == _L("Material Settings"))
main_frame->select_tab(wxGetApp().get_tab(Preset::TYPE_SLA_MATERIAL));
else if (title == _L("Printer Settings"))
main_frame->select_tab(wxGetApp().get_tab(Preset::TYPE_PRINTER));
// update markers for selected/unselected menu items
update_marker_for_tabs_menu(bar, title, is_mainframe_menu);
});
}
void MainFrame::show_tabs_menu(bool show)
{
if (show)
append_tab_menu_items_to_menubar(m_menubar, plater() ? plater()->printer_technology() : ptFFF, true);
else
while (m_menubar->GetMenuCount() >= 8) {
if (wxMenu* menu = m_menubar->Remove(7))
delete menu;
}
}
#endif // _MSW_DARK_MODE
void MainFrame::update_layout() void MainFrame::update_layout()
{ {
auto restore_to_creation = [this]() { auto restore_to_creation = [this]() {
@ -305,7 +386,7 @@ void MainFrame::update_layout()
ESettingsLayout layout = wxGetApp().is_gcode_viewer() ? ESettingsLayout::GCodeViewer : ESettingsLayout layout = wxGetApp().is_gcode_viewer() ? ESettingsLayout::GCodeViewer :
(wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : (wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old :
wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ( wxGetApp().dark_mode() || wxGetApp().app_config->get("tabs_as_menu") == "1" ? ESettingsLayout::Old : ESettingsLayout::New) :
wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old); wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old);
if (m_layout == layout) if (m_layout == layout)
@ -330,6 +411,7 @@ void MainFrame::update_layout()
layout == ESettingsLayout::Dlg ? State::toDlg : State::noUpdate; layout == ESettingsLayout::Dlg ? State::toDlg : State::noUpdate;
#endif //__WXMSW__ #endif //__WXMSW__
ESettingsLayout old_layout = m_layout;
m_layout = layout; m_layout = layout;
// From the very beginning the Print settings should be selected // From the very beginning the Print settings should be selected
@ -349,6 +431,14 @@ void MainFrame::update_layout()
m_main_sizer->Add(m_tabpanel, 1, wxEXPAND); m_main_sizer->Add(m_tabpanel, 1, wxEXPAND);
m_plater->Show(); m_plater->Show();
m_tabpanel->Show(); m_tabpanel->Show();
// update Tabs
if (old_layout == ESettingsLayout::Dlg)
if (int sel = m_tabpanel->GetSelection(); sel != wxNOT_FOUND)
m_tabpanel->SetSelection(sel+1);// call SetSelection to correct layout after switching from Dlg to Old mode
#ifdef _MSW_DARK_MODE
if (wxGetApp().dark_mode() || wxGetApp().app_config->get("tabs_as_menu") == "1")
show_tabs_menu(true);
#endif
break; break;
} }
case ESettingsLayout::New: case ESettingsLayout::New:
@ -368,6 +458,11 @@ void MainFrame::update_layout()
m_settings_dialog.GetSizer()->Add(m_tabpanel, 1, wxEXPAND); m_settings_dialog.GetSizer()->Add(m_tabpanel, 1, wxEXPAND);
m_tabpanel->Show(); m_tabpanel->Show();
m_plater->Show(); m_plater->Show();
#ifdef _MSW_DARK_MODE
if (wxGetApp().dark_mode() || wxGetApp().app_config->get("tabs_as_menu") == "1")
show_tabs_menu(false);
#endif
break; break;
} }
case ESettingsLayout::GCodeViewer: case ESettingsLayout::GCodeViewer:
@ -539,21 +634,31 @@ void MainFrame::init_tabpanel()
{ {
// wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10 // wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
// with multiple high resolution displays connected. // with multiple high resolution displays connected.
#ifdef _MSW_DARK_MODE
if (wxGetApp().dark_mode() || wxGetApp().app_config->get("tabs_as_menu") == "1") {
m_tabpanel = new wxSimplebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
wxGetApp().UpdateDarkUI(m_tabpanel);
}
else
m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
#else
m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME); m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
#endif
#ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList #ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font()); m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
#endif
#if wxCHECK_VERSION(3,1,3)
if (wxSystemSettings::GetAppearance().IsDark())
m_tabpanel->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif #endif
m_tabpanel->Hide(); m_tabpanel->Hide();
m_settings_dialog.set_tabpanel(m_tabpanel); m_settings_dialog.set_tabpanel(m_tabpanel);
#ifdef __WXMSW__
m_tabpanel->Bind(/*wxEVT_LISTBOOK_PAGE_CHANGED*/wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent& e) {
#else
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxBookCtrlEvent& e) { m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxBookCtrlEvent& e) {
#endif
#if ENABLE_VALIDATE_CUSTOM_GCODE #if ENABLE_VALIDATE_CUSTOM_GCODE
if (int old_selection = e.GetOldSelection(); if (int old_selection = e.GetOldSelection();
old_selection != wxNOT_FOUND && old_selection < static_cast<int>(m_tabpanel->GetPageCount())) { old_selection != wxNOT_FOUND && old_selection < m_tabpanel->GetPageCount()) {
Tab* old_tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(old_selection)); Tab* old_tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(old_selection));
if (old_tab) if (old_tab)
old_tab->validate_custom_gcodes(); old_tab->validate_custom_gcodes();
@ -896,7 +1001,8 @@ void MainFrame::on_sys_color_changed()
// update label colors in respect to the system mode // update label colors in respect to the system mode
wxGetApp().init_label_colours(); wxGetApp().init_label_colours();
#ifdef __WXMSW__ #ifdef __WXMSW__
m_tabpanel->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); wxGetApp().UpdateDarkUI(m_tabpanel);
m_statusbar->update_dark_ui();
#endif #endif
// update Plater // update Plater
@ -910,6 +1016,8 @@ void MainFrame::on_sys_color_changed()
wxMenuBar* menu_bar = this->GetMenuBar(); wxMenuBar* menu_bar = this->GetMenuBar();
for (size_t id = 0; id < menu_bar->GetMenuCount(); id++) for (size_t id = 0; id < menu_bar->GetMenuCount(); id++)
msw_rescale_menu(menu_bar->GetMenu(id)); msw_rescale_menu(menu_bar->GetMenu(id));
this->Refresh();
} }
#ifdef _MSC_VER #ifdef _MSC_VER
@ -1012,7 +1120,8 @@ void MainFrame::init_menubar_as_editor()
m_plater->load_project(filename); m_plater->load_project(filename);
else else
{ {
wxMessageDialog msg(this, _L("The selected project is no longer available.\nDo you want to remove it from the recent projects list?"), _L("Error"), wxYES_NO | wxYES_DEFAULT); //wxMessageDialog msg(this, _L("The selected project is no longer available.\nDo you want to remove it from the recent projects list?"), _L("Error"), wxYES_NO | wxYES_DEFAULT);
MessageDialog msg(this, _L("The selected project is no longer available.\nDo you want to remove it from the recent projects list?"), _L("Error"), wxYES_NO | wxYES_DEFAULT);
if (msg.ShowModal() == wxID_YES) if (msg.ShowModal() == wxID_YES)
{ {
m_recent_projects.RemoveFileFromHistory(file_id); m_recent_projects.RemoveFileFromHistory(file_id);
@ -1305,8 +1414,21 @@ void MainFrame::init_menubar_as_editor()
// Add additional menus from C++ // Add additional menus from C++
wxGetApp().add_config_menu(m_menubar); wxGetApp().add_config_menu(m_menubar);
m_menubar->Append(helpMenu, _L("&Help")); m_menubar->Append(helpMenu, _L("&Help"));
#ifdef _MSW_DARK_MODE
if (wxGetApp().dark_mode() || wxGetApp().app_config->get("tabs_as_menu") == "1") {
// Add separator
m_menubar->Append(new wxMenu(), " ");
add_tabs_as_menu(m_menubar, this, this);
}
#endif
SetMenuBar(m_menubar); SetMenuBar(m_menubar);
#ifdef _MSW_DARK_MODE
if (wxGetApp().dark_mode() || wxGetApp().app_config->get("tabs_as_menu") == "1")
m_menubar->EnableTop(6, false);
#endif
#ifdef __APPLE__ #ifdef __APPLE__
// This fixes a bug on Mac OS where the quit command doesn't emit window close events // This fixes a bug on Mac OS where the quit command doesn't emit window close events
// wx bug: https://trac.wxwidgets.org/ticket/18328 // wx bug: https://trac.wxwidgets.org/ticket/18328
@ -1391,9 +1513,9 @@ void MainFrame::update_menubar()
m_changeable_menu_items[miSend] ->SetItemLabel((is_fff ? _L("S&end G-code") : _L("S&end to print")) + dots + "\tCtrl+Shift+G"); m_changeable_menu_items[miSend] ->SetItemLabel((is_fff ? _L("S&end G-code") : _L("S&end to print")) + dots + "\tCtrl+Shift+G");
m_changeable_menu_items[miMaterialTab] ->SetItemLabel((is_fff ? _L("&Filament Settings Tab") : _L("Mate&rial Settings Tab")) + "\tCtrl+3"); m_changeable_menu_items[miMaterialTab] ->SetItemLabel((is_fff ? _L("&Filament Settings Tab") : _L("Mate&rial Settings Tab")) + "\tCtrl+3");
m_changeable_menu_items[miMaterialTab] ->SetBitmap(create_scaled_bitmap(is_fff ? "spool" : "resin")); m_changeable_menu_items[miMaterialTab] ->SetBitmap(create_menu_bitmap(is_fff ? "spool" : "resin"));
m_changeable_menu_items[miPrinterTab] ->SetBitmap(create_scaled_bitmap(is_fff ? "printer" : "sla_printer")); m_changeable_menu_items[miPrinterTab] ->SetBitmap(create_menu_bitmap(is_fff ? "printer" : "sla_printer"));
} }
// To perform the "Quck Slice", "Quick Slice and Save As", "Repeat last Quick Slice" and "Slice to SVG". // To perform the "Quck Slice", "Quick Slice and Save As", "Repeat last Quick Slice" and "Slice to SVG".
@ -1424,13 +1546,15 @@ void MainFrame::quick_slice(const int qs)
} }
else { else {
if (m_qs_last_input_file.IsEmpty()) { if (m_qs_last_input_file.IsEmpty()) {
wxMessageDialog dlg(this, _L("No previously sliced file."), //wxMessageDialog dlg(this, _L("No previously sliced file."),
MessageDialog dlg(this, _L("No previously sliced file."),
_L("Error"), wxICON_ERROR | wxOK); _L("Error"), wxICON_ERROR | wxOK);
dlg.ShowModal(); dlg.ShowModal();
return; return;
} }
if (std::ifstream(m_qs_last_input_file.ToUTF8().data())) { if (std::ifstream(m_qs_last_input_file.ToUTF8().data())) {
wxMessageDialog dlg(this, _L("Previously sliced file (")+m_qs_last_input_file+_L(") not found."), //wxMessageDialog dlg(this, _L("Previously sliced file (")+m_qs_last_input_file+_L(") not found."),
MessageDialog dlg(this, _L("Previously sliced file (")+m_qs_last_input_file+_L(") not found."),
_L("File Not Found"), wxICON_ERROR | wxOK); _L("File Not Found"), wxICON_ERROR | wxOK);
dlg.ShowModal(); dlg.ShowModal();
return; return;
@ -1514,7 +1638,8 @@ void MainFrame::quick_slice(const int qs)
auto message = format(_L("%1% was successfully sliced."), input_file_basename); auto message = format(_L("%1% was successfully sliced."), input_file_basename);
// wxTheApp->notify(message); // wxTheApp->notify(message);
wxMessageDialog(this, message, _L("Slicing Done!"), wxOK | wxICON_INFORMATION).ShowModal(); //wxMessageDialog(this, message, _L("Slicing Done!"), wxOK | wxICON_INFORMATION).ShowModal();
MessageDialog(this, message, _L("Slicing Done!"), wxOK | wxICON_INFORMATION).ShowModal();
// }; // };
// Slic3r::GUI::catch_error(this, []() { if (m_progress_dialog) m_progress_dialog->Destroy(); }); // Slic3r::GUI::catch_error(this, []() { if (m_progress_dialog) m_progress_dialog->Destroy(); });
} }
@ -1743,6 +1868,16 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
if (m_tabpanel->GetSelection() != (int)new_selection) if (m_tabpanel->GetSelection() != (int)new_selection)
m_tabpanel->SetSelection(new_selection); m_tabpanel->SetSelection(new_selection);
#ifdef _MSW_DARK_MODE
if (wxGetApp().dark_mode() || wxGetApp().app_config->get("tabs_as_menu") == "1") {
if (Tab* cur_tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(new_selection)))
update_marker_for_tabs_menu((m_layout == ESettingsLayout::Old ? m_menubar : m_settings_dialog.menubar()), cur_tab->title(), m_layout == ESettingsLayout::Old);
else if (tab == 0 && m_layout == ESettingsLayout::Old)
m_plater->get_current_canvas3D()->render();
}
#endif
if (tab == 0 && m_layout == ESettingsLayout::Old)
m_plater->canvas3D()->render();
else if (was_hidden) { else if (was_hidden) {
Tab* cur_tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(new_selection)); Tab* cur_tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(new_selection));
if (cur_tab) if (cur_tab)
@ -1781,6 +1916,8 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
m_settings_dialog.Show(); m_settings_dialog.Show();
} }
#endif #endif
if (m_settings_dialog.IsIconized())
m_settings_dialog.Iconize(false);
} }
else if (m_layout == ESettingsLayout::New) { else if (m_layout == ESettingsLayout::New) {
m_main_sizer->Show(m_plater, tab == 0); m_main_sizer->Show(m_plater, tab == 0);
@ -1884,6 +2021,21 @@ void MainFrame::add_to_recent_projects(const wxString& filename)
} }
} }
void MainFrame::technology_changed()
{
// upadte DiffDlg
diff_dialog.update_presets();
// update menu titles
PrinterTechnology pt = plater()->printer_technology();
if (int id = m_menubar->FindMenu(pt == ptFFF ? _L("Material Settings") : _L("Filament Settings")); id != wxNOT_FOUND)
m_menubar->SetMenuLabel(id , pt == ptSLA ? _L("Material Settings") : _L("Filament Settings"));
//if (wxGetApp().tab_panel()->GetSelection() != wxGetApp().tab_panel()->GetPageCount() - 1)
// wxGetApp().tab_panel()->SetSelection(wxGetApp().tab_panel()->GetPageCount() - 1);
}
// //
// Called after the Preferences dialog is closed and the program settings are saved. // Called after the Preferences dialog is closed and the program settings are saved.
// Update the UI based on the current preferences. // Update the UI based on the current preferences.
@ -1920,8 +2072,9 @@ std::string MainFrame::get_dir_name(const wxString &full_name) const
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
SettingsDialog::SettingsDialog(MainFrame* mainframe) SettingsDialog::SettingsDialog(MainFrame* mainframe)
: DPIDialog(mainframe, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("Settings"), wxDefaultPosition, wxDefaultSize, :DPIFrame(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("Settings"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, "settings_dialog"),
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX, "settings_dialog"), //: DPIDialog(mainframe, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("Settings"), wxDefaultPosition, wxDefaultSize,
// wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX, "settings_dialog"),
m_main_frame(mainframe) m_main_frame(mainframe)
{ {
if (wxGetApp().is_gcode_viewer()) if (wxGetApp().is_gcode_viewer())
@ -1978,6 +2131,18 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
} }
}); });
//just hide the Frame on closing
this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& evt) { this->Hide(); });
#ifdef _MSW_DARK_MODE
if (wxGetApp().dark_mode() || wxGetApp().app_config->get("tabs_as_menu") == "1") {
// menubar
m_menubar = new wxMenuBar();
add_tabs_as_menu(m_menubar, mainframe, this);
this->SetMenuBar(m_menubar);
}
#endif
// initialize layout // initialize layout
auto sizer = new wxBoxSizer(wxVERTICAL); auto sizer = new wxBoxSizer(wxVERTICAL);
sizer->SetSizeHints(this); sizer->SetSizeHints(this);

View File

@ -19,6 +19,7 @@
#include "UnsavedChangesDialog.hpp" #include "UnsavedChangesDialog.hpp"
class wxNotebook; class wxNotebook;
class wxBookCtrlBase;
class wxProgressDialog; class wxProgressDialog;
namespace Slic3r { namespace Slic3r {
@ -52,14 +53,16 @@ struct PresetTab {
// SettingsDialog // SettingsDialog
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class SettingsDialog : public DPIDialog class SettingsDialog : public DPIFrame//DPIDialog
{ {
wxNotebook* m_tabpanel { nullptr }; wxBookCtrlBase* m_tabpanel { nullptr };
MainFrame* m_main_frame { nullptr }; MainFrame* m_main_frame { nullptr };
wxMenuBar* m_menubar{ nullptr };
public: public:
SettingsDialog(MainFrame* mainframe); SettingsDialog(MainFrame* mainframe);
~SettingsDialog() = default; ~SettingsDialog() = default;
void set_tabpanel(wxNotebook* tabpanel) { m_tabpanel = tabpanel; } void set_tabpanel(wxBookCtrlBase* tabpanel) { m_tabpanel = tabpanel; }
wxMenuBar* menubar() { return m_menubar; }
protected: protected:
void on_dpi_changed(const wxRect& suggested_rect) override; void on_dpi_changed(const wxRect& suggested_rect) override;
@ -80,8 +83,6 @@ class MainFrame : public DPIFrame
wxMenuItem* m_menu_item_reslice_now { nullptr }; wxMenuItem* m_menu_item_reslice_now { nullptr };
wxSizer* m_main_sizer{ nullptr }; wxSizer* m_main_sizer{ nullptr };
size_t m_last_selected_tab; size_t m_last_selected_tab;
std::string get_base_name(const wxString &full_name, const char *extension = nullptr) const; std::string get_base_name(const wxString &full_name, const char *extension = nullptr) const;
@ -161,7 +162,9 @@ public:
void init_menubar_as_editor(); void init_menubar_as_editor();
void init_menubar_as_gcodeviewer(); void init_menubar_as_gcodeviewer();
void update_menubar(); void update_menubar();
#ifdef _WIN32
void show_tabs_menu(bool show);
#endif
void update_ui_from_settings(); void update_ui_from_settings();
bool is_loaded() const { return m_loaded; } bool is_loaded() const { return m_loaded; }
bool is_last_input_file() const { return !m_qs_last_input_file.IsEmpty(); } bool is_last_input_file() const { return !m_qs_last_input_file.IsEmpty(); }
@ -194,11 +197,12 @@ public:
#endif // ENABLE_PROJECT_DIRTY_STATE #endif // ENABLE_PROJECT_DIRTY_STATE
void add_to_recent_projects(const wxString& filename); void add_to_recent_projects(const wxString& filename);
void technology_changed();
PrintHostQueueDialog* printhost_queue_dlg() { return m_printhost_queue_dlg; } PrintHostQueueDialog* printhost_queue_dlg() { return m_printhost_queue_dlg; }
Plater* m_plater { nullptr }; Plater* m_plater { nullptr };
wxNotebook* m_tabpanel { nullptr }; wxBookCtrlBase* m_tabpanel { nullptr };
SettingsDialog m_settings_dialog; SettingsDialog m_settings_dialog;
DiffPresetDialog diff_dialog; DiffPresetDialog diff_dialog;
wxWindow* m_plater_page{ nullptr }; wxWindow* m_plater_page{ nullptr };

View File

@ -64,6 +64,59 @@ MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &he
SetSizerAndFit(topsizer); SetSizerAndFit(topsizer);
} }
void MsgDialog::add_btn(wxWindowID btn_id, bool set_focus /*= false*/)
{
wxButton* btn = new wxButton(this, btn_id);
if (set_focus)
btn->SetFocus();
btn_sizer->Add(btn, 0, wxRIGHT, HORIZ_SPACING);
btn->Bind(wxEVT_BUTTON, [this, btn_id](wxCommandEvent&) { this->EndModal(btn_id); });
};
// Text shown as HTML, so that mouse selection and Ctrl-V to copy will work.
static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxString msg, bool monospaced_font = false)
{
wxHtmlWindow* html = new wxHtmlWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
// count lines in the message
int msg_lines = 0;
if (!monospaced_font) {
int line_len = 55;// count of symbols in one line
int start_line = 0;
for (auto i = msg.begin(); i != msg.end(); ++i) {
if (*i == '\n') {
int cur_line_len = i - msg.begin() - start_line;
start_line = i - msg.begin();
if (cur_line_len == 0 || line_len > cur_line_len)
msg_lines++;
else
msg_lines += std::lround((double)(cur_line_len) / line_len);
}
}
msg_lines++;
}
html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), monospaced_font ? 30 * wxGetApp().em_unit() : 2 * msg_lines * wxGetApp().em_unit()));
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
wxFont monospace = wxGetApp().code_font();
wxColour text_clr = wxGetApp().get_label_clr_default();
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
const int font_size = font.GetPointSize();
int size[] = { font_size, font_size, font_size, font_size, font_size, font_size, font_size };
html->SetFonts(font.GetFaceName(), monospace.GetFaceName(), size);
html->SetBorders(2);
std::string msg_escaped = xml_escape(msg.ToUTF8().data());
boost::replace_all(msg_escaped, "\r\n", "<br>");
boost::replace_all(msg_escaped, "\n", "<br>");
if (monospaced_font)
// Code formatting will be preserved. This is useful for reporting errors from the placeholder parser.
msg_escaped = std::string("<pre><code>") + msg_escaped + "</code></pre>";
html->SetPage("<html><body bgcolor=\"" + bgr_clr_str + "\"><font color=\"" + text_clr_str + "\">" + wxString::FromUTF8(msg_escaped.data()) + "</font></body></html>");
content_sizer->Add(html, 1, wxEXPAND | wxBOTTOM, 30);
}
// ErrorDialog // ErrorDialog
ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, bool monospaced_font) ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, bool monospaced_font)
@ -72,36 +125,13 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, bool monospaced_
wxID_NONE) wxID_NONE)
, msg(msg) , msg(msg)
{ {
// Text shown as HTML, so that mouse selection and Ctrl-V to copy will work. add_msg_content(this, content_sizer, msg, monospaced_font);
wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); add_btn(wxID_OK, true);
{
html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), monospaced_font ? 30 * wxGetApp().em_unit() : -1));
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
wxFont monospace = wxGetApp().code_font();
wxColour text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
const int font_size = font.GetPointSize()-1;
int size[] = {font_size, font_size, font_size, font_size, font_size, font_size, font_size};
html->SetFonts(font.GetFaceName(), monospace.GetFaceName(), size);
html->SetBorders(2);
std::string msg_escaped = xml_escape(msg.ToUTF8().data());
boost::replace_all(msg_escaped, "\r\n", "<br>");
boost::replace_all(msg_escaped, "\n", "<br>");
if (monospaced_font)
// Code formatting will be preserved. This is useful for reporting errors from the placeholder parser.
msg_escaped = std::string("<pre><code>") + msg_escaped + "</code></pre>";
html->SetPage("<html><body bgcolor=\"" + bgr_clr_str + "\"><font color=\"" + text_clr_str + "\">" + wxString::FromUTF8(msg_escaped.data()) + "</font></body></html>");
content_sizer->Add(html, 1, wxEXPAND);
}
auto *btn_ok = new wxButton(this, wxID_OK);
btn_ok->SetFocus();
btn_sizer->Add(btn_ok, 0, wxRIGHT, HORIZ_SPACING);
// Use a small bitmap with monospaced font, as the error text will not be wrapped. // Use a small bitmap with monospaced font, as the error text will not be wrapped.
logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, monospaced_font ? 48 : 192)); logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, monospaced_font ? 48 : /*1*/92));
wxGetApp().UpdateDlgDarkUI(this);
SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT*wxGetApp().em_unit())); SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT*wxGetApp().em_unit()));
Fit(); Fit();
@ -115,45 +145,40 @@ WarningDialog::WarningDialog(wxWindow *parent,
long style/* = wxOK*/) long style/* = wxOK*/)
: MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s warning"), SLIC3R_APP_NAME) : caption, : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s warning"), SLIC3R_APP_NAME) : caption,
wxString::Format(_L("%s has a warning")+":", SLIC3R_APP_NAME), wxID_NONE) wxString::Format(_L("%s has a warning")+":", SLIC3R_APP_NAME), wxID_NONE)
, msg(message)
{ {
// Text shown as HTML, so that mouse selection and Ctrl-V to copy will work. add_msg_content(this, content_sizer, message);
wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
{
html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), 10 * wxGetApp().em_unit()));
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
wxFont monospace = wxGetApp().code_font();
wxColour text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
const int font_size = font.GetPointSize();
int size[] = {font_size, font_size, font_size, font_size, font_size, font_size, font_size};
html->SetFonts(font.GetFaceName(), monospace.GetFaceName(), size);
html->SetBorders(2);
std::string msg_escaped = xml_escape(msg.ToUTF8().data());
boost::replace_all(msg_escaped, "\r\n", "<br>");
boost::replace_all(msg_escaped, "\n", "<br>");
html->SetPage("<html><body bgcolor=\"" + bgr_clr_str + "\"><font color=\"" + text_clr_str + "\">" + wxString::FromUTF8(msg_escaped.data()) + "</font></body></html>");
content_sizer->Add(html, 1, wxEXPAND|wxBOTTOM, BORDER);
}
auto add_btn = [this](wxWindowID btn_id) { if (style & wxOK) add_btn(wxID_OK, true);
auto* btn = new wxButton(this, btn_id); if (style & wxYES) add_btn(wxID_YES);
btn_sizer->Add(btn, 0, wxRIGHT, HORIZ_SPACING); if (style & wxNO) add_btn(wxID_NO);
btn->Bind(wxEVT_BUTTON, [this, btn_id](wxCommandEvent&) { this->EndModal(btn_id); });
};
if (style & wxOK) logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, 90));
add_btn(wxID_OK);
if (style & wxYES)
add_btn(wxID_YES);
if (style & wxNO)
add_btn(wxID_NO);
logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, 150)); wxGetApp().UpdateDlgDarkUI(this);
Fit();
}
SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT*wxGetApp().em_unit()));
// MessageDialog
MessageDialog::MessageDialog(wxWindow* parent,
const wxString& message,
const wxString& caption/* = wxEmptyString*/,
long style/* = wxOK*/)
: MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, wxEmptyString, wxID_NONE)
{
add_msg_content(this, content_sizer, message);
if (style & wxOK) add_btn(wxID_OK, true);
if (style & wxYES) add_btn(wxID_YES);
if (style & wxNO) add_btn(wxID_NO);
if (style & wxCANCEL) add_btn(wxID_CANCEL);
logo->SetBitmap(create_scaled_bitmap(style & wxICON_WARNING ? "exclamation" :
style & wxICON_INFORMATION ? "info.png" :
style & wxICON_QUESTION ? "question" : "PrusaSlicer_192px_grayscale.png", this, 90));
wxGetApp().UpdateDlgDarkUI(this);
Fit(); Fit();
} }

View File

@ -31,7 +31,7 @@ struct MsgDialog : wxDialog
protected: protected:
enum { enum {
CONTENT_WIDTH = 50, CONTENT_WIDTH = 70,//50,
CONTENT_MAX_HEIGHT = 60, CONTENT_MAX_HEIGHT = 60,
BORDER = 30, BORDER = 30,
VERT_SPACING = 15, VERT_SPACING = 15,
@ -41,6 +41,8 @@ protected:
// button_id is an id of a button that can be added by default, use wxID_NONE to disable // button_id is an id of a button that can be added by default, use wxID_NONE to disable
MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id = wxID_OK, wxBitmap bitmap = wxNullBitmap); MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id = wxID_OK, wxBitmap bitmap = wxNullBitmap);
void add_btn(wxWindowID btn_id, bool set_focus = false);
wxFont boldfont; wxFont boldfont;
wxBoxSizer *content_sizer; wxBoxSizer *content_sizer;
wxBoxSizer *btn_sizer; wxBoxSizer *btn_sizer;
@ -66,12 +68,10 @@ private:
}; };
// Generic error dialog, used for displaying exceptions // Generic warning dialog, used for displaying exceptions
class WarningDialog : public MsgDialog class WarningDialog : public MsgDialog
{ {
public: public:
// If monospaced_font is true, the error message is displayed using html <code><pre></pre></code> tags,
// so that the code formatting will be preserved. This is useful for reporting errors from the placeholder parser.
WarningDialog( wxWindow *parent, WarningDialog( wxWindow *parent,
const wxString& message, const wxString& message,
const wxString& caption = wxEmptyString, const wxString& caption = wxEmptyString,
@ -81,9 +81,22 @@ public:
WarningDialog &operator=(WarningDialog&&) = delete; WarningDialog &operator=(WarningDialog&&) = delete;
WarningDialog &operator=(const WarningDialog&) = delete; WarningDialog &operator=(const WarningDialog&) = delete;
virtual ~WarningDialog() = default; virtual ~WarningDialog() = default;
};
private:
wxString msg; // Generic message dialog, used intead of wxMessageDialog
class MessageDialog : public MsgDialog
{
public:
MessageDialog( wxWindow *parent,
const wxString& message,
const wxString& caption = wxEmptyString,
long style = wxOK);
MessageDialog(MessageDialog&&) = delete;
MessageDialog(const MessageDialog&) = delete;
MessageDialog &operator=(MessageDialog&&) = delete;
MessageDialog &operator=(const MessageDialog&) = delete;
virtual ~MessageDialog() = default;
}; };

View File

@ -2,6 +2,7 @@
#include "OptionsGroup.hpp" #include "OptionsGroup.hpp"
#include "Plater.hpp" #include "Plater.hpp"
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include "MsgDialog.hpp"
#include "libslic3r/AppConfig.hpp" #include "libslic3r/AppConfig.hpp"
#include <wx/utils.h> #include <wx/utils.h>
@ -353,6 +354,8 @@ void OG_CustomCtrl::correct_widgets_position(wxSizer* widget, const Line& line,
wxPoint pos = line_pos; wxPoint pos = line_pos;
wxSize sz = child->GetWindow()->GetSize(); wxSize sz = child->GetWindow()->GetSize();
pos.y += std::max(0, int(0.5 * (line_height - sz.y))); pos.y += std::max(0, int(0.5 * (line_height - sz.y)));
if (line.extra_widget_sizer && widget == line.extra_widget_sizer)
pos.x += m_h_gap;
child->GetWindow()->SetPosition(pos); child->GetWindow()->SetPosition(pos);
line_pos.x += sz.x + m_h_gap; line_pos.x += sz.x + m_h_gap;
} }
@ -631,7 +634,12 @@ wxCoord OG_CustomCtrl::CtrlLine::draw_text(wxDC& dc, wxPoint pos, const wxStr
#else #else
dc.SetFont(old_font.Bold().Underlined()); dc.SetFont(old_font.Bold().Underlined());
#endif #endif
dc.SetTextForeground(color ? *color : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); dc.SetTextForeground(color ? *color :
#ifdef _WIN32
wxGetApp().get_label_clr_default());
#else
wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
#endif /* _WIN32 */
dc.DrawText(out_text, pos); dc.DrawText(out_text, pos);
dc.SetTextForeground(old_clr); dc.SetTextForeground(old_clr);
dc.SetFont(old_font); dc.SetFont(old_font);
@ -703,7 +711,6 @@ bool OG_CustomCtrl::CtrlLine::launch_browser() const
RememberChoiceDialog::RememberChoiceDialog(wxWindow* parent, const wxString& msg_text, const wxString& caption) RememberChoiceDialog::RememberChoiceDialog(wxWindow* parent, const wxString& msg_text, const wxString& caption)
: wxDialog(parent, wxID_ANY, caption, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxICON_INFORMATION) : wxDialog(parent, wxID_ANY, caption, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxICON_INFORMATION)
{ {
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
this->SetEscapeId(wxID_CLOSE); this->SetEscapeId(wxID_CLOSE);
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
@ -720,7 +727,8 @@ RememberChoiceDialog::RememberChoiceDialog(wxWindow* parent, const wxString& msg
_L("You will not be asked about it again on label hovering.") + "\n\n" + _L("You will not be asked about it again on label hovering.") + "\n\n" +
format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto changes your choice."), preferences_item); format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto changes your choice."), preferences_item);
wxMessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION); //wxMessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
MessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
if (dialog.ShowModal() == wxID_CANCEL) if (dialog.ShowModal() == wxID_CANCEL)
m_remember_choice->SetValue(false); m_remember_choice->SetValue(false);
}); });
@ -737,6 +745,11 @@ RememberChoiceDialog::RememberChoiceDialog(wxWindow* parent, const wxString& msg
topSizer->Add(m_remember_choice, 0, wxEXPAND | wxALL, 10); topSizer->Add(m_remember_choice, 0, wxEXPAND | wxALL, 10);
topSizer->Add(btns, 0, wxEXPAND | wxALL, 10); topSizer->Add(btns, 0, wxEXPAND | wxALL, 10);
#ifdef _WIN32
wxGetApp().UpdateDlgDarkUI(this);
#else
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
this->SetSizer(topSizer); this->SetSizer(topSizer);
topSizer->SetSizeHints(this); topSizer->SetSizeHints(this);

View File

@ -171,7 +171,7 @@ void ObjectDataViewModelNode::update_settings_digest_bitmaps()
if (bmp == nullptr) { if (bmp == nullptr) {
std::vector<wxBitmap> bmps; std::vector<wxBitmap> bmps;
for (auto& category : m_opt_categories) for (auto& category : m_opt_categories)
bmps.emplace_back(SettingsFactory::get_category_bitmap(category)); bmps.emplace_back(SettingsFactory::get_category_bitmap(category, false));
bmp = m_bitmap_cache->insert(scaled_bitmap_name, bmps); bmp = m_bitmap_cache->insert(scaled_bitmap_name, bmps);
} }

View File

@ -411,6 +411,7 @@ bool OptionsGroup::activate(std::function<void()> throw_if_canceled)
stb = new wxStaticBox(m_parent, wxID_ANY, _(title)); stb = new wxStaticBox(m_parent, wxID_ANY, _(title));
if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT); if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT);
stb->SetFont(wxOSX ? wxGetApp().normal_font() : wxGetApp().bold_font()); stb->SetFont(wxOSX ? wxGetApp().normal_font() : wxGetApp().bold_font());
wxGetApp().UpdateDarkUI(stb);
} }
else else
stb = nullptr; stb = nullptr;
@ -738,6 +739,39 @@ void ConfigOptionsGroup::msw_rescale()
void ConfigOptionsGroup::sys_color_changed() void ConfigOptionsGroup::sys_color_changed()
{ {
#ifdef _WIN32
if (staticbox && stb) {
wxGetApp().UpdateAllStaticTextDarkUI(stb);
// update bitmaps for extra column items (like "delete" buttons on settings panel)
for (auto extra_col : m_extra_column_item_ptrs)
wxGetApp().UpdateDarkUI(extra_col);
}
auto update = [](wxSizer* sizer) {
for (wxSizerItem* item : sizer->GetChildren())
if (item->IsWindow()) {
wxWindow* win = item->GetWindow();
// check if window is ScalableButton
if (ScalableButton* sc_btn = dynamic_cast<ScalableButton*>(win)) {
sc_btn->msw_rescale();
return;
}
wxGetApp().UpdateDarkUI(win, dynamic_cast<wxButton*>(win) != nullptr);
}
};
// scale widgets and extra widgets if any exists
for (const Line& line : m_lines) {
if (line.widget_sizer)
update(line.widget_sizer);
if (line.extra_widget_sizer)
update(line.extra_widget_sizer);
}
if (custom_ctrl)
wxGetApp().UpdateDarkUI(custom_ctrl);
#endif
// update undo buttons : rescale bitmaps // update undo buttons : rescale bitmaps
for (const auto& field : m_fields) for (const auto& field : m_fields)
field.second->sys_color_changed(); field.second->sys_color_changed();

View File

@ -87,7 +87,8 @@ using t_optionfield_map = std::map<t_config_option_key, t_field>;
using t_opt_map = std::map< std::string, std::pair<std::string, int> >; using t_opt_map = std::map< std::string, std::pair<std::string, int> >;
class OptionsGroup { class OptionsGroup {
wxStaticBox* stb; protected:
wxStaticBox* stb {nullptr};
public: public:
const bool staticbox {true}; const bool staticbox {true};
const wxString title; const wxString title;

View File

@ -31,6 +31,7 @@
#include "RemovableDriveManager.hpp" #include "RemovableDriveManager.hpp"
#include "BitmapCache.hpp" #include "BitmapCache.hpp"
#include "BonjourDialog.hpp" #include "BonjourDialog.hpp"
#include "MsgDialog.hpp"
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -156,8 +157,9 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent, wxString printer_
m_printer("", wxGetApp().preset_bundle->physical_printers.default_config()) m_printer("", wxGetApp().preset_bundle->physical_printers.default_config())
{ {
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
#ifndef _WIN32
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
m_default_name = _L("Type here the name of your printer device"); m_default_name = _L("Type here the name of your printer device");
bool new_printer = true; bool new_printer = true;
@ -171,12 +173,13 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent, wxString printer_
wxStaticText* label_top = new wxStaticText(this, wxID_ANY, _L("Descriptive name for the printer") + ":"); wxStaticText* label_top = new wxStaticText(this, wxID_ANY, _L("Descriptive name for the printer") + ":");
m_add_preset_btn = new ScalableButton(this, wxID_ANY, "add_copies", "", wxDefaultSize, wxDefaultPosition, /*wxBU_LEFT | */wxBU_EXACTFIT); m_add_preset_btn = new ScalableButton(this, wxID_ANY, "add_copies", "", wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT);
m_add_preset_btn->SetFont(wxGetApp().normal_font()); m_add_preset_btn->SetFont(wxGetApp().normal_font());
m_add_preset_btn->SetToolTip(_L("Add preset for this printer device")); m_add_preset_btn->SetToolTip(_L("Add preset for this printer device"));
m_add_preset_btn->Bind(wxEVT_BUTTON, &PhysicalPrinterDialog::AddPreset, this); m_add_preset_btn->Bind(wxEVT_BUTTON, &PhysicalPrinterDialog::AddPreset, this);
m_printer_name = new wxTextCtrl(this, wxID_ANY, printer_name, wxDefaultPosition, wxDefaultSize); m_printer_name = new wxTextCtrl(this, wxID_ANY, printer_name, wxDefaultPosition, wxDefaultSize);
wxGetApp().UpdateDarkUI(m_printer_name);
m_printer_name->Bind(wxEVT_TEXT, [this](wxEvent&) { this->update_full_printer_names(); }); m_printer_name->Bind(wxEVT_TEXT, [this](wxEvent&) { this->update_full_printer_names(); });
PhysicalPrinterCollection& printers = wxGetApp().preset_bundle->physical_printers; PhysicalPrinterCollection& printers = wxGetApp().preset_bundle->physical_printers;
@ -207,8 +210,11 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent, wxString printer_
wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL); wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
wxButton* btnOK = static_cast<wxButton*>(this->FindWindowById(wxID_OK, this)); wxButton* btnOK = static_cast<wxButton*>(this->FindWindowById(wxID_OK, this));
wxGetApp().UpdateDarkUI(btnOK);
btnOK->Bind(wxEVT_BUTTON, &PhysicalPrinterDialog::OnOK, this); btnOK->Bind(wxEVT_BUTTON, &PhysicalPrinterDialog::OnOK, this);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
wxBoxSizer* nameSizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* nameSizer = new wxBoxSizer(wxHORIZONTAL);
nameSizer->Add(m_printer_name, 1, wxEXPAND); nameSizer->Add(m_printer_name, 1, wxEXPAND);
nameSizer->Add(m_add_preset_btn, 0, wxEXPAND | wxLEFT, BORDER_W); nameSizer->Add(m_add_preset_btn, 0, wxEXPAND | wxLEFT, BORDER_W);
@ -554,7 +560,8 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event)
{ {
wxString msg_text = from_u8((boost::format(_u8L("Printer with name \"%1%\" already exists.")) % existing->name/*printer_name*/).str()); wxString msg_text = from_u8((boost::format(_u8L("Printer with name \"%1%\" already exists.")) % existing->name/*printer_name*/).str());
msg_text += "\n" + _L("Replace?"); msg_text += "\n" + _L("Replace?");
wxMessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxYES | wxNO); //wxMessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxYES | wxNO);
MessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxYES | wxNO);
if (dialog.ShowModal() == wxID_NO) if (dialog.ShowModal() == wxID_NO)
return; return;
@ -583,7 +590,8 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event)
"The above preset for printer \"%2%\" will be used just once.", "The above preset for printer \"%2%\" will be used just once.",
"Following printer presets are duplicated:%1%" "Following printer presets are duplicated:%1%"
"The above presets for printer \"%2%\" will be used just once.", repeat_cnt), repeatable_presets, printer_name); "The above presets for printer \"%2%\" will be used just once.", repeat_cnt), repeatable_presets, printer_name);
wxMessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxOK | wxCANCEL); //wxMessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxOK | wxCANCEL);
MessageDialog dialog(nullptr, msg_text, _L("Warning"), wxICON_WARNING | wxOK | wxCANCEL);
if (dialog.ShowModal() == wxID_CANCEL) if (dialog.ShowModal() == wxID_CANCEL)
return; return;
} }
@ -628,7 +636,8 @@ void PhysicalPrinterDialog::DeletePreset(PresetForPrinter* preset_for_printer)
{ {
if (m_presets.size() == 1) { if (m_presets.size() == 1) {
wxString msg_text = _L("It's not possible to delete the last related preset for the printer."); wxString msg_text = _L("It's not possible to delete the last related preset for the printer.");
wxMessageDialog dialog(nullptr, msg_text, _L("Information"), wxICON_INFORMATION | wxOK); //wxMessageDialog dialog(nullptr, msg_text, _L("Information"), wxICON_INFORMATION | wxOK);
MessageDialog dialog(nullptr, msg_text, _L("Information"), wxICON_INFORMATION | wxOK);
dialog.ShowModal(); dialog.ShowModal();
return; return;
} }

View File

@ -81,6 +81,7 @@
#include "InstanceCheck.hpp" #include "InstanceCheck.hpp"
#include "NotificationManager.hpp" #include "NotificationManager.hpp"
#include "PresetComboBoxes.hpp" #include "PresetComboBoxes.hpp"
#include "MsgDialog.hpp"
#if ENABLE_PROJECT_DIRTY_STATE #if ENABLE_PROJECT_DIRTY_STATE
#include "ProjectDirtyStateManager.hpp" #include "ProjectDirtyStateManager.hpp"
#endif // ENABLE_PROJECT_DIRTY_STATE #endif // ENABLE_PROJECT_DIRTY_STATE
@ -149,6 +150,7 @@ ObjectInfo::ObjectInfo(wxWindow *parent) :
wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _L("Info")), wxVERTICAL) wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _L("Info")), wxVERTICAL)
{ {
GetStaticBox()->SetFont(wxGetApp().bold_font()); GetStaticBox()->SetFont(wxGetApp().bold_font());
wxGetApp().UpdateDarkUI(GetStaticBox());
auto *grid_sizer = new wxFlexGridSizer(4, 5, 15); auto *grid_sizer = new wxFlexGridSizer(4, 5, 15);
grid_sizer->SetFlexibleDirection(wxHORIZONTAL); grid_sizer->SetFlexibleDirection(wxHORIZONTAL);
@ -224,6 +226,7 @@ SlicedInfo::SlicedInfo(wxWindow *parent) :
wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _L("Sliced Info")), wxVERTICAL) wxStaticBoxSizer(new wxStaticBox(parent, wxID_ANY, _L("Sliced Info")), wxVERTICAL)
{ {
GetStaticBox()->SetFont(wxGetApp().bold_font()); GetStaticBox()->SetFont(wxGetApp().bold_font());
wxGetApp().UpdateDarkUI(GetStaticBox());
auto *grid_sizer = new wxFlexGridSizer(2, 5, 15); auto *grid_sizer = new wxFlexGridSizer(2, 5, 15);
grid_sizer->SetFlexibleDirection(wxVERTICAL); grid_sizer->SetFlexibleDirection(wxVERTICAL);
@ -283,6 +286,7 @@ public:
void Show(const bool is_fff) override; void Show(const bool is_fff) override;
void msw_rescale(); void msw_rescale();
void sys_color_changed();
}; };
void FreqChangedParams::msw_rescale() void FreqChangedParams::msw_rescale()
@ -294,6 +298,17 @@ void FreqChangedParams::msw_rescale()
btn->msw_rescale(); btn->msw_rescale();
} }
void FreqChangedParams::sys_color_changed()
{
m_og->sys_color_changed();
m_og_sla->sys_color_changed();
for (auto btn: m_empty_buttons)
btn->msw_rescale();
wxGetApp().UpdateDarkUI(m_wiping_dialog_button, true);
}
FreqChangedParams::FreqChangedParams(wxWindow* parent) : FreqChangedParams::FreqChangedParams(wxWindow* parent) :
OG_Settings(parent, false) OG_Settings(parent, false)
{ {
@ -411,6 +426,8 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
auto wiping_dialog_btn = [this](wxWindow* parent) { auto wiping_dialog_btn = [this](wxWindow* parent) {
m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _L("Purging volumes") + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _L("Purging volumes") + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
m_wiping_dialog_button->SetFont(wxGetApp().normal_font()); m_wiping_dialog_button->SetFont(wxGetApp().normal_font());
wxGetApp().UpdateDarkUI(m_wiping_dialog_button, true);
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_wiping_dialog_button, 0, wxALIGN_CENTER_VERTICAL); sizer->Add(m_wiping_dialog_button, 0, wxALIGN_CENTER_VERTICAL);
m_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e) m_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e)
@ -640,7 +657,12 @@ Sidebar::Sidebar(Plater *parent)
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
#ifndef __APPLE__ #ifndef __APPLE__
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this);
wxGetApp().UpdateDarkUI(p->scrolled);
#else
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
#endif #endif
// Sizer in the scrolled area // Sizer in the scrolled area
@ -648,7 +670,7 @@ Sidebar::Sidebar(Plater *parent)
p->scrolled->SetSizer(scrolled_sizer); p->scrolled->SetSizer(scrolled_sizer);
// Sizer with buttons for mode changing // Sizer with buttons for mode changing
p->mode_sizer = new ModeSizer(p->scrolled); p->mode_sizer = new ModeSizer(p->scrolled, int(0.5 * wxGetApp().em_unit()));
// The preset chooser // The preset chooser
p->sizer_presets = new wxFlexGridSizer(10, 1, 1, 2); p->sizer_presets = new wxFlexGridSizer(10, 1, 1, 2);
@ -660,6 +682,7 @@ Sidebar::Sidebar(Plater *parent)
p->scrolled->SetDoubleBuffered(true); p->scrolled->SetDoubleBuffered(true);
p->presets_panel = new wxPanel(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); p->presets_panel = new wxPanel(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
wxGetApp().UpdateDarkUI(p->presets_panel);
p->presets_panel->SetSizer(p->sizer_presets); p->presets_panel->SetSizer(p->sizer_presets);
is_msw = true; is_msw = true;
@ -763,11 +786,16 @@ Sidebar::Sidebar(Plater *parent)
// regular buttons "Slice now" and "Export G-code" // regular buttons "Slice now" and "Export G-code"
// const int scaled_height = p->btn_eject_device->GetBitmapHeight() + 4; // const int scaled_height = p->btn_eject_device->GetBitmapHeight() + 4;
#ifdef _WIN32
const int scaled_height = p->btn_export_gcode_removable->GetBitmapHeight();
#else
const int scaled_height = p->btn_export_gcode_removable->GetBitmapHeight() + 4; const int scaled_height = p->btn_export_gcode_removable->GetBitmapHeight() + 4;
#endif
auto init_btn = [this](wxButton **btn, wxString label, const int button_height) { auto init_btn = [this](wxButton **btn, wxString label, const int button_height) {
*btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition, *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition,
wxSize(-1, button_height), wxBU_EXACTFIT); wxSize(-1, button_height), wxBU_EXACTFIT);
(*btn)->SetFont(wxGetApp().bold_font()); (*btn)->SetFont(wxGetApp().bold_font());
wxGetApp().UpdateDarkUI((*btn), true);
}; };
init_btn(&p->btn_export_gcode, _L("Export G-code") + dots , scaled_height); init_btn(&p->btn_export_gcode, _L("Export G-code") + dots , scaled_height);
@ -779,8 +807,8 @@ Sidebar::Sidebar(Plater *parent)
auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL); auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL);
complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND); complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND);
complect_btns_sizer->Add(p->btn_send_gcode); complect_btns_sizer->Add(p->btn_send_gcode, 0, wxLEFT, margin_5);
complect_btns_sizer->Add(p->btn_export_gcode_removable); complect_btns_sizer->Add(p->btn_export_gcode_removable, 0, wxLEFT, margin_5);
// complect_btns_sizer->Add(p->btn_eject_device); // complect_btns_sizer->Add(p->btn_eject_device);
@ -958,7 +986,11 @@ void Sidebar::msw_rescale()
p->btn_send_gcode->msw_rescale(); p->btn_send_gcode->msw_rescale();
// p->btn_eject_device->msw_rescale(); // p->btn_eject_device->msw_rescale();
p->btn_export_gcode_removable->msw_rescale(); p->btn_export_gcode_removable->msw_rescale();
const int scaled_height = p->btn_export_gcode_removable->GetBitmap().GetHeight() + 4; #ifdef _WIN32
const int scaled_height = p->btn_export_gcode_removable->GetBitmapHeight();
#else
const int scaled_height = p->btn_export_gcode_removable->GetBitmapHeight() + 4;
#endif
p->btn_export_gcode->SetMinSize(wxSize(-1, scaled_height)); p->btn_export_gcode->SetMinSize(wxSize(-1, scaled_height));
p->btn_reslice ->SetMinSize(wxSize(-1, scaled_height)); p->btn_reslice ->SetMinSize(wxSize(-1, scaled_height));
@ -967,19 +999,29 @@ void Sidebar::msw_rescale()
void Sidebar::sys_color_changed() void Sidebar::sys_color_changed()
{ {
#ifdef __WXMSW__ #ifdef _WIN32
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); wxWindowUpdateLocker noUpdates(this);
for (wxWindow* win : std::vector<wxWindow*>{ this, p->sliced_info->GetStaticBox(), p->object_info->GetStaticBox(), p->btn_reslice, p->btn_export_gcode })
wxGetApp().UpdateDarkUI(win);
for (wxWindow* win : std::vector<wxWindow*>{ p->scrolled, p->presets_panel })
wxGetApp().UpdateAllStaticTextDarkUI(win);
for (wxWindow* btn : std::vector<wxWindow*>{ p->btn_reslice, p->btn_export_gcode })
wxGetApp().UpdateDarkUI(btn, true);
p->mode_sizer->msw_rescale();
p->frequently_changed_parameters->sys_color_changed();
p->object_settings->sys_color_changed();
#endif #endif
for (PlaterPresetComboBox* combo : std::vector<PlaterPresetComboBox*>{ p->combo_print, for (PlaterPresetComboBox* combo : std::vector<PlaterPresetComboBox*>{ p->combo_print,
p->combo_sla_print, p->combo_sla_print,
p->combo_sla_material, p->combo_sla_material,
p->combo_printer }) p->combo_printer })
combo->msw_rescale(); combo->sys_color_changed();
for (PlaterPresetComboBox* combo : p->combos_filament) for (PlaterPresetComboBox* combo : p->combos_filament)
combo->msw_rescale(); combo->sys_color_changed();
p->object_list->msw_rescale();
p->object_list->sys_color_changed(); p->object_list->sys_color_changed();
p->object_manipulation->sys_color_changed(); p->object_manipulation->sys_color_changed();
p->object_layers->sys_color_changed(); p->object_layers->sys_color_changed();
@ -1531,7 +1573,8 @@ struct Plater::priv
if (dirty_state.is_dirty()) { if (dirty_state.is_dirty()) {
MainFrame* mainframe = wxGetApp().mainframe; MainFrame* mainframe = wxGetApp().mainframe;
if (mainframe->can_save_as()) { if (mainframe->can_save_as()) {
wxMessageDialog dlg(mainframe, _L("Do you want to save the changes to the current project ?"), wxString(SLIC3R_APP_NAME), wxYES_NO | wxCANCEL); //wxMessageDialog dlg(mainframe, _L("Do you want to save the changes to the current project ?"), wxString(SLIC3R_APP_NAME), wxYES_NO | wxCANCEL);
MessageDialog dlg(mainframe, _L("Do you want to save the changes to the current project ?"), wxString(SLIC3R_APP_NAME), wxYES_NO | wxCANCEL);
int res = dlg.ShowModal(); int res = dlg.ShowModal();
if (res == wxID_YES) if (res == wxID_YES)
mainframe->save_project_as(wxGetApp().plater()->get_project_filename()); mainframe->save_project_as(wxGetApp().plater()->get_project_filename());
@ -2311,7 +2354,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
// Convert even if the object is big. // Convert even if the object is big.
convert_from_imperial_units(model, false); convert_from_imperial_units(model, false);
else if (model.looks_like_saved_in_meters()) { else if (model.looks_like_saved_in_meters()) {
wxMessageDialog msg_dlg(q, format_wxstr(_L_PLURAL( //wxMessageDialog msg_dlg(q, format_wxstr(_L_PLURAL(
MessageDialog msg_dlg(q, format_wxstr(_L_PLURAL(
"The object in file %s looks like saved in meters.\n" "The object in file %s looks like saved in meters.\n"
"Should I consider it as a saved in meters and convert it?", "Should I consider it as a saved in meters and convert it?",
"Some objects in file %s look like saved in meters.\n" "Some objects in file %s look like saved in meters.\n"
@ -2322,7 +2366,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
model.convert_from_meters(true); model.convert_from_meters(true);
} }
else if (model.looks_like_imperial_units()) { else if (model.looks_like_imperial_units()) {
wxMessageDialog msg_dlg(q, format_wxstr(_L_PLURAL( //wxMessageDialog msg_dlg(q, format_wxstr(_L_PLURAL(
MessageDialog msg_dlg(q, format_wxstr(_L_PLURAL(
"The object in file %s looks like saved in inches.\n" "The object in file %s looks like saved in inches.\n"
"Should I consider it as a saved in inches and convert it?", "Should I consider it as a saved in inches and convert it?",
"Some objects in file %s look like saved in inches.\n" "Some objects in file %s look like saved in inches.\n"
@ -2334,7 +2379,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
} }
if (model.looks_like_multipart_object()) { if (model.looks_like_multipart_object()) {
wxMessageDialog msg_dlg(q, _L( //wxMessageDialog msg_dlg(q, _L(
MessageDialog msg_dlg(q, _L(
"This file contains several objects positioned at multiple heights.\n" "This file contains several objects positioned at multiple heights.\n"
"Instead of considering them as multiple objects, should I consider\n" "Instead of considering them as multiple objects, should I consider\n"
"this file as a single object having multiple parts?") + "\n", "this file as a single object having multiple parts?") + "\n",
@ -2345,7 +2391,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
} }
} }
else if ((wxGetApp().get_mode() == comSimple) && (type_3mf || type_any_amf) && model_has_advanced_features(model)) { else if ((wxGetApp().get_mode() == comSimple) && (type_3mf || type_any_amf) && model_has_advanced_features(model)) {
wxMessageDialog msg_dlg(q, _L("This file cannot be loaded in a simple mode. Do you want to switch to an advanced mode?")+"\n", //wxMessageDialog msg_dlg(q, _L("This file cannot be loaded in a simple mode. Do you want to switch to an advanced mode?")+"\n",
MessageDialog msg_dlg(q, _L("This file cannot be loaded in a simple mode. Do you want to switch to an advanced mode?")+"\n",
_L("Detected advanced data"), wxICON_WARNING | wxYES | wxNO); _L("Detected advanced data"), wxICON_WARNING | wxYES | wxNO);
if (msg_dlg.ShowModal() == wxID_YES) { if (msg_dlg.ShowModal() == wxID_YES) {
Slic3r::GUI::wxGetApp().save_mode(comAdvanced); Slic3r::GUI::wxGetApp().save_mode(comAdvanced);
@ -2397,7 +2444,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
} }
if (new_model != nullptr && new_model->objects.size() > 1) { if (new_model != nullptr && new_model->objects.size() > 1) {
wxMessageDialog msg_dlg(q, _L( //wxMessageDialog msg_dlg(q, _L(
MessageDialog msg_dlg(q, _L(
"Multiple objects were loaded for a multi-material printer.\n" "Multiple objects were loaded for a multi-material printer.\n"
"Instead of considering them as multiple objects, should I consider\n" "Instead of considering them as multiple objects, should I consider\n"
"these files to represent a single object having multiple parts?") + "\n", "these files to represent a single object having multiple parts?") + "\n",
@ -3154,7 +3202,7 @@ void Plater::priv::replace_with_stl()
fs::path out_path = dialog.GetPath().ToUTF8().data(); fs::path out_path = dialog.GetPath().ToUTF8().data();
if (out_path.empty()) { if (out_path.empty()) {
wxMessageDialog dlg(q, _L("File for the replace wasn't selected"), _L("Error during replace"), wxOK | wxOK_DEFAULT | wxICON_WARNING); MessageDialog dlg(q, _L("File for the replace wasn't selected"), _L("Error during replace"), wxOK | wxOK_DEFAULT | wxICON_WARNING);
dlg.ShowModal(); dlg.ShowModal();
return; return;
} }
@ -3179,7 +3227,7 @@ void Plater::priv::replace_with_stl()
} }
if (new_model.objects.size() > 1 || new_model.objects[0]->volumes.size() > 1) { if (new_model.objects.size() > 1 || new_model.objects[0]->volumes.size() > 1) {
wxMessageDialog dlg(q, _L("Unable to replace with more than one volume"), _L("Error during replace"), wxOK | wxOK_DEFAULT | wxICON_WARNING); MessageDialog dlg(q, _L("Unable to replace with more than one volume"), _L("Error during replace"), wxOK | wxOK_DEFAULT | wxICON_WARNING);
dlg.ShowModal(); dlg.ShowModal();
return; return;
} }
@ -3318,7 +3366,8 @@ void Plater::priv::reload_from_disk()
} }
else { else {
wxString message = _L("It is not allowed to change the file to reload") + " (" + from_u8(search.filename().string()) + ").\n" + _L("Do you want to retry") + " ?"; wxString message = _L("It is not allowed to change the file to reload") + " (" + from_u8(search.filename().string()) + ").\n" + _L("Do you want to retry") + " ?";
wxMessageDialog dlg(q, message, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION); //wxMessageDialog dlg(q, message, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION);
MessageDialog dlg(q, message, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION);
if (dlg.ShowModal() != wxID_YES) if (dlg.ShowModal() != wxID_YES)
return; return;
} }
@ -3432,7 +3481,8 @@ void Plater::priv::reload_from_disk()
for (const wxString& s : fail_list) { for (const wxString& s : fail_list) {
message += s + "\n"; message += s + "\n";
} }
wxMessageDialog dlg(q, message, _L("Error during reload"), wxOK | wxOK_DEFAULT | wxICON_WARNING); //wxMessageDialog dlg(q, message, _L("Error during reload"), wxOK | wxOK_DEFAULT | wxICON_WARNING);
MessageDialog dlg(q, message, _L("Error during reload"), wxOK | wxOK_DEFAULT | wxICON_WARNING);
dlg.ShowModal(); dlg.ShowModal();
} }
@ -3808,7 +3858,8 @@ bool Plater::priv::warnings_dialog()
text += it.first.message; text += it.first.message;
} }
//text += "\n\nDo you still wish to export?"; //text += "\n\nDo you still wish to export?";
wxMessageDialog msg_wingow(this->q, from_u8(text), wxString(SLIC3R_APP_NAME " ") + _L("generated warnings"), wxOK); //wxMessageDialog msg_wingow(this->q, from_u8(text), wxString(SLIC3R_APP_NAME " ") + _L("generated warnings"), wxOK);
MessageDialog msg_wingow(this->q, from_u8(text), wxString(SLIC3R_APP_NAME " ") + _L("generated warnings"), wxOK);
const auto res = msg_wingow.ShowModal(); const auto res = msg_wingow.ShowModal();
return res == wxID_OK; return res == wxID_OK;
@ -4841,7 +4892,8 @@ void Plater::load_gcode(const wxString& filename)
p->preview->get_canvas3d()->zoom_to_gcode(); p->preview->get_canvas3d()->zoom_to_gcode();
if (p->preview->get_canvas3d()->get_gcode_layers_zs().empty()) { if (p->preview->get_canvas3d()->get_gcode_layers_zs().empty()) {
wxMessageDialog(this, _L("The selected file") + ":\n" + filename + "\n" + _L("does not contain valid gcode."), //wxMessageDialog(this, _L("The selected file") + ":\n" + filename + "\n" + _L("does not contain valid gcode."),
MessageDialog(this, _L("The selected file") + ":\n" + filename + "\n" + _L("does not contain valid gcode."),
wxString(GCODEVIEWER_APP_NAME) + " - " + _L("Error while loading .gcode file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); wxString(GCODEVIEWER_APP_NAME) + " - " + _L("Error while loading .gcode file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal();
set_project_filename(wxEmptyString); set_project_filename(wxEmptyString);
} }
@ -4953,7 +5005,8 @@ bool Plater::load_files(const wxArrayString& filenames)
} }
if (paths.size() > 1) { if (paths.size() > 1) {
wxMessageDialog(static_cast<wxWindow*>(this), _L("You can open only one .gcode file at a time."), //wxMessageDialog(static_cast<wxWindow*>(this), _L("You can open only one .gcode file at a time."),
MessageDialog(static_cast<wxWindow*>(this), _L("You can open only one .gcode file at a time."),
wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal();
return false; return false;
} }
@ -5083,7 +5136,8 @@ void Plater::reset() { p->reset(); }
void Plater::reset_with_confirm() void Plater::reset_with_confirm()
{ {
if (p->model.objects.empty() || if (p->model.objects.empty() ||
wxMessageDialog(static_cast<wxWindow*>(this), _L("All objects will be removed, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Delete all"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) //wxMessageDialog(static_cast<wxWindow*>(this), _L("All objects will be removed, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Delete all"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES)
MessageDialog(static_cast<wxWindow*>(this), _L("All objects will be removed, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Delete all"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES)
reset(); reset();
} }
@ -5156,6 +5210,26 @@ void Plater::decrease_instances(size_t num)
this->p->schedule_background_process(); this->p->schedule_background_process();
} }
static long GetNumberFromUser( const wxString& msg,
const wxString& prompt,
const wxString& title,
long value,
long min,
long max,
wxWindow* parent)
{
#ifdef _WIN32
wxNumberEntryDialog dialog(parent, msg, prompt, title, value, min, max, wxDefaultPosition);
wxGetApp().UpdateDlgDarkUI(&dialog);
if (dialog.ShowModal() == wxID_OK)
return dialog.GetValue();
return -1;
#else
return wxGetNumberFromUser(msg, prompt, title, value, min, max, parent);
#endif
}
void Plater::set_number_of_copies(/*size_t num*/) void Plater::set_number_of_copies(/*size_t num*/)
{ {
int obj_idx = p->get_selected_object_idx(); int obj_idx = p->get_selected_object_idx();
@ -5164,7 +5238,7 @@ void Plater::set_number_of_copies(/*size_t num*/)
ModelObject* model_object = p->model.objects[obj_idx]; ModelObject* model_object = p->model.objects[obj_idx];
const int num = wxGetNumberFromUser( " ", _L("Enter the number of copies:"), const int num = GetNumberFromUser( " ", _L("Enter the number of copies:"),
_L("Copies of the selected object"), model_object->instances.size(), 0, 1000, this ); _L("Copies of the selected object"), model_object->instances.size(), 0, 1000, this );
if (num < 0) if (num < 0)
return; return;
@ -6292,8 +6366,7 @@ void Plater::sys_color_changed()
p->preview->sys_color_changed(); p->preview->sys_color_changed();
p->sidebar->sys_color_changed(); p->sidebar->sys_color_changed();
// msw_rescale_menu updates just icons, so use it p->menus.sys_color_changed();
p->menus.msw_rescale();
Layout(); Layout();
GetParent()->Layout(); GetParent()->Layout();

View File

@ -2,9 +2,11 @@
#include "OptionsGroup.hpp" #include "OptionsGroup.hpp"
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include "Plater.hpp" #include "Plater.hpp"
#include "MsgDialog.hpp"
#include "I18N.hpp" #include "I18N.hpp"
#include "libslic3r/AppConfig.hpp" #include "libslic3r/AppConfig.hpp"
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/listbook.h>
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -19,7 +21,7 @@ PreferencesDialog::PreferencesDialog(wxWindow* parent) :
build(); build();
} }
static std::shared_ptr<ConfigOptionsGroup>create_options_tab(const wxString& title, wxNotebook* tabs) static std::shared_ptr<ConfigOptionsGroup>create_options_tab(const wxString& title, wxBookCtrlBase* tabs)
{ {
wxPanel* tab = new wxPanel(tabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); wxPanel* tab = new wxPanel(tabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
tabs->AddPage(tab, title); tabs->AddPage(tab, title);
@ -44,15 +46,30 @@ static void activate_options_tab(std::shared_ptr<ConfigOptionsGroup> optgroup)
void PreferencesDialog::build() 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(); const wxFont& font = wxGetApp().normal_font();
SetFont(font); SetFont(font);
auto app_config = get_app_config(); auto app_config = get_app_config();
wxNotebook* tabs = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME); #ifdef _MSW_DARK_MODE
#ifdef __WXMSW__ wxBookCtrlBase* tabs;
tabs->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); if (wxGetApp().dark_mode()) {
tabs = new wxListbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME | wxNO_BORDER);
wxGetApp().UpdateDarkUI(tabs);
wxGetApp().UpdateDarkUI(dynamic_cast<wxListbook*>(tabs)->GetListView());
}
else {
tabs = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME | wxNB_DEFAULT);
tabs->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
}
#else
wxNotebook* tabs = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL |wxNB_NOPAGETHEME | wxNB_DEFAULT );
tabs->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif #endif
// Add "General" tab // Add "General" tab
@ -320,6 +337,24 @@ void PreferencesDialog::build()
option = Option(def, "order_volumes"); option = Option(def, "order_volumes");
m_optgroup_gui->append_single_option_line(option); m_optgroup_gui->append_single_option_line(option);
#ifdef _MSW_DARK_MODE
def.label = L("Use Dark color mode (experimental)");
def.type = coBool;
def.tooltip = L("If enabled, UI will use Dark mode colors. "
"If disabled, old UI will be used.");
def.set_default_value(new ConfigOptionBool{ app_config->get("dark_color_mode") == "1" });
option = Option(def, "dark_color_mode");
m_optgroup_gui->append_single_option_line(option);
#endif
def.label = L("Set settings tabs as menu items (experimental)");
def.type = coBool;
def.tooltip = L("If enabled, Settings Tabs will be placed as menu items. "
"If disabled, old UI will be used.");
def.set_default_value(new ConfigOptionBool{ app_config->get("tabs_as_menu") == "1" });
option = Option(def, "tabs_as_menu");
m_optgroup_gui->append_single_option_line(option);
def.label = L("Use custom size for toolbar icons"); def.label = L("Use custom size for toolbar icons");
def.type = coBool; def.type = coBool;
def.tooltip = L("If enabled, you can change size of toolbar icons manually."); def.tooltip = L("If enabled, you can change size of toolbar icons manually.");
@ -363,6 +398,10 @@ void PreferencesDialog::build()
auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL); auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this)); wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); }); btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); });
wxGetApp().UpdateDarkUI(btn);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxTOP, 10); sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxTOP, 10);
SetSizer(sizer); SetSizer(sizer);
@ -372,8 +411,43 @@ void PreferencesDialog::build()
void PreferencesDialog::accept() void PreferencesDialog::accept()
{ {
if (m_values.find("no_defaults") != m_values.end()) // if (m_values.find("no_defaults") != m_values.end()
warning_catcher(this, wxString::Format(_L("You need to restart %s to make the changes effective."), SLIC3R_APP_NAME)); // warning_catcher(this, wxString::Format(_L("You need to restart %s to make the changes effective."), SLIC3R_APP_NAME));
std::vector<std::string> options_to_recreate_GUI = { "no_defaults", "tabs_as_menu"
#ifdef _MSW_DARK_MODE
,"dark_color_mode"
#endif
};
for (const std::string& option : options_to_recreate_GUI) {
if (m_values.find(option) != m_values.end()) {
wxString title = wxGetApp().is_editor() ? wxString(SLIC3R_APP_NAME) : wxString(GCODEVIEWER_APP_NAME);
title += " - " + _L("Changes for the critical options");
MessageDialog dialog(nullptr,
_L("Changing fo some options will trigger application restart.\n"
"You will lose content of the plater.") + "\n\n" +
_L("Do you want to proceed?"),
title,
wxICON_QUESTION | wxYES | wxNO);
if (dialog.ShowModal() == wxID_YES) {
m_recreate_GUI = true;
#ifdef _MSW_DARK_MODE
m_color_mode_changed = m_values.find("dark_color_mode") != m_values.end();
#endif
}
else {
for (const std::string& option : options_to_recreate_GUI)
m_values.erase(option);
}
break;
}
}
if (m_values.empty()) {
EndModal(wxID_CANCEL);
return;
}
auto app_config = get_app_config(); auto app_config = get_app_config();
@ -405,6 +479,11 @@ void PreferencesDialog::accept()
m_values.erase(it); // we shouldn't change value, if some of those parameters was selected, and then deselected m_values.erase(it); // we shouldn't change value, if some of those parameters was selected, and then deselected
} }
#if 0 //#ifdef _WIN32 // #ysDarkMSW - Allow it when we deside to support the sustem colors for application
if (m_values.find("always_dark_color_mode") != m_values.end())
wxGetApp().force_sys_colors_update();
#endif
for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it) for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it)
app_config->set(it->first, it->second); app_config->set(it->first, it->second);
@ -453,6 +532,7 @@ void PreferencesDialog::create_icon_size_slider()
m_icon_size_sizer = new wxBoxSizer(wxHORIZONTAL); m_icon_size_sizer = new wxBoxSizer(wxHORIZONTAL);
wxWindow* parent = m_optgroup_gui->parent(); wxWindow* parent = m_optgroup_gui->parent();
wxGetApp().UpdateDarkUI(parent);
if (isOSX) if (isOSX)
// For correct rendering of the slider and value label under OSX // For correct rendering of the slider and value label under OSX
@ -505,31 +585,59 @@ void PreferencesDialog::create_icon_size_slider()
void PreferencesDialog::create_settings_mode_widget() void PreferencesDialog::create_settings_mode_widget()
{ {
wxString choices[] = { _L("Old regular layout with the tab bar"), bool dark_mode = wxGetApp().dark_mode();
_L("New layout, access via settings button in the top menu"), std::vector<wxString> choices = { _L("Old regular layout with the tab bar"),
_L("Settings in non-modal window") }; _L("New layout, access via settings button in the top menu"),
_L("Settings in non-modal window") };
auto app_config = get_app_config(); auto app_config = get_app_config();
int selection = app_config->get("old_settings_layout_mode") == "1" ? 0 : int selection = app_config->get("old_settings_layout_mode") == "1" ? 0 :
app_config->get("new_settings_layout_mode") == "1" ? 1 : app_config->get("new_settings_layout_mode") == "1" ? 1 :
app_config->get("dlg_settings_layout_mode") == "1" ? 2 : 0; app_config->get("dlg_settings_layout_mode") == "1" ? 2 : 0;
#ifdef _MSW_DARK_MODE
if (dark_mode) {
choices = { _L("Old regular layout with the tab bar"),
_L("Settings in non-modal window") };
selection = app_config->get("dlg_settings_layout_mode") == "1" ? 1 : 0;
}
#endif
wxWindow* parent = m_optgroup_gui->parent(); wxWindow* parent = m_optgroup_gui->parent();
wxGetApp().UpdateDarkUI(parent);
m_layout_mode_box = new wxRadioBox(parent, wxID_ANY, _L("Layout Options"), wxDefaultPosition, wxDefaultSize, wxStaticBox* stb = new wxStaticBox(parent, wxID_ANY, _L("Layout Options"));
WXSIZEOF(choices), choices, 3, wxRA_SPECIFY_ROWS); wxGetApp().UpdateDarkUI(stb);
m_layout_mode_box->SetFont(wxGetApp().normal_font()); if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT);
m_layout_mode_box->SetSelection(selection); stb->SetFont(wxGetApp().normal_font());
m_layout_mode_box->Bind(wxEVT_RADIOBOX, [this](wxCommandEvent& e) { wxSizer* stb_sizer = new wxStaticBoxSizer(stb, wxVERTICAL);
int selection = e.GetSelection();
m_values["old_settings_layout_mode"] = boost::any_cast<bool>(selection == 0) ? "1" : "0"; int id = 0;
m_values["new_settings_layout_mode"] = boost::any_cast<bool>(selection == 1) ? "1" : "0"; for (const wxString& label : choices) {
m_values["dlg_settings_layout_mode"] = boost::any_cast<bool>(selection == 2) ? "1" : "0"; wxRadioButton* btn = new wxRadioButton(parent, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, id==0 ? wxRB_GROUP : 0);
}); stb_sizer->Add(btn);
btn->SetValue(id == selection);
int dlg_id = 2;
#ifdef _MSW_DARK_MODE
if (dark_mode)
dlg_id = 1;
#endif
btn->Bind(wxEVT_RADIOBUTTON, [this, id, dlg_id, dark_mode](wxCommandEvent& ) {
m_values["old_settings_layout_mode"] = (id == 0) ? "1" : "0";
#ifdef _MSW_DARK_MODE
if (!dark_mode)
m_values["new_settings_layout_mode"] = (id == 1) ? "1" : "0";
#endif
m_values["dlg_settings_layout_mode"] = (id == dlg_id) ? "1" : "0";
});
id++;
}
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_layout_mode_box, 1, wxALIGN_CENTER_VERTICAL); sizer->Add(/*m_layout_mode_box*/stb_sizer, 1, wxALIGN_CENTER_VERTICAL);
m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit()); m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND | wxTOP, em_unit());
} }
@ -538,6 +646,7 @@ void PreferencesDialog::create_settings_text_color_widget()
wxWindow* parent = m_optgroup_gui->parent(); wxWindow* parent = m_optgroup_gui->parent();
wxStaticBox* stb = new wxStaticBox(parent, wxID_ANY, _L("Text color Settings")); wxStaticBox* stb = new wxStaticBox(parent, wxID_ANY, _L("Text color Settings"));
wxGetApp().UpdateDarkUI(stb);
if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT); if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT);
wxSizer* sizer = new wxStaticBoxSizer(stb, wxVERTICAL); wxSizer* sizer = new wxStaticBoxSizer(stb, wxVERTICAL);
@ -547,6 +656,7 @@ void PreferencesDialog::create_settings_text_color_widget()
auto sys_label = new wxStaticText(parent, wxID_ANY, _L("Value is the same as the system value")); auto sys_label = new wxStaticText(parent, wxID_ANY, _L("Value is the same as the system value"));
sys_label->SetForegroundColour(wxGetApp().get_label_clr_sys()); sys_label->SetForegroundColour(wxGetApp().get_label_clr_sys());
m_sys_colour = new wxColourPickerCtrl(parent, wxID_ANY, wxGetApp().get_label_clr_sys()); m_sys_colour = new wxColourPickerCtrl(parent, wxID_ANY, wxGetApp().get_label_clr_sys());
wxGetApp().UpdateDarkUI(m_sys_colour->GetPickerCtrl(), true);
m_sys_colour->Bind(wxEVT_COLOURPICKER_CHANGED, [this, sys_label](wxCommandEvent&) { m_sys_colour->Bind(wxEVT_COLOURPICKER_CHANGED, [this, sys_label](wxCommandEvent&) {
sys_label->SetForegroundColour(m_sys_colour->GetColour()); sys_label->SetForegroundColour(m_sys_colour->GetColour());
sys_label->Refresh(); sys_label->Refresh();
@ -558,6 +668,7 @@ void PreferencesDialog::create_settings_text_color_widget()
auto mod_label = new wxStaticText(parent, wxID_ANY, _L("Value was changed and is not equal to the system value or the last saved preset")); auto mod_label = new wxStaticText(parent, wxID_ANY, _L("Value was changed and is not equal to the system value or the last saved preset"));
mod_label->SetForegroundColour(wxGetApp().get_label_clr_modified()); mod_label->SetForegroundColour(wxGetApp().get_label_clr_modified());
m_mod_colour = new wxColourPickerCtrl(parent, wxID_ANY, wxGetApp().get_label_clr_modified()); m_mod_colour = new wxColourPickerCtrl(parent, wxID_ANY, wxGetApp().get_label_clr_modified());
wxGetApp().UpdateDarkUI(m_mod_colour->GetPickerCtrl(), true);
m_mod_colour->Bind(wxEVT_COLOURPICKER_CHANGED, [this, mod_label](wxCommandEvent&) { m_mod_colour->Bind(wxEVT_COLOURPICKER_CHANGED, [this, mod_label](wxCommandEvent&) {
mod_label->SetForegroundColour(m_mod_colour->GetColour()); mod_label->SetForegroundColour(m_mod_colour->GetColour());
mod_label->Refresh(); mod_label->Refresh();

View File

@ -34,7 +34,10 @@ class PreferencesDialog : public DPIDialog
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER #if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
bool m_seq_top_gcode_indices_changed{ false }; bool m_seq_top_gcode_indices_changed{ false };
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
bool m_recreate_GUI{false};
#ifdef _MSW_DARK_MODE
bool m_color_mode_changed {false};
#endif
public: public:
explicit PreferencesDialog(wxWindow* parent); explicit PreferencesDialog(wxWindow* parent);
~PreferencesDialog() = default; ~PreferencesDialog() = default;
@ -44,7 +47,10 @@ public:
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER #if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
bool seq_seq_top_gcode_indices_changed() const { return m_seq_top_gcode_indices_changed; } bool seq_seq_top_gcode_indices_changed() const { return m_seq_top_gcode_indices_changed; }
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
bool recreate_GUI() const { return m_recreate_GUI; }
#ifdef _MSW_DARK_MODE
bool color_mode_changed() const { return m_color_mode_changed; }
#endif
void build(); void build();
void accept(); void accept();

View File

@ -13,6 +13,13 @@
#include <wx/colordlg.h> #include <wx/colordlg.h>
#include <wx/wupdlock.h> #include <wx/wupdlock.h>
#include <wx/menu.h> #include <wx/menu.h>
#include <wx/odcombo.h>
#include <wx/listbook.h>
#ifdef _WIN32
#include <wx/msw/dcclient.h>
#include <wx/msw/private.h>
#endif
#include "libslic3r/libslic3r.h" #include "libslic3r/libslic3r.h"
#include "libslic3r/PrintConfig.hpp" #include "libslic3r/PrintConfig.hpp"
@ -31,6 +38,7 @@
#include "BitmapCache.hpp" #include "BitmapCache.hpp"
#include "PhysicalPrinterDialog.hpp" #include "PhysicalPrinterDialog.hpp"
#include "SavePresetDialog.hpp" #include "SavePresetDialog.hpp"
#include "MsgDialog.hpp"
// A workaround for a set of issues related to text fitting into gtk widgets: // A workaround for a set of issues related to text fitting into gtk widgets:
// See e.g.: https://github.com/prusa3d/PrusaSlicer/issues/4584 // See e.g.: https://github.com/prusa3d/PrusaSlicer/issues/4584
@ -63,19 +71,12 @@ namespace GUI {
**/ **/
PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size, PresetBundle* preset_bundle/* = nullptr*/) : PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size, PresetBundle* preset_bundle/* = nullptr*/) :
wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, size, 0, nullptr, wxCB_READONLY), BitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, size, 0, nullptr, wxCB_READONLY),
m_type(preset_type), m_type(preset_type),
m_last_selected(wxNOT_FOUND), m_last_selected(wxNOT_FOUND),
m_em_unit(em_unit(this)), m_em_unit(em_unit(this)),
m_preset_bundle(preset_bundle ? preset_bundle : wxGetApp().preset_bundle) m_preset_bundle(preset_bundle ? preset_bundle : wxGetApp().preset_bundle)
{ {
SetFont(wxGetApp().normal_font());
#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);
#endif /* _WIN32 */
switch (m_type) switch (m_type)
{ {
case Preset::TYPE_PRINT: { case Preset::TYPE_PRINT: {
@ -335,7 +336,8 @@ bool PresetComboBox::del_physical_printer(const wxString& note_string/* = wxEmpt
msg += note_string + "\n"; msg += note_string + "\n";
msg += format_wxstr(_L("Are you sure you want to delete \"%1%\" printer?"), printer_name); msg += format_wxstr(_L("Are you sure you want to delete \"%1%\" printer?"), printer_name);
if (wxMessageDialog(this, msg, _L("Delete Physical Printer"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal() != wxID_YES) //if (wxMessageDialog(this, msg, _L("Delete Physical Printer"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal() != wxID_YES)
if (MessageDialog(this, msg, _L("Delete Physical Printer"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal() != wxID_YES)
return false; return false;
m_preset_bundle->physical_printers.delete_selected_printer(); m_preset_bundle->physical_printers.delete_selected_printer();
@ -383,6 +385,12 @@ void PresetComboBox::msw_rescale()
update(); update();
} }
void PresetComboBox::sys_color_changed()
{
wxGetApp().UpdateDarkUI(this);
msw_rescale();
}
void PresetComboBox::fill_width_height() void PresetComboBox::fill_width_height()
{ {
// To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so // To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so
@ -532,72 +540,6 @@ bool PresetComboBox::selection_is_changed_according_to_physical_printers()
return true; return true;
} }
#ifdef __APPLE__
bool PresetComboBox::OnAddBitmap(const wxBitmap& bitmap)
{
if (bitmap.IsOk())
{
// we should use scaled! size values of bitmap
int width = (int)bitmap.GetScaledWidth();
int height = (int)bitmap.GetScaledHeight();
if (m_usedImgSize.x < 0)
{
// If size not yet determined, get it from this image.
m_usedImgSize.x = width;
m_usedImgSize.y = height;
// Adjust control size to vertically fit the bitmap
wxWindow* ctrl = GetControl();
ctrl->InvalidateBestSize();
wxSize newSz = ctrl->GetBestSize();
wxSize sz = ctrl->GetSize();
if (newSz.y > sz.y)
ctrl->SetSize(sz.x, newSz.y);
else
DetermineIndent();
}
wxCHECK_MSG(width == m_usedImgSize.x && height == m_usedImgSize.y,
false,
"you can only add images of same size");
return true;
}
return false;
}
void PresetComboBox::OnDrawItem(wxDC& dc,
const wxRect& rect,
int item,
int flags) const
{
const wxBitmap& bmp = *(static_cast<wxBitmap*>(m_bitmaps[item]));
if (bmp.IsOk())
{
// we should use scaled! size values of bitmap
wxCoord w = bmp.GetScaledWidth();
wxCoord h = bmp.GetScaledHeight();
const int imgSpacingLeft = 4;
// Draw the image centered
dc.DrawBitmap(bmp,
rect.x + (m_usedImgSize.x - w) / 2 + imgSpacingLeft,
rect.y + (rect.height - h) / 2,
true);
}
wxString text = GetString(item);
if (!text.empty())
dc.DrawText(text,
rect.x + m_imgAreaWidth + 1,
rect.y + (rect.height - dc.GetCharHeight()) / 2);
}
#endif
// --------------------------------- // ---------------------------------
// *** PlaterPresetComboBox *** // *** PlaterPresetComboBox ***
// --------------------------------- // ---------------------------------

View File

@ -1,11 +1,12 @@
#ifndef slic3r_PresetComboBoxes_hpp_ #ifndef slic3r_PresetComboBoxes_hpp_
#define slic3r_PresetComboBoxes_hpp_ #define slic3r_PresetComboBoxes_hpp_
#include <wx/bmpcbox.h> //#include <wx/bmpcbox.h>
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
#include "libslic3r/Preset.hpp" #include "libslic3r/Preset.hpp"
#include "wxExtensions.hpp" #include "wxExtensions.hpp"
#include "BitmapComboBox.hpp"
#include "GUI_Utils.hpp" #include "GUI_Utils.hpp"
class wxString; class wxString;
@ -28,7 +29,7 @@ class BitmapCache;
// --------------------------------- // ---------------------------------
// BitmapComboBox used to presets list on Sidebar and Tabs // BitmapComboBox used to presets list on Sidebar and Tabs
class PresetComboBox : public wxBitmapComboBox class PresetComboBox : public BitmapComboBox
{ {
bool m_show_all { false }; bool m_show_all { false };
public: public:
@ -71,6 +72,7 @@ public:
void show_all(bool show_all); void show_all(bool show_all);
virtual void update(); virtual void update();
virtual void msw_rescale(); virtual void msw_rescale();
virtual void sys_color_changed();
virtual void OnSelect(wxCommandEvent& evt); virtual void OnSelect(wxCommandEvent& evt);
protected: protected:
@ -126,21 +128,6 @@ protected:
wxBitmap* get_bmp( std::string bitmap_key, const std::string& main_icon_name, const std::string& next_icon_name, wxBitmap* get_bmp( std::string bitmap_key, const std::string& main_icon_name, const std::string& next_icon_name,
bool is_enabled = true, bool is_compatible = true, bool is_system = false); bool is_enabled = true, bool is_compatible = true, bool is_system = false);
#ifdef __APPLE__
/* For PresetComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina
* (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean
* "please scale this to such and such" but rather
* "the wxImage is already sized for backing scale such and such". )
* Unfortunately, the constructor changes the size of wxBitmap too.
* Thus We need to use unscaled size value for bitmaps that we use
* to avoid scaled size of control items.
* For this purpose control drawing methods and
* control size calculation methods (virtual) are overridden.
**/
bool OnAddBitmap(const wxBitmap& bitmap) override;
void OnDrawItem(wxDC& dc, const wxRect& rect, int item, int flags) const override;
#endif
private: private:
void fill_width_height(); void fill_width_height();
}; };

View File

@ -92,7 +92,8 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
// .gcode suffix control // .gcode suffix control
if (!path.Lower().EndsWith(suffix.Lower())) if (!path.Lower().EndsWith(suffix.Lower()))
{ {
wxMessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO); //wxMessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
MessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
if (msg_wingow.ShowModal() == wxID_NO) if (msg_wingow.ShowModal() == wxID_NO)
return; return;
} }
@ -238,6 +239,9 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent)
topsizer->Add(btnsizer, 0, wxEXPAND); topsizer->Add(btnsizer, 0, wxEXPAND);
SetSizer(topsizer); SetSizer(topsizer);
wxGetApp().UpdateDlgDarkUI(this);
wxGetApp().UpdateDVCDarkUI(job_list);
std::vector<int> size; std::vector<int> size;
SetSize(load_user_data(UDT_SIZE, size) ? wxSize(size[0] * em, size[1] * em) : wxSize(HEIGHT * em, WIDTH * em)); SetSize(load_user_data(UDT_SIZE, size) ? wxSize(size[0] * em, size[1] * em) : wxSize(HEIGHT * em, WIDTH * em));

View File

@ -28,6 +28,7 @@ ProgressStatusBar::ProgressStatusBar(wxWindow *parent, int id)
wxDefaultSize)} wxDefaultSize)}
, m_timer{new wxTimer(self)} , m_timer{new wxTimer(self)}
{ {
update_dark_ui();
m_prog->Hide(); m_prog->Hide();
m_cancelbutton->Hide(); m_cancelbutton->Hide();
@ -68,6 +69,13 @@ ProgressStatusBar::~ProgressStatusBar() {
if(m_timer && m_timer->IsRunning()) m_timer->Stop(); if(m_timer && m_timer->IsRunning()) m_timer->Stop();
} }
void ProgressStatusBar::update_dark_ui()
{
GUI::wxGetApp().UpdateDarkUI(self);
GUI::wxGetApp().UpdateDarkUI(m_prog);
GUI::wxGetApp().UpdateDarkUI(m_cancelbutton);
}
int ProgressStatusBar::get_progress() const int ProgressStatusBar::get_progress() const
{ {
return m_prog ? m_prog->GetValue() : 0; return m_prog ? m_prog->GetValue() : 0;

View File

@ -61,6 +61,8 @@ public:
void show_cancel_button(); void show_cancel_button();
void hide_cancel_button(); void hide_cancel_button();
void update_dark_ui();
private: private:
bool m_busy = false; bool m_busy = false;
CancelFn m_cancel_cb; CancelFn m_cancel_cb;

View File

@ -3,6 +3,7 @@
#include "RammingChart.hpp" #include "RammingChart.hpp"
#include "GUI.hpp" #include "GUI.hpp"
#include "GUI_App.hpp"
#include "I18N.hpp" #include "I18N.hpp"
wxDEFINE_EVENT(EVT_WIPE_TOWER_CHART_CHANGED, wxCommandEvent); wxDEFINE_EVENT(EVT_WIPE_TOWER_CHART_CHANGED, wxCommandEvent);
@ -15,8 +16,13 @@ void Chart::draw() {
dc.SetPen(GetBackgroundColour()); dc.SetPen(GetBackgroundColour());
dc.DrawRectangle(GetClientRect()); // otherwise the background would end up black on windows dc.DrawRectangle(GetClientRect()); // otherwise the background would end up black on windows
#ifdef _WIN32
dc.SetPen(wxPen(GetForegroundColour()));
dc.SetBrush(wxBrush(Slic3r::GUI::wxGetApp().get_highlight_default_clr()));
#else
dc.SetPen(*wxBLACK_PEN); dc.SetPen(*wxBLACK_PEN);
dc.SetBrush(*wxWHITE_BRUSH); dc.SetBrush(*wxWHITE_BRUSH);
#endif
dc.DrawRectangle(m_rect); dc.DrawRectangle(m_rect);
if (visible_area.m_width < 0.499) { if (visible_area.m_width < 0.499) {
@ -31,7 +37,11 @@ void Chart::draw() {
dc.SetPen( wxPen( wxColor(std::min(255,color),255-std::max(color-255,0),0), 1 ) ); dc.SetPen( wxPen( wxColor(std::min(255,color),255-std::max(color-255,0),0), 1 ) );
dc.DrawLine(m_rect.GetLeft()+1+i,(m_line_to_draw)[i],m_rect.GetLeft()+1+i,m_rect.GetBottom()); dc.DrawLine(m_rect.GetLeft()+1+i,(m_line_to_draw)[i],m_rect.GetLeft()+1+i,m_rect.GetBottom());
} }
#ifdef _WIN32
dc.SetPen(wxPen(GetForegroundColour()));
#else
dc.SetPen( wxPen( wxColor(0,0,0), 1 ) ); dc.SetPen( wxPen( wxColor(0,0,0), 1 ) );
#endif
for (unsigned int i=0;i<m_line_to_draw.size()-2;++i) { for (unsigned int i=0;i<m_line_to_draw.size()-2;++i) {
if (splines) if (splines)
dc.DrawLine(m_rect.GetLeft()+i,(m_line_to_draw)[i],m_rect.GetLeft()+i+1,(m_line_to_draw)[i+1]); dc.DrawLine(m_rect.GetLeft()+i,(m_line_to_draw)[i],m_rect.GetLeft()+i+1,(m_line_to_draw)[i+1]);
@ -44,7 +54,11 @@ void Chart::draw() {
// draw draggable buttons // draw draggable buttons
dc.SetBrush(*wxBLUE_BRUSH); dc.SetBrush(*wxBLUE_BRUSH);
dc.SetPen( wxPen( wxColor(0,0,0), 1 ) ); #ifdef _WIN32
dc.SetPen(wxPen(GetForegroundColour()));
#else
dc.SetPen( wxPen( wxColor(0,0,0), 1 ) );
#endif
for (auto& button : m_buttons) for (auto& button : m_buttons)
//dc.DrawRectangle(math_to_screen(button.get_pos())-wxPoint(side/2.,side/2.), wxSize(side,side)); //dc.DrawRectangle(math_to_screen(button.get_pos())-wxPoint(side/2.,side/2.), wxSize(side,side));
dc.DrawCircle(math_to_screen(button.get_pos()),side/2.); dc.DrawCircle(math_to_screen(button.get_pos()),side/2.);

View File

@ -409,16 +409,21 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
searcher(searcher) searcher(searcher)
{ {
SetFont(GUI::wxGetApp().normal_font()); SetFont(GUI::wxGetApp().normal_font());
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); GUI::wxGetApp().UpdateDarkUI(this);
SetBackgroundColour(bgr_clr);
default_string = _L("Enter a search term"); default_string = _L("Enter a search term");
int border = 10; int border = 10;
int em = em_unit(); int em = em_unit();
search_line = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); search_line = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
GUI::wxGetApp().UpdateDarkUI(search_line);
search_list = new wxDataViewCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(em * 40, em * 30), wxDV_NO_HEADER | wxDV_SINGLE | wxBORDER_SIMPLE); search_list = new wxDataViewCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(em * 40, em * 30), wxDV_NO_HEADER | wxDV_SINGLE
#ifdef _WIN32
| wxBORDER_SIMPLE
#endif
);
GUI::wxGetApp().UpdateDarkUI(search_list);
search_list_model = new SearchListModel(this); search_list_model = new SearchListModel(this);
search_list->AssociateModel(search_list_model); search_list->AssociateModel(search_list_model);
@ -442,6 +447,7 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
check_english = new wxCheckBox(this, wxID_ANY, _L("Search in English")); check_english = new wxCheckBox(this, wxID_ANY, _L("Search in English"));
wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL); wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL);
GUI::wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
check_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Use for search") + ":"), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border); check_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Use for search") + ":"), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
check_sizer->Add(check_category, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border); check_sizer->Add(check_category, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
@ -656,6 +662,13 @@ void SearchDialog::on_dpi_changed(const wxRect& suggested_rect)
void SearchDialog::on_sys_color_changed() void SearchDialog::on_sys_color_changed()
{ {
#ifdef _WIN32
GUI::wxGetApp().UpdateAllStaticTextDarkUI(this);
GUI::wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)), true);
for (wxWindow* win : std::vector<wxWindow*> {search_line, search_list, check_category, check_english})
if (win) GUI::wxGetApp().UpdateDarkUI(win);
#endif
// msw_rescale updates just icons, so use it // msw_rescale updates just icons, so use it
search_list_model->msw_rescale(); search_list_model->msw_rescale();

View File

@ -82,7 +82,7 @@ std::string get_mem_info(bool format_as_html)
SysInfoDialog::SysInfoDialog() SysInfoDialog::SysInfoDialog()
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, (wxGetApp().is_editor() ? wxString(SLIC3R_APP_NAME) : wxString(GCODEVIEWER_APP_NAME)) + " - " + _L("System Information"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) : DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, (wxGetApp().is_editor() ? wxString(SLIC3R_APP_NAME) : wxString(GCODEVIEWER_APP_NAME)) + " - " + _L("System Information"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); wxColour bgr_clr = wxGetApp().get_window_default_clr();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
SetBackgroundColour(bgr_clr); SetBackgroundColour(bgr_clr);
SetFont(wxGetApp().normal_font()); SetFont(wxGetApp().normal_font());
@ -112,7 +112,7 @@ SysInfoDialog::SysInfoDialog()
// main_info_text // main_info_text
wxFont font = get_default_font(this); wxFont font = get_default_font(this);
const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); const auto text_clr = wxGetApp().get_label_clr_default();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
@ -170,6 +170,9 @@ SysInfoDialog::SysInfoDialog()
this->Bind(wxEVT_BUTTON, &SysInfoDialog::onCloseDialog, this, wxID_OK); this->Bind(wxEVT_BUTTON, &SysInfoDialog::onCloseDialog, this, wxID_OK);
main_sizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3); main_sizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_OK, this)), true);
wxGetApp().UpdateDarkUI(m_btn_copy_to_clipboard, true);
// this->Bind(wxEVT_LEFT_DOWN, &SysInfoDialog::onCloseDialog, this); // this->Bind(wxEVT_LEFT_DOWN, &SysInfoDialog::onCloseDialog, this);
// logo->Bind(wxEVT_LEFT_DOWN, &SysInfoDialog::onCloseDialog, this); // logo->Bind(wxEVT_LEFT_DOWN, &SysInfoDialog::onCloseDialog, this);

View File

@ -43,6 +43,7 @@
#include "PhysicalPrinterDialog.hpp" #include "PhysicalPrinterDialog.hpp"
#include "UnsavedChangesDialog.hpp" #include "UnsavedChangesDialog.hpp"
#include "SavePresetDialog.hpp" #include "SavePresetDialog.hpp"
#include "MsgDialog.hpp"
#ifdef WIN32 #ifdef WIN32
#include <commctrl.h> #include <commctrl.h>
@ -100,12 +101,14 @@ void Tab::Highlighter::blink()
invalidate(); invalidate();
} }
Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) : Tab::Tab(wxBookCtrlBase* parent, const wxString& title, Preset::Type type) :
m_parent(parent), m_title(title), m_type(type) m_parent(parent), m_title(title), m_type(type)
{ {
Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL/*, name*/); Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL/*, name*/);
this->SetFont(Slic3r::GUI::wxGetApp().normal_font()); this->SetFont(Slic3r::GUI::wxGetApp().normal_font());
wxGetApp().UpdateDarkUI(this);
m_compatible_printers.type = Preset::TYPE_PRINTER; m_compatible_printers.type = Preset::TYPE_PRINTER;
m_compatible_printers.key_list = "compatible_printers"; m_compatible_printers.key_list = "compatible_printers";
m_compatible_printers.key_condition = "compatible_printers_condition"; m_compatible_printers.key_condition = "compatible_printers_condition";
@ -253,7 +256,7 @@ void Tab::create_preset_tab()
m_default_text_clr = wxGetApp().get_label_clr_default(); m_default_text_clr = wxGetApp().get_label_clr_default();
// Sizer with buttons for mode changing // Sizer with buttons for mode changing
m_mode_sizer = new ModeSizer(panel); m_mode_sizer = new ModeSizer(panel, int (0.5*em_unit(this)));
const float scale_factor = /*wxGetApp().*/em_unit(this)*0.1;// GetContentScaleFactor(); const float scale_factor = /*wxGetApp().*/em_unit(this)*0.1;// GetContentScaleFactor();
m_hsizer = new wxBoxSizer(wxHORIZONTAL); m_hsizer = new wxBoxSizer(wxHORIZONTAL);
@ -305,6 +308,7 @@ void Tab::create_preset_tab()
m_treectrl->AssignImageList(m_icons); m_treectrl->AssignImageList(m_icons);
m_treectrl->AddRoot("root"); m_treectrl->AddRoot("root");
m_treectrl->SetIndent(0); m_treectrl->SetIndent(0);
wxGetApp().UpdateDarkUI(m_treectrl);
// Delay processing of the following handler until the message queue is flushed. // Delay processing of the following handler until the message queue is flushed.
// This helps to process all the cursor key events on Windows in the tree control, // This helps to process all the cursor key events on Windows in the tree control,
@ -483,11 +487,25 @@ void Tab::OnActivate()
// create controls on active page // create controls on active page
activate_selected_page([](){}); activate_selected_page([](){});
m_hsizer->Layout(); m_hsizer->Layout();
// Workaroud for Menu instead of NoteBook
#ifdef _MSW_DARK_MODE
if (wxGetApp().dark_mode()) {
wxSize sz = m_presets_choice->GetSize();
wxSize ok_sz = wxSize(35 * m_em_unit, m_presets_choice->GetBestSize().y+1);
if (sz != ok_sz) {
m_presets_choice->SetMinSize(ok_sz);
m_presets_choice->SetSize(ok_sz);
GetSizer()->GetItem(size_t(0))->GetSizer()->Layout();
}
}
#endif // _MSW_DARK_MODE
Refresh(); Refresh();
} }
void Tab::update_label_colours() void Tab::update_label_colours()
{ {
m_default_text_clr = wxGetApp().get_label_clr_default();
if (m_sys_label_clr == wxGetApp().get_label_clr_sys() && m_modified_label_clr == wxGetApp().get_label_clr_modified()) if (m_sys_label_clr == wxGetApp().get_label_clr_sys() && m_modified_label_clr == wxGetApp().get_label_clr_modified())
return; return;
m_sys_label_clr = wxGetApp().get_label_clr_sys(); m_sys_label_clr = wxGetApp().get_label_clr_sys();
@ -984,14 +1002,15 @@ void Tab::msw_rescale()
void Tab::sys_color_changed() void Tab::sys_color_changed()
{ {
update_tab_ui(); m_presets_choice->sys_color_changed();
m_presets_choice->msw_rescale();
// update buttons and cached bitmaps // update buttons and cached bitmaps
for (const auto btn : m_scaled_buttons) for (const auto btn : m_scaled_buttons)
btn->msw_rescale(); btn->msw_rescale();
for (const auto bmp : m_scaled_bitmaps) for (const auto bmp : m_scaled_bitmaps)
bmp->msw_rescale(); bmp->msw_rescale();
if (m_detach_preset_btn)
m_detach_preset_btn->msw_rescale();
// update icons for tree_ctrl // update icons for tree_ctrl
for (ScalableBitmap& bmp : m_scaled_icons_list) for (ScalableBitmap& bmp : m_scaled_icons_list)
@ -1002,15 +1021,20 @@ void Tab::sys_color_changed()
for (ScalableBitmap& bmp : m_scaled_icons_list) for (ScalableBitmap& bmp : m_scaled_icons_list)
m_icons->Add(bmp.bmp()); m_icons->Add(bmp.bmp());
m_treectrl->AssignImageList(m_icons); m_treectrl->AssignImageList(m_icons);
#ifdef __WXMSW__
m_treectrl->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
// Colors for ui "decoration" // Colors for ui "decoration"
update_label_colours(); update_label_colours();
#ifdef _WIN32
wxWindowUpdateLocker noUpdates(this);
m_mode_sizer->msw_rescale();
wxGetApp().UpdateDarkUI(this);
wxGetApp().UpdateDarkUI(m_treectrl);
#endif
update_changed_tree_ui();
// update options_groups // update options_groups
if (m_active_page) if (m_active_page)
m_active_page->msw_rescale(); m_active_page->sys_color_changed();
Layout(); Layout();
} }
@ -1271,7 +1295,8 @@ void Tab::build_preset_description_line(ConfigOptionsGroup* optgroup)
msg_text += "\n\n"; msg_text += "\n\n";
msg_text += _(L("This action is not revertible.\nDo you want to proceed?")); msg_text += _(L("This action is not revertible.\nDo you want to proceed?"));
wxMessageDialog dialog(parent, msg_text, _(L("Detach preset")), wxICON_WARNING | wxYES_NO | wxCANCEL); //wxMessageDialog dialog(parent, msg_text, _(L("Detach preset")), wxICON_WARNING | wxYES_NO | wxCANCEL);
MessageDialog dialog(parent, msg_text, _(L("Detach preset")), wxICON_WARNING | wxYES_NO | wxCANCEL);
if (dialog.ShowModal() == wxID_YES) if (dialog.ShowModal() == wxID_YES)
save_preset(m_presets->get_edited_preset().is_system ? std::string() : m_presets->get_edited_preset().name, true); save_preset(m_presets->get_edited_preset().is_system ? std::string() : m_presets->get_edited_preset().name, true);
}); });
@ -1740,7 +1765,8 @@ bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode)
reports += _L("contain reserved keywords.") + "\n"; reports += _L("contain reserved keywords.") + "\n";
reports += _L("Please remove them, as they may cause problems in g-code visualization and printing time estimation."); reports += _L("Please remove them, as they may cause problems in g-code visualization and printing time estimation.");
wxMessageDialog dialog(wxGetApp().mainframe, reports, _L("Found reserved keywords in") + " " + _(title), wxICON_WARNING | wxOK); //wxMessageDialog dialog(wxGetApp().mainframe, reports, _L("Found reserved keywords in") + " " + _(title), wxICON_WARNING | wxOK);
MessageDialog dialog(wxGetApp().mainframe, reports, _L("Found reserved keywords in") + " " + _(title), wxICON_WARNING | wxOK);
dialog.ShowModal(); dialog.ShowModal();
} }
return !invalid; return !invalid;
@ -1952,6 +1978,7 @@ void TabFilament::build()
create_line_with_widget(optgroup.get(), "filament_ramming_parameters", wxEmptyString, [this](wxWindow* parent) { create_line_with_widget(optgroup.get(), "filament_ramming_parameters", wxEmptyString, [this](wxWindow* parent) {
auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
wxGetApp().UpdateDarkUI(ramming_dialog_btn);
ramming_dialog_btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); ramming_dialog_btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
ramming_dialog_btn->SetSize(ramming_dialog_btn->GetBestSize()); ramming_dialog_btn->SetSize(ramming_dialog_btn->GetBestSize());
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
@ -2232,7 +2259,8 @@ void TabPrinter::build_fff()
const wxString msg_text = _(L("Single Extruder Multi Material is selected, \n" const wxString msg_text = _(L("Single Extruder Multi Material is selected, \n"
"and all extruders must have the same diameter.\n" "and all extruders must have the same diameter.\n"
"Do you want to change the diameter for all extruders to first extruder nozzle diameter value?")); "Do you want to change the diameter for all extruders to first extruder nozzle diameter value?"));
wxMessageDialog dialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO); //wxMessageDialog dialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
MessageDialog dialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
DynamicPrintConfig new_conf = *m_config; DynamicPrintConfig new_conf = *m_config;
if (dialog.ShowModal() == wxID_YES) { if (dialog.ShowModal() == wxID_YES) {
@ -2690,7 +2718,8 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
{ {
const wxString msg_text = _(L("This is a single extruder multimaterial printer, diameters of all extruders " const wxString msg_text = _(L("This is a single extruder multimaterial printer, diameters of all extruders "
"will be set to the new value. Do you want to proceed?")); "will be set to the new value. Do you want to proceed?"));
wxMessageDialog dialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO); //wxMessageDialog dialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
MessageDialog dialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
DynamicPrintConfig new_conf = *m_config; DynamicPrintConfig new_conf = *m_config;
if (dialog.ShowModal() == wxID_YES) { if (dialog.ShowModal() == wxID_YES) {
@ -2921,7 +2950,8 @@ void TabPrinter::toggle_options()
toggle_option("retract_before_wipe", wipe, i); toggle_option("retract_before_wipe", wipe, i);
if (use_firmware_retraction && wipe) { if (use_firmware_retraction && wipe) {
wxMessageDialog dialog(parent(), //wxMessageDialog dialog(parent(),
MessageDialog dialog(parent(),
_(L("The Wipe option is not available when using the Firmware Retraction mode.\n" _(L("The Wipe option is not available when using the Firmware Retraction mode.\n"
"\nShall I disable it in order to enable Firmware Retraction?")), "\nShall I disable it in order to enable Firmware Retraction?")),
_(L("Firmware Retraction")), wxICON_WARNING | wxYES | wxNO); _(L("Firmware Retraction")), wxICON_WARNING | wxYES | wxNO);
@ -3047,8 +3077,12 @@ void Tab::load_current_preset()
Page* tmp_page = m_active_page; Page* tmp_page = m_active_page;
m_active_page = nullptr; m_active_page = nullptr;
for (auto tab : wxGetApp().tabs_list) { for (auto tab : wxGetApp().tabs_list) {
if (tab->type() == Preset::TYPE_PRINTER) // Printer tab is shown every time if (tab->type() == Preset::TYPE_PRINTER) { // Printer tab is shown every time
int cur_selection = wxGetApp().tab_panel()->GetSelection();
if (cur_selection != 0)
wxGetApp().tab_panel()->SetSelection(wxGetApp().tab_panel()->GetPageCount() - 1);
continue; continue;
}
if (tab->supports_printer_technology(printer_technology)) if (tab->supports_printer_technology(printer_technology))
{ {
wxGetApp().tab_panel()->InsertPage(wxGetApp().tab_panel()->FindPage(this), tab, tab->title()); wxGetApp().tab_panel()->InsertPage(wxGetApp().tab_panel()->FindPage(this), tab, tab->title());
@ -3324,7 +3358,7 @@ void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/,
} }
if (technology_changed) if (technology_changed)
wxGetApp().mainframe->diff_dialog.update_presets(); wxGetApp().mainframe->technology_changed();
} }
// If the current preset is dirty, the user is asked whether the changes may be discarded. // If the current preset is dirty, the user is asked whether the changes may be discarded.
@ -3651,7 +3685,8 @@ void Tab::delete_preset()
// TRN Remove/Delete // TRN Remove/Delete
wxString title = from_u8((boost::format(_utf8(L("%1% Preset"))) % action).str()); //action + _(L(" Preset")); wxString title = from_u8((boost::format(_utf8(L("%1% Preset"))) % action).str()); //action + _(L(" Preset"));
if (current_preset.is_default || if (current_preset.is_default ||
wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal()) //wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal())
wxID_YES != MessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal())
return; return;
// if we just delete preset from the physical printer // if we just delete preset from the physical printer
@ -3730,6 +3765,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
{ {
deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All"))); deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All")));
deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font());
wxGetApp().UpdateDarkUI(deps.checkbox, false, true);
deps.btn = new ScalableButton(parent, wxID_ANY, "printer", from_u8((boost::format(" %s %s") % _utf8(L("Set")) % std::string(dots.ToUTF8())).str()), deps.btn = new ScalableButton(parent, wxID_ANY, "printer", from_u8((boost::format(" %s %s") % _utf8(L("Set")) % std::string(dots.ToUTF8())).str()),
wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT, true); wxDefaultSize, wxDefaultPosition, wxBU_LEFT | wxBU_EXACTFIT, true);
deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
@ -3768,6 +3804,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
} }
wxMultiChoiceDialog dlg(parent, deps.dialog_title, deps.dialog_label, presets); wxMultiChoiceDialog dlg(parent, deps.dialog_title, deps.dialog_label, presets);
wxGetApp().UpdateDlgDarkUI(&dlg);
// Collect and set indices of depending_presets marked as compatible. // Collect and set indices of depending_presets marked as compatible.
wxArrayInt selections; wxArrayInt selections;
auto *compatible_printers = dynamic_cast<const ConfigOptionStrings*>(m_config->option(deps.key_list)); auto *compatible_printers = dynamic_cast<const ConfigOptionStrings*>(m_config->option(deps.key_list));

View File

@ -17,6 +17,7 @@
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/listbook.h>
#include <wx/scrolwin.h> #include <wx/scrolwin.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/bmpcbox.h> #include <wx/bmpcbox.h>
@ -104,7 +105,7 @@ protected:
using PageShp = std::shared_ptr<Page>; using PageShp = std::shared_ptr<Page>;
class Tab: public wxPanel class Tab: public wxPanel
{ {
wxNotebook* m_parent; wxBookCtrlBase* m_parent;
#ifdef __WXOSX__ #ifdef __WXOSX__
wxPanel* m_tmp_panel; wxPanel* m_tmp_panel;
int m_size_move = -1; int m_size_move = -1;
@ -259,13 +260,11 @@ public:
int m_update_cnt = 0; int m_update_cnt = 0;
public: public:
// Tab(wxNotebook* parent, const wxString& title, const char* name); Tab(wxBookCtrlBase* parent, const wxString& title, Preset::Type type);
Tab(wxNotebook* parent, const wxString& title, Preset::Type type);
~Tab() {} ~Tab() {}
wxWindow* parent() const { return m_parent; } wxWindow* parent() const { return m_parent; }
wxString title() const { return m_title; } wxString title() const { return m_title; }
// std::string name() const { return m_name; }
std::string name() const { return m_presets->name(); } std::string name() const { return m_presets->name(); }
Preset::Type type() const { return m_type; } Preset::Type type() const { return m_type; }
// The tab is already constructed. // The tab is already constructed.
@ -386,9 +385,8 @@ protected:
class TabPrint : public Tab class TabPrint : public Tab
{ {
public: public:
TabPrint(wxNotebook* parent) : TabPrint(wxBookCtrlBase* parent) :
// Tab(parent, _L("Print Settings"), L("print")) {} Tab(parent, _(L("Print Settings")), Slic3r::Preset::TYPE_PRINT) {}
Tab(parent, _L("Print Settings"), Slic3r::Preset::TYPE_PRINT) {}
~TabPrint() {} ~TabPrint() {}
void build() override; void build() override;
@ -420,9 +418,8 @@ private:
std::map<std::string, wxCheckBox*> m_overrides_options; std::map<std::string, wxCheckBox*> m_overrides_options;
public: public:
TabFilament(wxNotebook* parent) : TabFilament(wxBookCtrlBase* parent) :
// Tab(parent, _L("Filament Settings"), L("filament")) {} Tab(parent, _(L("Filament Settings")), Slic3r::Preset::TYPE_FILAMENT) {}
Tab(parent, _L("Filament Settings"), Slic3r::Preset::TYPE_FILAMENT) {}
~TabFilament() {} ~TabFilament() {}
void build() override; void build() override;
@ -466,8 +463,7 @@ public:
PrinterTechnology m_printer_technology = ptFFF; PrinterTechnology m_printer_technology = ptFFF;
// TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), L("printer")) {} TabPrinter(wxBookCtrlBase* parent) :
TabPrinter(wxNotebook* parent) :
Tab(parent, _L("Printer Settings"), Slic3r::Preset::TYPE_PRINTER) {} Tab(parent, _L("Printer Settings"), Slic3r::Preset::TYPE_PRINTER) {}
~TabPrinter() {} ~TabPrinter() {}
@ -504,9 +500,8 @@ public:
class TabSLAMaterial : public Tab class TabSLAMaterial : public Tab
{ {
public: public:
TabSLAMaterial(wxNotebook* parent) : TabSLAMaterial(wxBookCtrlBase* parent) :
// Tab(parent, _L("Material Settings"), L("sla_material")) {} Tab(parent, _(L("Material Settings")), Slic3r::Preset::TYPE_SLA_MATERIAL) {}
Tab(parent, _L("Material Settings"), Slic3r::Preset::TYPE_SLA_MATERIAL) {}
~TabSLAMaterial() {} ~TabSLAMaterial() {}
void build() override; void build() override;
@ -524,9 +519,8 @@ public:
class TabSLAPrint : public Tab class TabSLAPrint : public Tab
{ {
public: public:
TabSLAPrint(wxNotebook* parent) : TabSLAPrint(wxBookCtrlBase* parent) :
// Tab(parent, _L("Print Settings"), L("sla_print")) {} Tab(parent, _(L("Print Settings")), Slic3r::Preset::TYPE_SLA_PRINT) {}
Tab(parent, _L("Print Settings"), Slic3r::Preset::TYPE_SLA_PRINT) {}
~TabSLAPrint() {} ~TabSLAPrint() {}
ogStaticText* m_support_object_elevation_description_line = nullptr; ogStaticText* m_support_object_elevation_description_line = nullptr;

View File

@ -19,6 +19,7 @@
#include "wxExtensions.hpp" #include "wxExtensions.hpp"
#include "SavePresetDialog.hpp" #include "SavePresetDialog.hpp"
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include "MsgDialog.hpp"
//#define FTS_FUZZY_MATCH_IMPLEMENTATION //#define FTS_FUZZY_MATCH_IMPLEMENTATION
//#include "fts_fuzzy_match.h" //#include "fts_fuzzy_match.h"
@ -56,7 +57,7 @@ static std::string get_icon_name(Preset::Type type, PrinterTechnology pt) {
static std::string def_text_color() static std::string def_text_color()
{ {
wxColour def_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); wxColour def_colour = wxGetApp().get_label_clr_default();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), def_colour.Red(), def_colour.Green(), def_colour.Blue()); auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), def_colour.Red(), def_colour.Green(), def_colour.Blue());
return clr_str.ToStdString(); return clr_str.ToStdString();
} }
@ -581,9 +582,15 @@ static std::string get_pure_opt_key(std::string opt_key)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
DiffViewCtrl::DiffViewCtrl(wxWindow* parent, wxSize size) DiffViewCtrl::DiffViewCtrl(wxWindow* parent, wxSize size)
: wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, size, wxBORDER_SIMPLE | wxDV_VARIABLE_LINE_HEIGHT | wxDV_ROW_LINES), : wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, size, wxDV_VARIABLE_LINE_HEIGHT | wxDV_ROW_LINES
#ifdef _WIN32
| wxBORDER_SIMPLE
#endif
),
m_em_unit(em_unit(parent)) m_em_unit(em_unit(parent))
{ {
wxGetApp().UpdateDVCDarkUI(this);
model = new DiffModel(parent); model = new DiffModel(parent);
this->AssociateModel(model); this->AssociateModel(model);
model->SetAssociatedControl(this); model->SetAssociatedControl(this);
@ -789,9 +796,6 @@ UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, PresetCollection*
void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header) void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_presets, const std::string& new_selected_preset, const wxString& header)
{ {
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
SetBackgroundColour(bgr_clr);
#if defined(__WXMSW__) #if defined(__WXMSW__)
// ys_FIXME! temporary workaround for correct font scaling // ys_FIXME! temporary workaround for correct font scaling
// Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts, // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
@ -865,7 +869,8 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
_L("You will not be asked about the unsaved changes the next time you switch a preset.")) + "\n\n" + _L("You will not be asked about the unsaved changes the next time you switch a preset.")) + "\n\n" +
format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto be asked about unsaved changes again."), preferences_item); format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto be asked about unsaved changes again."), preferences_item);
wxMessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION); //wxMessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
MessageDialog dialog(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
if (dialog.ShowModal() == wxID_CANCEL) if (dialog.ShowModal() == wxID_CANCEL)
m_remember_choice->SetValue(false); m_remember_choice->SetValue(false);
}); });
@ -1279,8 +1284,7 @@ void UnsavedChangesDialog::on_sys_color_changed()
FullCompareDialog::FullCompareDialog(const wxString& option_name, const wxString& old_value, const wxString& new_value) FullCompareDialog::FullCompareDialog(const wxString& option_name, const wxString& old_value, const wxString& new_value)
: wxDialog(nullptr, wxID_ANY, option_name, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) : wxDialog(nullptr, wxID_ANY, option_name, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); wxGetApp().UpdateDarkUI(this);
SetBackgroundColour(bgr_clr);
int border = 10; int border = 10;
@ -1323,7 +1327,8 @@ FullCompareDialog::FullCompareDialog(const wxString& option_name, const wxString
std::set_difference(new_set.begin(), new_set.end(), old_set.begin(), old_set.end(), std::inserter(new_old_diff_set, new_old_diff_set.begin())); std::set_difference(new_set.begin(), new_set.end(), old_set.begin(), old_set.end(), std::inserter(new_old_diff_set, new_old_diff_set.begin()));
auto add_value = [grid_sizer, border, this](wxString label, const std::set<wxString>& diff_set, bool is_colored = false) { auto add_value = [grid_sizer, border, this](wxString label, const std::set<wxString>& diff_set, bool is_colored = false) {
wxTextCtrl* text = new wxTextCtrl(this, wxID_ANY, label, wxDefaultPosition, wxSize(400, 400), wxTE_MULTILINE | wxTE_READONLY | wxBORDER_NONE | wxTE_RICH); wxTextCtrl* text = new wxTextCtrl(this, wxID_ANY, label, wxDefaultPosition, wxSize(400, 400), wxTE_MULTILINE | wxTE_READONLY | wxBORDER_SIMPLE | wxTE_RICH);
wxGetApp().UpdateDarkUI(text);
text->SetStyle(0, label.Len(), wxTextAttr(is_colored ? wxColour(orange) : wxNullColour, wxNullColour, this->GetFont())); text->SetStyle(0, label.Len(), wxTextAttr(is_colored ? wxColour(orange) : wxNullColour, wxNullColour, this->GetFont()));
for (const wxString& str : diff_set) { for (const wxString& str : diff_set) {
@ -1341,6 +1346,7 @@ FullCompareDialog::FullCompareDialog(const wxString& option_name, const wxString
sizer->Add(grid_sizer, 1, wxEXPAND); sizer->Add(grid_sizer, 1, wxEXPAND);
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK); wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK);
wxGetApp().UpdateDarkUI(static_cast<wxButton*>(this->FindWindowById(wxID_OK, this)), true);
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
@ -1375,9 +1381,6 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe)
: DPIDialog(mainframe, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), : DPIDialog(mainframe, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
m_pr_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology()) m_pr_technology(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology())
{ {
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
SetBackgroundColour(bgr_clr);
#if defined(__WXMSW__) #if defined(__WXMSW__)
// ys_FIXME! temporary workaround for correct font scaling // ys_FIXME! temporary workaround for correct font scaling
// Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts, // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts,
@ -1673,6 +1676,17 @@ void DiffPresetDialog::on_dpi_changed(const wxRect&)
void DiffPresetDialog::on_sys_color_changed() void DiffPresetDialog::on_sys_color_changed()
{ {
#ifdef _WIN32
wxGetApp().UpdateAllStaticTextDarkUI(this);
wxGetApp().UpdateDarkUI(m_show_all_presets);
wxGetApp().UpdateDVCDarkUI(m_tree);
#endif
for (auto preset_combos : m_preset_combos) {
preset_combos.presets_left->msw_rescale();
preset_combos.equal_bmp->msw_rescale();
preset_combos.presets_right->msw_rescale();
}
// msw_rescale updates just icons, so use it // msw_rescale updates just icons, so use it
m_tree->Rescale(); m_tree->Rescale();
Refresh(); Refresh();

View File

@ -137,6 +137,8 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates) :
btn_sizer->Add(btn_ok); btn_sizer->Add(btn_ok);
btn_ok->SetFocus(); btn_ok->SetFocus();
wxGetApp().UpdateDlgDarkUI(this);
Fit(); Fit();
} }
@ -292,6 +294,8 @@ MsgDataLegacy::MsgDataLegacy() :
content_sizer->Add(link); content_sizer->Add(link);
content_sizer->AddSpacer(VERT_SPACING); content_sizer->AddSpacer(VERT_SPACING);
wxGetApp().UpdateDlgDarkUI(this);
Fit(); Fit();
} }
@ -316,6 +320,8 @@ MsgNoUpdates::MsgNoUpdates() :
logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, 192)); logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, 192));
wxGetApp().UpdateDlgDarkUI(this);
Fit(); Fit();
} }

View File

@ -5,23 +5,32 @@
#include "GUI.hpp" #include "GUI.hpp"
#include "I18N.hpp" #include "I18N.hpp"
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include "MsgDialog.hpp"
#include <wx/sizer.h> #include <wx/sizer.h>
int scale(const int val) { return val * Slic3r::GUI::wxGetApp().em_unit(); } int scale(const int val) { return val * Slic3r::GUI::wxGetApp().em_unit(); }
int ITEM_WIDTH() { return scale(6); } int ITEM_WIDTH() { return scale(6); }
static void update_ui(wxWindow* window)
{
Slic3r::GUI::wxGetApp().UpdateDarkUI(window);
}
RammingDialog::RammingDialog(wxWindow* parent,const std::string& parameters) RammingDialog::RammingDialog(wxWindow* parent,const std::string& parameters)
: wxDialog(parent, wxID_ANY, _(L("Ramming customization")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/) : wxDialog(parent, wxID_ANY, _(L("Ramming customization")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/)
{ {
update_ui(this);
m_panel_ramming = new RammingPanel(this,parameters); m_panel_ramming = new RammingPanel(this,parameters);
// Not found another way of getting the background colours of RammingDialog, RammingPanel and Chart correct than setting // Not found another way of getting the background colours of RammingDialog, RammingPanel and Chart correct than setting
// them all explicitely. Reading the parent colour yielded colour that didn't really match it, no wxSYS_COLOUR_... matched // them all explicitely. Reading the parent colour yielded colour that didn't really match it, no wxSYS_COLOUR_... matched
// colour used for the dialog. Same issue (and "solution") here : https://forums.wxwidgets.org/viewtopic.php?f=1&t=39608 // colour used for the dialog. Same issue (and "solution") here : https://forums.wxwidgets.org/viewtopic.php?f=1&t=39608
// Whoever can fix this, feel free to do so. // Whoever can fix this, feel free to do so.
#ifndef _WIN32
this-> SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK)); this-> SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK));
m_panel_ramming->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK)); m_panel_ramming->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK));
#endif
m_panel_ramming->Show(true); m_panel_ramming->Show(true);
this->Show(); this->Show();
@ -31,6 +40,9 @@ RammingDialog::RammingDialog(wxWindow* parent,const std::string& parameters)
SetSizer(main_sizer); SetSizer(main_sizer);
main_sizer->SetSizeHints(this); main_sizer->SetSizeHints(this);
update_ui(static_cast<wxButton*>(this->FindWindowById(wxID_OK, this)));
update_ui(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); }); this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); });
this->Bind(wxEVT_BUTTON,[this](wxCommandEvent&) { this->Bind(wxEVT_BUTTON,[this](wxCommandEvent&) {
@ -38,20 +50,28 @@ RammingDialog::RammingDialog(wxWindow* parent,const std::string& parameters)
EndModal(wxID_OK); EndModal(wxID_OK);
},wxID_OK); },wxID_OK);
this->Show(); this->Show();
wxMessageDialog(this,_(L("Ramming denotes the rapid extrusion just before a tool change in a single-extruder MM printer. Its purpose is to " // wxMessageDialog dlg(this, _(L("Ramming denotes the rapid extrusion just before a tool change in a single-extruder MM printer. Its purpose is to "
"properly shape the end of the unloaded filament so it does not prevent insertion of the new filament and can itself " Slic3r::GUI::MessageDialog dlg(this, _(L("Ramming denotes the rapid extrusion just before a tool change in a single-extruder MM printer. Its purpose is to "
"be reinserted later. This phase is important and different materials can require different extrusion speeds to get " "properly shape the end of the unloaded filament so it does not prevent insertion of the new filament and can itself "
"the good shape. For this reason, the extrusion rates during ramming are adjustable.\n\nThis is an expert-level " "be reinserted later. This phase is important and different materials can require different extrusion speeds to get "
"setting, incorrect adjustment will likely lead to jams, extruder wheel grinding into filament etc.")),_(L("Warning")),wxOK|wxICON_EXCLAMATION).ShowModal(); "the good shape. For this reason, the extrusion rates during ramming are adjustable.\n\nThis is an expert-level "
"setting, incorrect adjustment will likely lead to jams, extruder wheel grinding into filament etc.")), _(L("Warning")), wxOK | wxICON_EXCLAMATION);// .ShowModal();
dlg.ShowModal();
} }
#ifdef _WIN32
#define style wxSP_ARROW_KEYS | wxBORDER_SIMPLE
#else
#define style wxSP_ARROW_KEYS
#endif
RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters) RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxPoint(50,50), wxSize(800,350),wxBORDER_RAISED*/) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxPoint(50,50), wxSize(800,350),wxBORDER_RAISED*/)
{ {
update_ui(this);
auto sizer_chart = new wxBoxSizer(wxVERTICAL); auto sizer_chart = new wxBoxSizer(wxVERTICAL);
auto sizer_param = new wxBoxSizer(wxVERTICAL); auto sizer_param = new wxBoxSizer(wxVERTICAL);
@ -71,13 +91,24 @@ RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
buttons.push_back(std::make_pair(x, y)); buttons.push_back(std::make_pair(x, y));
m_chart = new Chart(this, wxRect(scale(1),scale(1),scale(48),scale(36)), buttons, ramming_speed_size, 0.25f, scale(1)); m_chart = new Chart(this, wxRect(scale(1),scale(1),scale(48),scale(36)), buttons, ramming_speed_size, 0.25f, scale(1));
#ifdef _WIN32
update_ui(m_chart);
#else
m_chart->SetBackgroundColour(parent->GetBackgroundColour()); // see comment in RammingDialog constructor m_chart->SetBackgroundColour(parent->GetBackgroundColour()); // see comment in RammingDialog constructor
#endif
sizer_chart->Add(m_chart, 0, wxALL, 5); sizer_chart->Add(m_chart, 0, wxALL, 5);
m_widget_time = new wxSpinCtrlDouble(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),wxSP_ARROW_KEYS,0.,5.0,3.,0.5); m_widget_time = new wxSpinCtrlDouble(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,0.,5.0,3.,0.5);
m_widget_volume = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),wxSP_ARROW_KEYS,0,10000,0); m_widget_volume = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,0,10000,0);
m_widget_ramming_line_width_multiplicator = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),wxSP_ARROW_KEYS,10,200,100); m_widget_ramming_line_width_multiplicator = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,10,200,100);
m_widget_ramming_step_multiplicator = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),wxSP_ARROW_KEYS,10,200,100); m_widget_ramming_step_multiplicator = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,10,200,100);
#ifdef _WIN32
update_ui(m_widget_time->GetText());
update_ui(m_widget_volume);
update_ui(m_widget_ramming_line_width_multiplicator);
update_ui(m_widget_ramming_step_multiplicator);
#endif
auto gsizer_param = new wxFlexGridSizer(2, 5, 15); auto gsizer_param = new wxFlexGridSizer(2, 5, 15);
gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Total ramming time")) + " (" + _(L("s")) + "):")), 0, wxALIGN_CENTER_VERTICAL); gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Total ramming time")) + " (" + _(L("s")) + "):")), 0, wxALIGN_CENTER_VERTICAL);
@ -141,7 +172,9 @@ std::string RammingPanel::get_parameters()
WipingDialog::WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours) WipingDialog::WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours)
: wxDialog(parent, wxID_ANY, _(L("Wipe tower - Purging volume adjustment")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/) : wxDialog(parent, wxID_ANY, _(L("Wipe tower - Purging volume adjustment")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/)
{ {
update_ui(this);
auto widget_button = new wxButton(this,wxID_ANY,"-",wxPoint(0,0),wxDefaultSize); auto widget_button = new wxButton(this,wxID_ANY,"-",wxPoint(0,0),wxDefaultSize);
update_ui(widget_button);
m_panel_wiping = new WipingPanel(this,matrix,extruders, extruder_colours, widget_button); m_panel_wiping = new WipingPanel(this,matrix,extruders, extruder_colours, widget_button);
auto main_sizer = new wxBoxSizer(wxVERTICAL); auto main_sizer = new wxBoxSizer(wxVERTICAL);
@ -156,6 +189,9 @@ WipingDialog::WipingDialog(wxWindow* parent, const std::vector<float>& matrix, c
SetSizer(main_sizer); SetSizer(main_sizer);
main_sizer->SetSizeHints(this); main_sizer->SetSizeHints(this);
update_ui(static_cast<wxButton*>(this->FindWindowById(wxID_OK, this)));
update_ui(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); }); this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); });
this->Bind(wxEVT_BUTTON,[this](wxCommandEvent&) { // if OK button is clicked.. this->Bind(wxEVT_BUTTON,[this](wxCommandEvent&) { // if OK button is clicked..
@ -203,6 +239,9 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
m_page_simple->SetSizer(m_sizer_simple); m_page_simple->SetSizer(m_sizer_simple);
m_page_advanced->SetSizer(m_sizer_advanced); m_page_advanced->SetSizer(m_sizer_advanced);
update_ui(m_page_simple);
update_ui(m_page_advanced);
auto gridsizer_simple = new wxGridSizer(3, 5, 10); auto gridsizer_simple = new wxGridSizer(3, 5, 10);
m_gridsizer_advanced = new wxGridSizer(m_number_of_extruders+1, 5, 1); m_gridsizer_advanced = new wxGridSizer(m_number_of_extruders+1, 5, 1);
@ -211,7 +250,13 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
edit_boxes.push_back(std::vector<wxTextCtrl*>(0)); edit_boxes.push_back(std::vector<wxTextCtrl*>(0));
for (unsigned int j = 0; j < m_number_of_extruders; ++j) { for (unsigned int j = 0; j < m_number_of_extruders; ++j) {
#ifdef _WIN32
wxTextCtrl* text = new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), wxBORDER_SIMPLE);
update_ui(text);
edit_boxes.back().push_back(text);
#else
edit_boxes.back().push_back(new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1))); edit_boxes.back().push_back(new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1)));
#endif
if (i == j) if (i == j)
edit_boxes[i][j]->Disable(); edit_boxes[i][j]->Disable();
else else
@ -265,7 +310,8 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
auto add_spin_ctrl = [this](std::vector<wxSpinCtrl*>& vec, float initial) auto add_spin_ctrl = [this](std::vector<wxSpinCtrl*>& vec, float initial)
{ {
wxSpinCtrl* spin_ctrl = new wxSpinCtrl(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), wxSP_ARROW_KEYS | wxALIGN_RIGHT, 0, 300, (int)initial); wxSpinCtrl* spin_ctrl = new wxSpinCtrl(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), style | wxALIGN_RIGHT, 0, 300, (int)initial);
update_ui(spin_ctrl);
vec.push_back(spin_ctrl); vec.push_back(spin_ctrl);
#ifdef __WXOSX__ #ifdef __WXOSX__
@ -392,8 +438,9 @@ bool WipingPanel::advanced_matches_simple() {
// Switches the dialog from simple to advanced mode and vice versa // Switches the dialog from simple to advanced mode and vice versa
void WipingPanel::toggle_advanced(bool user_action) { void WipingPanel::toggle_advanced(bool user_action) {
if (m_advanced && !advanced_matches_simple() && user_action) { if (m_advanced && !advanced_matches_simple() && user_action) {
if (wxMessageDialog(this,wxString(_(L("Switching to simple settings will discard changes done in the advanced mode!\n\nDo you want to proceed?"))), // if (wxMessageDialog(this,wxString(_(L("Switching to simple settings will discard changes done in the advanced mode!\n\nDo you want to proceed?"))),
wxString(_(L("Warning"))),wxYES_NO|wxICON_EXCLAMATION).ShowModal() != wxID_YES) if (Slic3r::GUI::MessageDialog(this, _L("Switching to simple settings will discard changes done in the advanced mode!\n\nDo you want to proceed?"),
_L("Warning"),wxYES_NO|wxICON_EXCLAMATION).ShowModal() != wxID_YES)
return; return;
} }
if (user_action) if (user_action)

View File

@ -15,6 +15,7 @@
#include "GUI_Utils.hpp" #include "GUI_Utils.hpp"
#include "Plater.hpp" #include "Plater.hpp"
#include "../Utils/MacDarkMode.hpp" #include "../Utils/MacDarkMode.hpp"
#include "BitmapComboBox.hpp"
#ifndef __linux__ #ifndef __linux__
// msw_menuitem_bitmaps is used for MSW and OSX // msw_menuitem_bitmaps is used for MSW and OSX
@ -26,7 +27,7 @@ void msw_rescale_menu(wxMenu* menu)
static void run(wxMenuItem* item) { static void run(wxMenuItem* item) {
const auto it = msw_menuitem_bitmaps.find(item->GetId()); const auto it = msw_menuitem_bitmaps.find(item->GetId());
if (it != msw_menuitem_bitmaps.end()) { if (it != msw_menuitem_bitmaps.end()) {
const wxBitmap& item_icon = create_scaled_bitmap(it->second); const wxBitmap& item_icon = create_menu_bitmap(it->second);
if (item_icon.IsOk()) if (item_icon.IsOk())
item->SetBitmap(item_icon); item->SetBitmap(item_icon);
} }
@ -96,7 +97,7 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const
if (id == wxID_ANY) if (id == wxID_ANY)
id = wxNewId(); id = wxNewId();
const wxBitmap& bmp = !icon.empty() ? create_scaled_bitmap(icon) : wxNullBitmap; // FIXME: pass window ptr const wxBitmap& bmp = !icon.empty() ? create_menu_bitmap(icon) : wxNullBitmap; // FIXME: pass window ptr
//#ifdef __WXMSW__ //#ifdef __WXMSW__
#ifndef __WXGTK__ #ifndef __WXGTK__
if (bmp.IsOk()) if (bmp.IsOk())
@ -114,7 +115,7 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin
wxMenuItem* item = new wxMenuItem(menu, id, string, description); wxMenuItem* item = new wxMenuItem(menu, id, string, description);
if (!icon.empty()) { if (!icon.empty()) {
item->SetBitmap(create_scaled_bitmap(icon)); // FIXME: pass window ptr item->SetBitmap(create_menu_bitmap(icon)); // FIXME: pass window ptr
//#ifdef __WXMSW__ //#ifdef __WXMSW__
#ifndef __WXGTK__ #ifndef __WXGTK__
msw_menuitem_bitmaps[id] = icon; msw_menuitem_bitmaps[id] = icon;
@ -416,13 +417,19 @@ int mode_icon_px_size()
#endif #endif
} }
wxBitmap create_menu_bitmap(const std::string& bmp_name)
{
return create_scaled_bitmap(bmp_name, nullptr, 16, false, true);
}
// win is used to get a correct em_unit value // win is used to get a correct em_unit value
// It's important for bitmaps of dialogs. // It's important for bitmaps of dialogs.
// if win == nullptr, em_unit value of MainFrame will be used // if win == nullptr, em_unit value of MainFrame will be used
wxBitmap create_scaled_bitmap( const std::string& bmp_name_in, wxBitmap create_scaled_bitmap( const std::string& bmp_name_in,
wxWindow *win/* = nullptr*/, wxWindow *win/* = nullptr*/,
const int px_cnt/* = 16*/, const int px_cnt/* = 16*/,
const bool grayscale/* = false*/) const bool grayscale/* = false*/,
const bool menu_bitmap/* = false*/)
{ {
static Slic3r::GUI::BitmapCache cache; static Slic3r::GUI::BitmapCache cache;
@ -432,8 +439,14 @@ wxBitmap create_scaled_bitmap( const std::string& bmp_name_in,
std::string bmp_name = bmp_name_in; std::string bmp_name = bmp_name_in;
boost::replace_last(bmp_name, ".png", ""); boost::replace_last(bmp_name, ".png", "");
bool dark_mode =
#ifdef _WIN32
menu_bitmap ? Slic3r::GUI::check_dark_mode() :
#endif
Slic3r::GUI::wxGetApp().dark_mode();
// Try loading an SVG first, then PNG if SVG is not found: // Try loading an SVG first, then PNG if SVG is not found:
wxBitmap *bmp = cache.load_svg(bmp_name, width, height, grayscale, Slic3r::GUI::wxGetApp().dark_mode()); wxBitmap *bmp = cache.load_svg(bmp_name, width, height, grayscale, dark_mode);
if (bmp == nullptr) { if (bmp == nullptr) {
bmp = cache.load_png(bmp_name, width, height, grayscale); bmp = cache.load_png(bmp_name, width, height, grayscale);
} }
@ -487,7 +500,7 @@ std::vector<wxBitmap*> get_extruder_color_icons(bool thin_icon/* = false*/)
} }
void apply_extruder_selector(wxBitmapComboBox** ctrl, void apply_extruder_selector(Slic3r::GUI::BitmapComboBox** ctrl,
wxWindow* parent, wxWindow* parent,
const std::string& first_item/* = ""*/, const std::string& first_item/* = ""*/,
wxPoint pos/* = wxDefaultPosition*/, wxPoint pos/* = wxDefaultPosition*/,
@ -496,9 +509,10 @@ void apply_extruder_selector(wxBitmapComboBox** ctrl,
{ {
std::vector<wxBitmap*> icons = get_extruder_color_icons(use_thin_icon); std::vector<wxBitmap*> icons = get_extruder_color_icons(use_thin_icon);
if (!*ctrl) if (!*ctrl) {
*ctrl = new wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, pos, size, *ctrl = new Slic3r::GUI::BitmapComboBox(parent, wxID_ANY, wxEmptyString, pos, size, 0, nullptr, wxCB_READONLY);
0, nullptr, wxCB_READONLY); Slic3r::GUI::wxGetApp().UpdateDarkUI(*ctrl);
}
else else
{ {
(*ctrl)->SetPosition(pos); (*ctrl)->SetPosition(pos);
@ -550,9 +564,7 @@ LockButton::LockButton( wxWindow *parent,
m_bmp_lock_open = ScalableBitmap(this, "lock_open"); m_bmp_lock_open = ScalableBitmap(this, "lock_open");
m_bmp_lock_open_f = ScalableBitmap(this, "lock_open_f"); m_bmp_lock_open_f = ScalableBitmap(this, "lock_open_f");
#ifdef __WXMSW__ Slic3r::GUI::wxGetApp().UpdateDarkUI(this);
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__
SetBitmap(m_bmp_lock_open.bmp()); SetBitmap(m_bmp_lock_open.bmp());
SetBitmapDisabled(m_bmp_lock_open.bmp()); SetBitmapDisabled(m_bmp_lock_open.bmp());
SetBitmapHover(m_bmp_lock_closed_f.bmp()); SetBitmapHover(m_bmp_lock_closed_f.bmp());
@ -590,9 +602,7 @@ void LockButton::msw_rescale()
void LockButton::update_button_bitmaps() void LockButton::update_button_bitmaps()
{ {
#ifdef __WXMSW__ Slic3r::GUI::wxGetApp().UpdateDarkUI(this);
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
SetBitmap(m_is_pushed ? m_bmp_lock_closed.bmp() : m_bmp_lock_open.bmp()); SetBitmap(m_is_pushed ? m_bmp_lock_closed.bmp() : m_bmp_lock_open.bmp());
SetBitmapHover(m_is_pushed ? m_bmp_lock_closed_f.bmp() : m_bmp_lock_open_f.bmp()); SetBitmapHover(m_is_pushed ? m_bmp_lock_closed_f.bmp() : m_bmp_lock_open_f.bmp());
@ -662,6 +672,7 @@ void ModeButton::focus_button(const bool focus)
Slic3r::GUI::wxGetApp().normal_font(); Slic3r::GUI::wxGetApp().normal_font();
SetFont(new_font); SetFont(new_font);
#ifndef _WIN32
SetForegroundColour(wxSystemSettings::GetColour(focus ? wxSYS_COLOUR_BTNTEXT : SetForegroundColour(wxSystemSettings::GetColour(focus ? wxSYS_COLOUR_BTNTEXT :
#if defined (__linux__) && defined (__WXGTK3__) #if defined (__linux__) && defined (__WXGTK3__)
wxSYS_COLOUR_GRAYTEXT wxSYS_COLOUR_GRAYTEXT
@ -671,6 +682,7 @@ void ModeButton::focus_button(const bool focus)
wxSYS_COLOUR_BTNSHADOW wxSYS_COLOUR_BTNSHADOW
#endif #endif
)); ));
#endif /* no _WIN32 */
Refresh(); Refresh();
Update(); Update();
@ -820,13 +832,11 @@ ScalableButton::ScalableButton( wxWindow * parent,
m_parent(parent), m_parent(parent),
m_current_icon_name(icon_name), m_current_icon_name(icon_name),
m_use_default_disabled_bitmap (use_default_disabled_bitmap), m_use_default_disabled_bitmap (use_default_disabled_bitmap),
m_px_cnt(bmp_px_cnt) m_px_cnt(bmp_px_cnt),
m_has_border(!(style & wxNO_BORDER))
{ {
Create(parent, id, label, pos, size, style); Create(parent, id, label, pos, size, style);
#ifdef __WXMSW__ Slic3r::GUI::wxGetApp().UpdateDarkUI(this);
if (style & wxNO_BORDER)
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__
SetBitmap(create_scaled_bitmap(icon_name, parent, m_px_cnt)); SetBitmap(create_scaled_bitmap(icon_name, parent, m_px_cnt));
if (m_use_default_disabled_bitmap) if (m_use_default_disabled_bitmap)
@ -848,13 +858,11 @@ ScalableButton::ScalableButton( wxWindow * parent,
long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) : long style /*= wxBU_EXACTFIT | wxNO_BORDER*/) :
m_parent(parent), m_parent(parent),
m_current_icon_name(bitmap.name()), m_current_icon_name(bitmap.name()),
m_px_cnt(bitmap.px_cnt()) m_px_cnt(bitmap.px_cnt()),
m_has_border(!(style& wxNO_BORDER))
{ {
Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style); Create(parent, id, label, wxDefaultPosition, wxDefaultSize, style);
#ifdef __WXMSW__ Slic3r::GUI::wxGetApp().UpdateDarkUI(this);
if (style & wxNO_BORDER)
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__
SetBitmap(bitmap.bmp()); SetBitmap(bitmap.bmp());
} }
@ -888,9 +896,8 @@ void ScalableButton::UseDefaultBitmapDisabled()
void ScalableButton::msw_rescale() void ScalableButton::msw_rescale()
{ {
#ifdef __WXMSW__ Slic3r::GUI::wxGetApp().UpdateDarkUI(this, m_has_border);
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
SetBitmap(create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt)); SetBitmap(create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt));
if (!m_disabled_icon_name.empty()) if (!m_disabled_icon_name.empty())
SetBitmapDisabled(create_scaled_bitmap(m_disabled_icon_name, m_parent, m_px_cnt)); SetBitmapDisabled(create_scaled_bitmap(m_disabled_icon_name, m_parent, m_px_cnt));

View File

@ -48,11 +48,19 @@ void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector<
int em_unit(wxWindow* win); int em_unit(wxWindow* win);
int mode_icon_px_size(); int mode_icon_px_size();
wxBitmap create_menu_bitmap(const std::string& bmp_name);
wxBitmap create_scaled_bitmap(const std::string& bmp_name, wxWindow *win = nullptr, wxBitmap create_scaled_bitmap(const std::string& bmp_name, wxWindow *win = nullptr,
const int px_cnt = 16, const bool grayscale = false); const int px_cnt = 16, const bool grayscale = false, const bool menu_bitmap = false);
std::vector<wxBitmap*> get_extruder_color_icons(bool thin_icon = false); std::vector<wxBitmap*> get_extruder_color_icons(bool thin_icon = false);
void apply_extruder_selector(wxBitmapComboBox** ctrl,
namespace Slic3r {
namespace GUI {
class BitmapComboBox;
}
}
void apply_extruder_selector(Slic3r::GUI::BitmapComboBox** ctrl,
wxWindow* parent, wxWindow* parent,
const std::string& first_item = "", const std::string& first_item = "",
wxPoint pos = wxDefaultPosition, wxPoint pos = wxDefaultPosition,
@ -240,6 +248,7 @@ private:
// bitmap dimensions // bitmap dimensions
int m_px_cnt{ 16 }; int m_px_cnt{ 16 };
bool m_has_border {false};
}; };

View File

@ -35,6 +35,7 @@
#include "libslic3r/Format/3mf.hpp" #include "libslic3r/Format/3mf.hpp"
#include "../GUI/GUI.hpp" #include "../GUI/GUI.hpp"
#include "../GUI/I18N.hpp" #include "../GUI/I18N.hpp"
#include "../GUI/MsgDialog.hpp"
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#include <wx/progdlg.h> #include <wx/progdlg.h>
@ -421,10 +422,12 @@ void fix_model_by_win10_sdk_gui(ModelObject &model_object, int volume_idx)
if (canceled) { if (canceled) {
// Nothing to show. // Nothing to show.
} else if (success) { } else if (success) {
wxMessageDialog dlg(nullptr, _(L("Model repaired successfully")), _(L("Model Repair by the Netfabb service")), wxICON_INFORMATION | wxOK_DEFAULT); //wxMessageDialog dlg(nullptr, _(L("Model repaired successfully")), _(L("Model Repair by the Netfabb service")), wxICON_INFORMATION | wxOK_DEFAULT);
Slic3r::GUI::MessageDialog dlg(nullptr, _(L("Model repaired successfully")), _(L("Model Repair by the Netfabb service")), wxICON_INFORMATION | wxOK_DEFAULT);
dlg.ShowModal(); dlg.ShowModal();
} else { } else {
wxMessageDialog dlg(nullptr, _(L("Model repair failed:")) + " \n" + _(progress.message), _(L("Model Repair by the Netfabb service")), wxICON_ERROR | wxOK_DEFAULT); //wxMessageDialog dlg(nullptr, _(L("Model repair failed:")) + " \n" + _(progress.message), _(L("Model Repair by the Netfabb service")), wxICON_ERROR | wxOK_DEFAULT);
Slic3r::GUI::MessageDialog dlg(nullptr, _(L("Model repair failed:")) + " \n" + _(progress.message), _(L("Model Repair by the Netfabb service")), wxICON_ERROR | wxOK_DEFAULT);
dlg.ShowModal(); dlg.ShowModal();
} }
worker_thread.join(); worker_thread.join();