Fixed conflicts after merge with master

This commit is contained in:
Enrico Turri 2019-04-25 08:09:22 +02:00
commit 771ab50466
52 changed files with 2105 additions and 1250 deletions

View File

@ -131,7 +131,7 @@ void PrintConfigDef::init_fff_params()
"as [layer_num] and [layer_z]."); "as [layer_num] and [layer_z].");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 50; def->height = 5;
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionString(""); def->default_value = new ConfigOptionString("");
@ -140,7 +140,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("This code is inserted between objects when using sequential printing. By default extruder and bed temperature are reset using non-wait command; however if M104, M109, M140 or M190 are detected in this custom code, Slic3r will not add temperature commands. Note that you can use placeholder variables for all Slic3r settings, so you can put a \"M109 S[first_layer_temperature]\" command wherever you want."); def->tooltip = L("This code is inserted between objects when using sequential printing. By default extruder and bed temperature are reset using non-wait command; however if M104, M109, M140 or M190 are detected in this custom code, Slic3r will not add temperature commands. Note that you can use placeholder variables for all Slic3r settings, so you can put a \"M109 S[first_layer_temperature]\" command wherever you want.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 120; def->height = 12;
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionString(""); def->default_value = new ConfigOptionString("");
@ -360,7 +360,7 @@ void PrintConfigDef::init_fff_params()
"Note that you can use placeholder variables for all Slic3r settings."); "Note that you can use placeholder variables for all Slic3r settings.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 120; def->height = 12;
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionString("M104 S0 ; turn off temperature\nG28 X0 ; home X axis\nM84 ; disable motors\n"); def->default_value = new ConfigOptionString("M104 S0 ; turn off temperature\nG28 X0 ; home X axis\nM84 ; disable motors\n");
@ -539,7 +539,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("If layer print time is estimated below this number of seconds, fan will be enabled " def->tooltip = L("If layer print time is estimated below this number of seconds, fan will be enabled "
"and its speed will be calculated by interpolating the minimum and maximum speeds."); "and its speed will be calculated by interpolating the minimum and maximum speeds.");
def->sidetext = L("approximate seconds"); def->sidetext = L("approximate seconds");
def->width = 60; def->width = 6;
def->min = 0; def->min = 0;
def->max = 1000; def->max = 1000;
def->mode = comExpert; def->mode = comExpert;
@ -556,7 +556,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("You can put your notes regarding the filament here."); def->tooltip = L("You can put your notes regarding the filament here.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 130; def->height = 13;
def->mode = comAdvanced; def->mode = comAdvanced;
def->default_value = new ConfigOptionStrings { "" }; def->default_value = new ConfigOptionStrings { "" };
@ -1007,7 +1007,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Inherits profile"); def->label = L("Inherits profile");
def->tooltip = L("Name of the profile, from which this profile inherits."); def->tooltip = L("Name of the profile, from which this profile inherits.");
def->full_width = true; def->full_width = true;
def->height = 50; def->height = 5;
def->default_value = new ConfigOptionString(); def->default_value = new ConfigOptionString();
def->cli = ConfigOptionDef::nocli; def->cli = ConfigOptionDef::nocli;
@ -1034,7 +1034,7 @@ void PrintConfigDef::init_fff_params()
def->cli = "after-layer-gcode|layer-gcode"; def->cli = "after-layer-gcode|layer-gcode";
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 50; def->height = 5;
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionString(""); def->default_value = new ConfigOptionString("");
@ -1053,7 +1053,7 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionBool(true); def->default_value = new ConfigOptionBool(true);
const int machine_limits_opt_width = 70; const int machine_limits_opt_width = 7;
{ {
struct AxisDefault { struct AxisDefault {
std::string name; std::string name;
@ -1252,7 +1252,7 @@ void PrintConfigDef::init_fff_params()
"header comments."); "header comments.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 130; def->height = 13;
def->mode = comAdvanced; def->mode = comAdvanced;
def->default_value = new ConfigOptionString(""); def->default_value = new ConfigOptionString("");
@ -1387,7 +1387,7 @@ void PrintConfigDef::init_fff_params()
def->gui_flags = "serialized"; def->gui_flags = "serialized";
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 60; def->height = 6;
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionStrings(); def->default_value = new ConfigOptionStrings();
@ -1402,7 +1402,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("You can put your notes regarding the printer here."); def->tooltip = L("You can put your notes regarding the printer here.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 130; def->height = 13;
def->mode = comAdvanced; def->mode = comAdvanced;
def->default_value = new ConfigOptionString(""); def->default_value = new ConfigOptionString("");
@ -1589,7 +1589,7 @@ void PrintConfigDef::init_fff_params()
def->label = ""; def->label = "";
def->full_label = L("Serial port"); def->full_label = L("Serial port");
def->tooltip = L("USB/serial port for printer connection."); def->tooltip = L("USB/serial port for printer connection.");
def->width = 200; def->width = 20;
def->default_value = new ConfigOptionString(""); def->default_value = new ConfigOptionString("");
def = this->add("serial_speed", coInt); def = this->add("serial_speed", coInt);
@ -1635,7 +1635,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("If layer print time is estimated below this number of seconds, print moves " def->tooltip = L("If layer print time is estimated below this number of seconds, print moves "
"speed will be scaled down to extend duration to this value."); "speed will be scaled down to extend duration to this value.");
def->sidetext = L("approximate seconds"); def->sidetext = L("approximate seconds");
def->width = 60; def->width = 6;
def->min = 0; def->min = 0;
def->max = 1000; def->max = 1000;
def->mode = comExpert; def->mode = comExpert;
@ -1742,7 +1742,7 @@ void PrintConfigDef::init_fff_params()
"a \"M109 S[first_layer_temperature]\" command wherever you want."); "a \"M109 S[first_layer_temperature]\" command wherever you want.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 120; def->height = 12;
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionString("G28 ; home all axes\nG1 Z5 F5000 ; lift nozzle\n"); def->default_value = new ConfigOptionString("G28 ; home all axes\nG1 Z5 F5000 ; lift nozzle\n");
@ -1758,7 +1758,7 @@ void PrintConfigDef::init_fff_params()
"in extruder order."); "in extruder order.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 120; def->height = 12;
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionStrings { "; Filament gcode\n" }; def->default_value = new ConfigOptionStrings { "; Filament gcode\n" };
@ -2008,7 +2008,7 @@ void PrintConfigDef::init_fff_params()
"as [previous_extruder] and [next_extruder]."); "as [previous_extruder] and [next_extruder].");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 50; def->height = 5;
def->mode = comExpert; def->mode = comExpert;
def->default_value = new ConfigOptionString(""); def->default_value = new ConfigOptionString("");
@ -2330,7 +2330,7 @@ void PrintConfigDef::init_sla_params()
def->tooltip = L("You can put your notes regarding the SLA print material here."); def->tooltip = L("You can put your notes regarding the SLA print material here.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 130; def->height = 13;
def->mode = comAdvanced; def->mode = comAdvanced;
def->default_value = new ConfigOptionString(""); def->default_value = new ConfigOptionString("");

View File

@ -32,8 +32,11 @@ void AboutDialogLogo::onRepaint(wxEvent &event)
} }
AboutDialog::AboutDialog() AboutDialog::AboutDialog()
: wxDialog(NULL, wxID_ANY, wxString::Format(_(L("About %s")), SLIC3R_APP_NAME), wxDefaultPosition, wxDefaultSize, wxCAPTION) : DPIDialog(NULL, wxID_ANY, wxString::Format(_(L("About %s")), SLIC3R_APP_NAME), wxDefaultPosition,
wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
SetFont(wxGetApp().normal_font());
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
SetBackgroundColour(bgr_clr); SetBackgroundColour(bgr_clr);
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
@ -42,8 +45,9 @@ AboutDialog::AboutDialog()
main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20); main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20);
// logo // logo
auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); m_logo_bitmap = ScalableBitmap(this, "Slic3r_192px.png", 192);
hsizer->Add(logo, 1, wxALIGN_CENTER_VERTICAL); m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bitmap.bmp());
hsizer->Add(m_logo, 1, wxALIGN_CENTER_VERTICAL);
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
hsizer->Add(vsizer, 2, wxEXPAND|wxLEFT, 20); hsizer->Add(vsizer, 2, wxEXPAND|wxLEFT, 20);
@ -51,8 +55,7 @@ AboutDialog::AboutDialog()
// title // title
{ {
wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize); wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize);
wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont title_font = GUI::wxGetApp().bold_font();
title_font.SetWeight(wxFONTWEIGHT_BOLD);
title_font.SetFamily(wxFONTFAMILY_ROMAN); title_font.SetFamily(wxFONTFAMILY_ROMAN);
title_font.SetPointSize(24); title_font.SetPointSize(24);
title->SetFont(title_font); title->SetFont(title_font);
@ -63,9 +66,9 @@ AboutDialog::AboutDialog()
{ {
auto version_string = _(L("Version"))+ " " + std::string(SLIC3R_VERSION); auto version_string = _(L("Version"))+ " " + std::string(SLIC3R_VERSION);
wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize); wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
wxFont version_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont version_font = GetFont();
#ifdef __WXMSW__ #ifdef __WXMSW__
version_font.SetPointSize(9); version_font.SetPointSize(version_font.GetPointSize()-1);
#else #else
version_font.SetPointSize(11); version_font.SetPointSize(11);
#endif #endif
@ -74,18 +77,18 @@ AboutDialog::AboutDialog()
} }
// text // text
wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO/*NEVER*/); m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO/*NEVER*/);
{ {
html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit())); m_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont font = GetFont();
const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); const auto text_clr = 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());
const int fs = font.GetPointSize()-1; const int fs = font.GetPointSize()-1;
int size[] = {fs,fs,fs,fs,fs,fs,fs}; int size[] = {fs,fs,fs,fs,fs,fs,fs};
html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
html->SetBorders(2); m_html->SetBorders(2);
const auto text = wxString::Format( const auto text = wxString::Format(
"<html>" "<html>"
"<body bgcolor= %s link= %s>" "<body bgcolor= %s link= %s>"
@ -101,9 +104,9 @@ AboutDialog::AboutDialog()
"</font>" "</font>"
"</body>" "</body>"
"</html>", bgr_clr_str, text_clr_str, text_clr_str); "</html>", bgr_clr_str, text_clr_str, text_clr_str);
html->SetPage(text); m_html->SetPage(text);
vsizer->Add(html, 1, wxEXPAND | wxBOTTOM, 10); vsizer->Add(m_html, 1, wxEXPAND | wxBOTTOM, 10);
html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this); m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this);
} }
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE); wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE);
@ -118,6 +121,29 @@ AboutDialog::AboutDialog()
main_sizer->SetSizeHints(this); main_sizer->SetSizeHints(this);
} }
void AboutDialog::on_dpi_changed(const wxRect &suggested_rect)
{
m_logo_bitmap.msw_rescale();
m_logo->SetBitmap(m_logo_bitmap.bmp());
const wxFont& font = GetFont();
const int fs = font.GetPointSize() - 1;
int font_size[] = { fs, fs, fs, fs, fs, fs, fs };
m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size);
const int& em = em_unit();
m_html->SetMinSize(wxSize(-1, 16 * em));
m_html->Refresh();
const wxSize& size = wxSize(65 * em, 30 * em);
SetMinSize(size);
SetSize(size);
Refresh();
}
void AboutDialog::onLinkClicked(wxHtmlLinkEvent &event) void AboutDialog::onLinkClicked(wxHtmlLinkEvent &event)
{ {
wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref()); wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());

View File

@ -7,6 +7,9 @@
#include <wx/intl.h> #include <wx/intl.h>
#include <wx/html/htmlwin.h> #include <wx/html/htmlwin.h>
#include "GUI_Utils.hpp"
#include "wxExtensions.hpp"
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -20,11 +23,17 @@ private:
void onRepaint(wxEvent &event); void onRepaint(wxEvent &event);
}; };
class AboutDialog : public wxDialog class AboutDialog : public DPIDialog
{ {
ScalableBitmap m_logo_bitmap;
wxHtmlWindow* m_html;
wxStaticBitmap* m_logo;
public: public:
AboutDialog(); AboutDialog();
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private: private:
void onLinkClicked(wxHtmlLinkEvent &event); void onLinkClicked(wxHtmlLinkEvent &event);
void onCloseDialog(wxEvent &); void onCloseDialog(wxEvent &);

View File

@ -18,6 +18,7 @@ namespace GUI {
void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt) void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt)
{ {
SetFont(wxGetApp().normal_font());
m_panel = new BedShapePanel(this); m_panel = new BedShapePanel(this);
m_panel->build_panel(default_pt); m_panel->build_panel(default_pt);
@ -36,6 +37,22 @@ void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt)
})); }));
} }
void BedShapeDialog::on_dpi_changed(const wxRect &suggested_rect)
{
const int& em = em_unit();
m_panel->m_shape_options_book->SetMinSize(wxSize(25 * em, -1));
for (auto og : m_panel->m_optgroups)
og->msw_rescale();
const wxSize& size = wxSize(50 * em, -1);
SetMinSize(size);
SetSize(size);
Refresh();
}
void BedShapePanel::build_panel(ConfigOptionPoints* default_pt) void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
{ {
// on_change(nullptr); // on_change(nullptr);
@ -125,7 +142,7 @@ ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(wxString title)
ConfigOptionsGroupShp optgroup; ConfigOptionsGroupShp optgroup;
optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Settings"))); optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Settings")));
optgroup->label_width = 10*wxGetApp().em_unit();//100; optgroup->label_width = 10;
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
update_shape(); update_shape();
}; };

View File

@ -16,11 +16,8 @@ namespace GUI {
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>; using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
class BedShapePanel : public wxPanel class BedShapePanel : public wxPanel
{ {
wxChoicebook* m_shape_options_book;
Bed_2D* m_canvas; Bed_2D* m_canvas;
std::vector <ConfigOptionsGroupShp> m_optgroups;
public: public:
BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY) {} BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY) {}
~BedShapePanel() {} ~BedShapePanel() {}
@ -35,18 +32,25 @@ public:
// Returns the resulting bed shape polygon. This value will be stored to the ini file. // Returns the resulting bed shape polygon. This value will be stored to the ini file.
std::vector<Vec2d> GetValue() { return m_canvas->m_bed_shape; } std::vector<Vec2d> GetValue() { return m_canvas->m_bed_shape; }
wxChoicebook* m_shape_options_book;
std::vector <ConfigOptionsGroupShp> m_optgroups;
}; };
class BedShapeDialog : public wxDialog class BedShapeDialog : public DPIDialog
{ {
BedShapePanel* m_panel; BedShapePanel* m_panel;
public: public:
BedShapeDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, _(L("Bed Shape")), BedShapeDialog(wxWindow* parent) : DPIDialog(parent, wxID_ANY, _(L("Bed Shape")),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {} wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {}
~BedShapeDialog() {} ~BedShapeDialog() {}
void build_dialog(ConfigOptionPoints* default_pt); void build_dialog(ConfigOptionPoints* default_pt);
std::vector<Vec2d> GetValue() { return m_panel->GetValue(); } std::vector<Vec2d> GetValue() { return m_panel->GetValue(); }
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
}; };
} // GUI } // GUI

View File

@ -23,6 +23,8 @@ void BitmapCache::clear()
{ {
for (std::pair<const std::string, wxBitmap*> &bitmap : m_map) for (std::pair<const std::string, wxBitmap*> &bitmap : m_map)
delete bitmap.second; delete bitmap.second;
m_map.clear();
} }
static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image, float scale = 1.0f) static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image, float scale = 1.0f)
@ -259,9 +261,6 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_
wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency) wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency)
{ {
width = width * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f;
height = height * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f;
wxImage image(width, height); wxImage image(width, height);
image.InitAlpha(); image.InitAlpha();
unsigned char* imgdata = image.GetData(); unsigned char* imgdata = image.GetData();

View File

@ -7,6 +7,7 @@
#include "GUI.hpp" #include "GUI.hpp"
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include "I18N.hpp" #include "I18N.hpp"
#include "wxExtensions.hpp"
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -23,7 +24,7 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, t_icon_descriptions* ic
// Icon description // Icon description
for (auto pair : *m_icon_descriptions) for (auto pair : *m_icon_descriptions)
{ {
auto icon = new wxStaticBitmap(this, wxID_ANY, *pair.first); auto icon = new wxStaticBitmap(this, wxID_ANY, /***/pair.first->bmp());
grid_sizer->Add(icon, -1, wxALIGN_CENTRE_VERTICAL); grid_sizer->Add(icon, -1, wxALIGN_CENTRE_VERTICAL);
std::istringstream f(pair.second); std::istringstream f(pair.second);

View File

@ -4,10 +4,12 @@
#include <wx/dialog.h> #include <wx/dialog.h>
#include <vector> #include <vector>
class ScalableBitmap;
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
using t_icon_descriptions = std::vector<std::pair<wxBitmap*, std::string>>; using t_icon_descriptions = std::vector<std::pair<ScalableBitmap*, std::string>>;
class ButtonsDescription : public wxDialog class ButtonsDescription : public wxDialog
{ {
@ -15,8 +17,6 @@ class ButtonsDescription : public wxDialog
public: public:
ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions); ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions);
~ButtonsDescription() {} ~ButtonsDescription() {}
}; };
} // GUI } // GUI

View File

@ -95,21 +95,26 @@ static wxString generate_html_page(const Config::SnapshotDB &snapshot_db, const
} }
ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db, const wxString &on_snapshot) ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db, const wxString &on_snapshot)
: wxDialog(NULL, wxID_ANY, _(L("Configuration Snapshots")), wxDefaultPosition, : DPIDialog(NULL, wxID_ANY, _(L("Configuration Snapshots")), wxDefaultPosition,
wxSize(45 * wxGetApp().em_unit(), 40 * wxGetApp().em_unit()), wxSize(45 * wxGetApp().em_unit(), 40 * wxGetApp().em_unit()),
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX) wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
{ {
this->SetFont(wxGetApp().normal_font());
this->SetBackgroundColour(*wxWHITE); this->SetBackgroundColour(*wxWHITE);
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
this->SetSizer(vsizer); this->SetSizer(vsizer);
// text // text
wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
{ {
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont font = wxGetApp().normal_font();//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
#ifdef __WXMSW__ #ifdef __WXMSW__
int size[] = {8,8,8,8,11,11,11}; const int fs = font.GetPointSize();
const int fs1 = static_cast<int>(0.8f*fs);
const int fs2 = static_cast<int>(1.1f*fs);
int size[] = {fs1, fs1, fs1, fs1, fs2, fs2, fs2};
// int size[] = {8,8,8,8,11,11,11};
#else #else
int size[] = {11,11,11,11,14,14,14}; int size[] = {11,11,11,11,14,14,14};
#endif #endif
@ -127,6 +132,26 @@ ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db
vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3); vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);
} }
void ConfigSnapshotDialog::on_dpi_changed(const wxRect &suggested_rect)
{
wxFont font = GetFont();
const int fs = font.GetPointSize();
const int fs1 = static_cast<int>(0.8f*fs);
const int fs2 = static_cast<int>(1.1f*fs);
int font_size[] = { fs1, fs1, fs1, fs1, fs2, fs2, fs2 };
html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size);
html->Refresh();
const int& em = em_unit();
const wxSize& size = wxSize(45 * em, 40 * em);
SetMinSize(size);
SetSize(size);
Refresh();
}
void ConfigSnapshotDialog::onLinkClicked(wxHtmlLinkEvent &event) void ConfigSnapshotDialog::onLinkClicked(wxHtmlLinkEvent &event)
{ {
m_snapshot_to_activate = event.GetLinkInfo().GetHref(); m_snapshot_to_activate = event.GetLinkInfo().GetHref();

View File

@ -2,6 +2,7 @@
#define slic3r_GUI_ConfigSnapshotDialog_hpp_ #define slic3r_GUI_ConfigSnapshotDialog_hpp_
#include "GUI.hpp" #include "GUI.hpp"
#include "GUI_Utils.hpp"
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/intl.h> #include <wx/intl.h>
@ -14,18 +15,23 @@ namespace Config {
class SnapshotDB; class SnapshotDB;
} }
class ConfigSnapshotDialog : public wxDialog class ConfigSnapshotDialog : public DPIDialog
{ {
public: public:
ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db, const wxString &id); ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db, const wxString &id);
const std::string& snapshot_to_activate() const { return m_snapshot_to_activate; } const std::string& snapshot_to_activate() const { return m_snapshot_to_activate; }
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private: private:
void onLinkClicked(wxHtmlLinkEvent &event); void onLinkClicked(wxHtmlLinkEvent &event);
void onCloseDialog(wxEvent &); void onCloseDialog(wxEvent &);
// If set, it contains a snapshot ID to be restored after the dialog closes. // If set, it contains a snapshot ID to be restored after the dialog closes.
std::string m_snapshot_to_activate; std::string m_snapshot_to_activate;
wxHtmlWindow* html;
}; };
} // namespace GUI } // namespace GUI

View File

@ -642,16 +642,21 @@ void PageTemperatures::apply_custom_config(DynamicPrintConfig &config)
ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent)
: wxPanel(parent) : wxPanel(parent)
// XXX: use create_scaled_bitmap: /* #ys_FIXME_delete_after_testing by VK
, bg(GUI::from_u8(Slic3r::var("Slic3r_192px_transparent.png")), wxBITMAP_TYPE_PNG) , bg(GUI::from_u8(Slic3r::var("Slic3r_192px_transparent.png")), wxBITMAP_TYPE_PNG)
, bullet_black(GUI::from_u8(Slic3r::var("bullet_black.png")), wxBITMAP_TYPE_PNG) , bullet_black(GUI::from_u8(Slic3r::var("bullet_black.png")), wxBITMAP_TYPE_PNG)
, bullet_blue(GUI::from_u8(Slic3r::var("bullet_blue.png")), wxBITMAP_TYPE_PNG) , bullet_blue(GUI::from_u8(Slic3r::var("bullet_blue.png")), wxBITMAP_TYPE_PNG)
, bullet_white(GUI::from_u8(Slic3r::var("bullet_white.png")), wxBITMAP_TYPE_PNG) , bullet_white(GUI::from_u8(Slic3r::var("bullet_white.png")), wxBITMAP_TYPE_PNG)
*/
, bg(ScalableBitmap(parent, "Slic3r_192px_transparent.png", 192))
, bullet_black(ScalableBitmap(parent, "bullet_black.png"))
, bullet_blue(ScalableBitmap(parent, "bullet_blue.png"))
, bullet_white(ScalableBitmap(parent, "bullet_white.png"))
, item_active(0) , item_active(0)
, item_hover(-1) , item_hover(-1)
, last_page((size_t)-1) , last_page((size_t)-1)
{ {
SetMinSize(bg.GetSize()); SetMinSize(bg.bmp().GetSize());
const wxSize size = GetTextExtent("m"); const wxSize size = GetTextExtent("m");
em_w = size.x; em_w = size.x;
@ -663,7 +668,10 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent)
// In some cases it didn't work at all. And so wxStaticBitmap is used here instead, // In some cases it didn't work at all. And so wxStaticBitmap is used here instead,
// because it has all the platform quirks figured out. // because it has all the platform quirks figured out.
auto *sizer = new wxBoxSizer(wxVERTICAL); auto *sizer = new wxBoxSizer(wxVERTICAL);
/* #ys_FIXME_delete_after_testing by VK
auto *logo = new wxStaticBitmap(this, wxID_ANY, bg); auto *logo = new wxStaticBitmap(this, wxID_ANY, bg);
*/
logo = new wxStaticBitmap(this, wxID_ANY, bg.bmp());
sizer->AddStretchSpacer(); sizer->AddStretchSpacer();
sizer->Add(logo); sizer->Add(logo);
SetSizer(sizer); SetSizer(sizer);
@ -771,8 +779,12 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
wxPaintDC dc(this); wxPaintDC dc(this);
/* #ys_FIXME_delete_after_testing by VK
const auto bullet_w = bullet_black.GetSize().GetWidth(); const auto bullet_w = bullet_black.GetSize().GetWidth();
const auto bullet_h = bullet_black.GetSize().GetHeight(); const auto bullet_h = bullet_black.GetSize().GetHeight();
*/
const auto bullet_w = bullet_black.bmp().GetSize().GetWidth();
const auto bullet_h = bullet_black.bmp().GetSize().GetHeight();
const int yoff_icon = bullet_h < em_h ? (em_h - bullet_h) / 2 : 0; const int yoff_icon = bullet_h < em_h ? (em_h - bullet_h) / 2 : 0;
const int yoff_text = bullet_h > em_h ? (bullet_h - em_h) / 2 : 0; const int yoff_text = bullet_h > em_h ? (bullet_h - em_h) / 2 : 0;
const int yinc = item_height(); const int yinc = item_height();
@ -785,10 +797,16 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
unsigned x = em_w/2 + item.indent * em_w; unsigned x = em_w/2 + item.indent * em_w;
if (i == item_active || item_hover >= 0 && i == (size_t)item_hover) { if (i == item_active || item_hover >= 0 && i == (size_t)item_hover) {
/*#ys_FIXME_delete_after_testing by VK
dc.DrawBitmap(bullet_blue, x, y + yoff_icon, false); dc.DrawBitmap(bullet_blue, x, y + yoff_icon, false);
} }
else if (i < item_active) { dc.DrawBitmap(bullet_black, x, y + yoff_icon, false); } else if (i < item_active) { dc.DrawBitmap(bullet_black, x, y + yoff_icon, false); }
else if (i > item_active) { dc.DrawBitmap(bullet_white, x, y + yoff_icon, false); } else if (i > item_active) { dc.DrawBitmap(bullet_white, x, y + yoff_icon, false); }
*/
dc.DrawBitmap(bullet_blue.bmp(), x, y + yoff_icon, false);
}
else if (i < item_active) { dc.DrawBitmap(bullet_black.bmp(), x, y + yoff_icon, false); }
else if (i > item_active) { dc.DrawBitmap(bullet_white.bmp(), x, y + yoff_icon, false); }
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);
@ -821,6 +839,18 @@ void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt)
evt.Skip(); evt.Skip();
} }
void ConfigWizardIndex::msw_rescale()
{
bg.msw_rescale();
SetMinSize(bg.bmp().GetSize());
logo->SetBitmap(bg.bmp());
bullet_black.msw_rescale();
bullet_blue.msw_rescale();
bullet_white.msw_rescale();
Refresh();
}
// priv // priv
@ -995,9 +1025,10 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
// Public // Public
ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason)
: wxDialog(parent, wxID_ANY, _(name().ToStdString()), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) : DPIDialog(parent, wxID_ANY, _(name().ToStdString()), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, p(new priv(this)) , p(new priv(this))
{ {
this->SetFont(wxGetApp().normal_font());
p->run_reason = reason; p->run_reason = reason;
p->load_vendors(); p->load_vendors();
@ -1141,5 +1172,11 @@ const wxString& ConfigWizard::name(const bool from_menu/* = false*/)
return from_menu ? config_wizard_name_menu : config_wizard_name; return from_menu ? config_wizard_name_menu : config_wizard_name;
} }
void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect)
{
p->index->msw_rescale();
Refresh();
}
} }
} }

View File

@ -5,6 +5,8 @@
#include <wx/dialog.h> #include <wx/dialog.h>
#include "GUI_Utils.hpp"
namespace Slic3r { namespace Slic3r {
class PresetBundle; class PresetBundle;
@ -13,7 +15,7 @@ class PresetUpdater;
namespace GUI { namespace GUI {
class ConfigWizard: public wxDialog class ConfigWizard: public DPIDialog
{ {
public: public:
// Why is the Wizard run // Why is the Wizard run
@ -35,6 +37,10 @@ public:
bool run(PresetBundle *preset_bundle, const PresetUpdater *updater); bool run(PresetBundle *preset_bundle, const PresetUpdater *updater);
static const wxString& name(const bool from_menu = false); static const wxString& name(const bool from_menu = false);
protected:
void on_dpi_changed(const wxRect &suggested_rect) override ;
private: private:
struct priv; struct priv;
std::unique_ptr<priv> p; std::unique_ptr<priv> p;

View File

@ -210,6 +210,7 @@ public:
void go_to(ConfigWizardPage *page); void go_to(ConfigWizardPage *page);
void clear(); void clear();
void msw_rescale();
int em() const { return em_w; } int em() const { return em_w; }
private: private:
@ -224,18 +225,27 @@ private:
int em_w; int em_w;
int em_h; int em_h;
/* #ys_FIXME_delete_after_testing by VK
const wxBitmap bg; const wxBitmap bg;
const wxBitmap bullet_black; const wxBitmap bullet_black;
const wxBitmap bullet_blue; const wxBitmap bullet_blue;
const wxBitmap bullet_white; const wxBitmap bullet_white;
*/
ScalableBitmap bg;
ScalableBitmap bullet_black;
ScalableBitmap bullet_blue;
ScalableBitmap bullet_white;
wxStaticBitmap* logo;
std::vector<Item> items; std::vector<Item> items;
size_t item_active; size_t item_active;
ssize_t item_hover; ssize_t item_hover;
size_t last_page; size_t last_page;
/* #ys_FIXME_delete_after_testing by VK
int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em_w) + em_w; } int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em_w) + em_w; }
*/
int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em_w) + em_w; }
void on_paint(wxPaintEvent &evt); void on_paint(wxPaintEvent &evt);
void on_mouse_move(wxMouseEvent &evt); void on_mouse_move(wxMouseEvent &evt);

View File

@ -33,21 +33,11 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/)
void Field::PostInitialize() void Field::PostInitialize()
{ {
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); m_Undo_btn = new RevertButton(m_parent, "bullet_white.png");
m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); m_Undo_to_sys_btn = new RevertButton(m_parent, "bullet_white.png");
if (wxMSW) {
m_Undo_btn->SetBackgroundColour(color);
m_Undo_btn->SetBackgroundStyle(wxBG_STYLE_PAINT);
m_Undo_to_sys_btn->SetBackgroundColour(color);
m_Undo_to_sys_btn->SetBackgroundStyle(wxBG_STYLE_PAINT);
}
m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); }));
m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); }));
//set default bitmap m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); }));
wxBitmap bmp = create_scaled_bitmap(m_parent, "bullet_white.png"); m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); }));
set_undo_bitmap(&bmp);
set_undo_to_sys_bitmap(&bmp);
switch (m_opt.type) switch (m_opt.type)
{ {
@ -65,6 +55,9 @@ void Field::PostInitialize()
break; break;
} }
// initialize m_unit_value
m_em_unit = em_unit(m_parent);
BUILD(); BUILD();
} }
@ -212,8 +205,8 @@ bool is_defined_input_value(wxWindow* win, const ConfigOptionType& type)
void TextCtrl::BUILD() { void TextCtrl::BUILD() {
auto size = wxSize(wxDefaultSize); auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
wxString text_value = wxString(""); wxString text_value = wxString("");
@ -357,6 +350,21 @@ boost::any& TextCtrl::get_value()
return m_value; return m_value;
} }
void TextCtrl::msw_rescale()
{
Field::msw_rescale();
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
if (size != wxDefaultSize)
{
wxTextCtrl* field = dynamic_cast<wxTextCtrl*>(window);
field->SetMinSize(size);
}
}
void TextCtrl::enable() { dynamic_cast<wxTextCtrl*>(window)->Enable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(true); } void TextCtrl::enable() { dynamic_cast<wxTextCtrl*>(window)->Enable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(true); }
void TextCtrl::disable() { dynamic_cast<wxTextCtrl*>(window)->Disable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(false); } void TextCtrl::disable() { dynamic_cast<wxTextCtrl*>(window)->Disable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(false); }
@ -379,7 +387,8 @@ void CheckBox::BUILD() {
static_cast<const ConfigOptionBools*>(m_opt.default_value)->get_at(m_opt_idx) : static_cast<const ConfigOptionBools*>(m_opt.default_value)->get_at(m_opt_idx) :
false; false;
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); // Set Label as a string of at least one space simbol to correct system scaling of a CheckBox
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size);
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
temp->SetValue(check_value); temp->SetValue(check_value);
@ -408,8 +417,8 @@ int undef_spin_val = -9999; //! Probably, It's not necessary
void SpinCtrl::BUILD() { void SpinCtrl::BUILD() {
auto size = wxSize(wxDefaultSize); auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
wxString text_value = wxString(""); wxString text_value = wxString("");
int default_value = 0; int default_value = 0;
@ -504,10 +513,18 @@ void SpinCtrl::propagate_value()
on_change_field(); on_change_field();
} }
void SpinCtrl::msw_rescale()
{
Field::msw_rescale();
wxSpinCtrl* field = dynamic_cast<wxSpinCtrl*>(window);
field->SetMinSize(wxSize(-1, int(1.9f*field->GetFont().GetPixelSize().y)));
}
void Choice::BUILD() { void Choice::BUILD() {
wxSize size(15 * wxGetApp().em_unit(), -1); wxSize size(m_width * m_em_unit, -1);
if (m_opt.height >= 0) size.SetHeight(m_opt.height); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
wxBitmapComboBox* temp; wxBitmapComboBox* temp;
if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) { if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) {
@ -816,11 +833,53 @@ boost::any& Choice::get_value()
return m_value; return m_value;
} }
void Choice::msw_rescale()
{
Field::msw_rescale();
wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window);
const wxString selection = field->GetString(field->GetSelection());
/* To correct scaling (set new controll size) of a wxBitmapCombobox
* we need to refill control with new bitmaps. So, in our case :
* 1. clear conrol
* 2. add content
* 3. add scaled "empty" bitmap to the at least one item
*/
field->Clear();
wxSize size(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height * m_em_unit);
size.SetWidth((m_opt.width > 0 ? m_opt.width : m_width) * m_em_unit);
field->SetSize(size);
size_t idx, counter = idx = 0;
if (m_opt.enum_labels.empty() && m_opt.enum_values.empty()) {}
else{
for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels) {
const wxString& str = _(el);
field->Append(str);
if (el.compare(selection) == 0)
idx = counter;
++counter;
}
}
wxBitmap empty_bmp(1, field->GetFont().GetPixelSize().y + 2);
empty_bmp.SetWidth(0);
field->SetItemBitmap(0, empty_bmp);
idx == m_opt.enum_values.size() ?
field->SetValue(selection) :
field->SetSelection(idx);
}
void ColourPicker::BUILD() void ColourPicker::BUILD()
{ {
auto size = wxSize(wxDefaultSize); auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
// Validate the color // Validate the color
wxString clr_str(static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx)); wxString clr_str(static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx));
@ -855,7 +914,7 @@ void PointCtrl::BUILD()
{ {
auto temp = new wxBoxSizer(wxHORIZONTAL); auto temp = new wxBoxSizer(wxHORIZONTAL);
const wxSize field_size(4 * wxGetApp().em_unit(), -1); const wxSize field_size(4 * m_em_unit, -1);
auto default_pt = static_cast<const ConfigOptionPoints*>(m_opt.default_value)->values.at(0); auto default_pt = static_cast<const ConfigOptionPoints*>(m_opt.default_value)->values.at(0);
double val = default_pt(0); double val = default_pt(0);
@ -898,6 +957,16 @@ void PointCtrl::BUILD()
y_textctrl->SetToolTip(get_tooltip_text(X+", "+Y)); y_textctrl->SetToolTip(get_tooltip_text(X+", "+Y));
} }
void PointCtrl::msw_rescale()
{
Field::msw_rescale();
const wxSize field_size(4 * m_em_unit, -1);
x_textctrl->SetMinSize(field_size);
y_textctrl->SetMinSize(field_size);
}
void PointCtrl::propagate_value(wxTextCtrl* win) void PointCtrl::propagate_value(wxTextCtrl* win)
{ {
if (!win->GetValue().empty()) if (!win->GetValue().empty())
@ -943,8 +1012,8 @@ boost::any& PointCtrl::get_value()
void StaticText::BUILD() void StaticText::BUILD()
{ {
auto size = wxSize(wxDefaultSize); auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value); const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value);
auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE);
@ -958,6 +1027,21 @@ void StaticText::BUILD()
temp->SetToolTip(get_tooltip_text(legend)); temp->SetToolTip(get_tooltip_text(legend));
} }
void StaticText::msw_rescale()
{
Field::msw_rescale();
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
if (size != wxDefaultSize)
{
wxStaticText* field = dynamic_cast<wxStaticText*>(window);
field->SetSize(size);
}
}
void SliderCtrl::BUILD() void SliderCtrl::BUILD()
{ {
auto size = wxSize(wxDefaultSize); auto size = wxSize(wxDefaultSize);

View File

@ -19,6 +19,7 @@
#include "libslic3r/Utils.hpp" #include "libslic3r/Utils.hpp"
#include "GUI.hpp" #include "GUI.hpp"
#include "wxExtensions.hpp"
#ifdef __WXMSW__ #ifdef __WXMSW__
#define wxMSW true #define wxMSW true
@ -36,19 +37,24 @@ using t_back_to_init = std::function<void(const std::string&)>;
wxString double_to_string(double const value, const int max_precision = 4); wxString double_to_string(double const value, const int max_precision = 4);
class MyButton : public wxButton class RevertButton : public ScalableButton
{ {
bool hidden = false; // never show button if it's hidden ones bool hidden = false; // never show button if it's hidden ones
public: public:
MyButton() {} // RevertButton() {}
MyButton(wxWindow* parent, wxWindowID id, const wxString& label = wxEmptyString, // RevertButton(wxWindow* parent, wxWindowID id, const wxString& label = wxEmptyString,
const wxPoint& pos = wxDefaultPosition, // const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = 0, // const wxSize& size = wxDefaultSize, long style = 0,
const wxValidator& validator = wxDefaultValidator, // const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxTextCtrlNameStr) // const wxString& name = wxTextCtrlNameStr)
{ // {
this->Create(parent, id, label, pos, size, style, validator, name); // this->Create(parent, id, label, pos, size, style, validator, name);
} // }
RevertButton(
wxWindow *parent,
const std::string& icon_name = ""
) :
ScalableButton(parent, wxID_ANY, icon_name) {}
// overridden from wxWindow base class // overridden from wxWindow base class
virtual bool virtual bool
@ -154,19 +160,19 @@ public:
return std::move(p); //!p; return std::move(p); //!p;
} }
bool set_undo_bitmap(const wxBitmap *bmp) { bool set_undo_bitmap(const ScalableBitmap *bmp) {
if (m_undo_bitmap != bmp) { if (m_undo_bitmap != bmp) {
m_undo_bitmap = bmp; m_undo_bitmap = bmp;
m_Undo_btn->SetBitmap(*bmp); m_Undo_btn->SetBitmap_(*bmp);
return true; return true;
} }
return false; return false;
} }
bool set_undo_to_sys_bitmap(const wxBitmap *bmp) { bool set_undo_to_sys_bitmap(const ScalableBitmap *bmp) {
if (m_undo_to_sys_bitmap != bmp) { if (m_undo_to_sys_bitmap != bmp) {
m_undo_to_sys_bitmap = bmp; m_undo_to_sys_bitmap = bmp;
m_Undo_to_sys_btn->SetBitmap(*bmp); m_Undo_to_sys_btn->SetBitmap_(*bmp);
return true; return true;
} }
return false; return false;
@ -211,15 +217,23 @@ public:
m_side_text = side_text; m_side_text = side_text;
} }
virtual void msw_rescale() {
m_Undo_to_sys_btn->msw_rescale();
m_Undo_btn->msw_rescale();
// update em_unit value
m_em_unit = em_unit(m_parent);
}
protected: protected:
MyButton* m_Undo_btn = nullptr; RevertButton* m_Undo_btn = nullptr;
// Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. // Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
const wxBitmap* m_undo_bitmap = nullptr; const ScalableBitmap* m_undo_bitmap = nullptr;
const wxString* m_undo_tooltip = nullptr; const wxString* m_undo_tooltip = nullptr;
MyButton* m_Undo_to_sys_btn = nullptr; RevertButton* m_Undo_to_sys_btn = nullptr;
// Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. // Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
const wxBitmap* m_undo_to_sys_bitmap = nullptr; const ScalableBitmap* m_undo_to_sys_bitmap = nullptr;
const wxString* m_undo_to_sys_tooltip = nullptr; const wxString* m_undo_to_sys_tooltip = nullptr;
wxStaticText* m_Label = nullptr; wxStaticText* m_Label = nullptr;
// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one. // Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
@ -230,6 +244,8 @@ protected:
// current value // current value
boost::any m_value; boost::any m_value;
int m_em_unit;
bool bEnterPressed = false; bool bEnterPressed = false;
friend class OptionsGroup; friend class OptionsGroup;
@ -274,6 +290,8 @@ public:
boost::any& get_value() override; boost::any& get_value() override;
void msw_rescale() override;
virtual void enable(); virtual void enable();
virtual void disable(); virtual void disable();
virtual wxWindow* getWindow() { return window; } virtual wxWindow* getWindow() { return window; }
@ -337,6 +355,8 @@ public:
return m_value = tmp_value; return m_value = tmp_value;
} }
void msw_rescale() override;
void enable() override { dynamic_cast<wxSpinCtrl*>(window)->Enable(); } void enable() override { dynamic_cast<wxSpinCtrl*>(window)->Enable(); }
void disable() override { dynamic_cast<wxSpinCtrl*>(window)->Disable(); } void disable() override { dynamic_cast<wxSpinCtrl*>(window)->Disable(); }
wxWindow* getWindow() override { return window; } wxWindow* getWindow() override { return window; }
@ -344,6 +364,7 @@ public:
class Choice : public Field { class Choice : public Field {
using Field::Field; using Field::Field;
int m_width{ 15 };
public: public:
Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {} Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {} Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
@ -363,6 +384,8 @@ public:
void set_values(const std::vector<std::string> &values); void set_values(const std::vector<std::string> &values);
boost::any& get_value() override; boost::any& get_value() override;
void msw_rescale() override;
void enable() override { dynamic_cast<wxBitmapComboBox*>(window)->Enable(); }; void enable() override { dynamic_cast<wxBitmapComboBox*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxBitmapComboBox*>(window)->Disable(); }; void disable() override{ dynamic_cast<wxBitmapComboBox*>(window)->Disable(); };
wxWindow* getWindow() override { return window; } wxWindow* getWindow() override { return window; }
@ -414,6 +437,8 @@ public:
void set_value(const boost::any& value, bool change_event = false); void set_value(const boost::any& value, bool change_event = false);
boost::any& get_value() override; boost::any& get_value() override;
void msw_rescale() override;
void enable() override { void enable() override {
x_textctrl->Enable(); x_textctrl->Enable();
y_textctrl->Enable(); } y_textctrl->Enable(); }
@ -446,6 +471,8 @@ public:
boost::any& get_value()override { return m_value; } boost::any& get_value()override { return m_value; }
void msw_rescale() override;
void enable() override { dynamic_cast<wxStaticText*>(window)->Enable(); }; void enable() override { dynamic_cast<wxStaticText*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxStaticText*>(window)->Disable(); }; void disable() override{ dynamic_cast<wxStaticText*>(window)->Disable(); };
wxWindow* getWindow() override { return window; } wxWindow* getWindow() override { return window; }

View File

@ -732,7 +732,7 @@ const char* FirmwareDialog::priv::avr109_dev_name(Avr109Pid usb_pid) {
// Public // Public
FirmwareDialog::FirmwareDialog(wxWindow *parent) : FirmwareDialog::FirmwareDialog(wxWindow *parent) :
wxDialog(parent, wxID_ANY, _(L("Firmware flasher")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), GUI::DPIDialog(parent, wxID_ANY, _(L("Firmware flasher")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
p(new priv(this)) p(new priv(this))
{ {
enum { enum {
@ -748,7 +748,13 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
int min_height = MIN_HEIGHT * em; int min_height = MIN_HEIGHT * em;
int min_height_expanded = MIN_HEIGHT_EXPANDED * em; int min_height_expanded = MIN_HEIGHT_EXPANDED * em;
wxFont status_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); /* get current font from application,
* because of wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) function
* returns font for primary Display
*/
const wxFont& font = GUI::wxGetApp().normal_font();
SetFont(font);
wxFont status_font = font;//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
status_font.MakeBold(); status_font.MakeBold();
wxFont mono_font(wxFontInfo().Family(wxFONTFAMILY_TELETYPE)); wxFont mono_font(wxFontInfo().Family(wxFONTFAMILY_TELETYPE));
mono_font.MakeSmaller(); mono_font.MakeSmaller();

View File

@ -4,12 +4,13 @@
#include <memory> #include <memory>
#include <wx/dialog.h> #include <wx/dialog.h>
#include "GUI_Utils.hpp"
namespace Slic3r { namespace Slic3r {
class FirmwareDialog: public wxDialog class FirmwareDialog: public GUI::DPIDialog
{ {
public: public:
FirmwareDialog(wxWindow *parent); FirmwareDialog(wxWindow *parent);
@ -20,6 +21,9 @@ public:
~FirmwareDialog(); ~FirmwareDialog();
static void run(wxWindow *parent); static void run(wxWindow *parent);
protected:
void on_dpi_changed(const wxRect &suggested_rect) override{;}
private: private:
struct priv; struct priv;
std::unique_ptr<priv> p; std::unique_ptr<priv> p;

View File

@ -706,6 +706,7 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool
m_warnings.erase(it); m_warnings.erase(it);
if (m_warnings.empty()) { // nothing remains to be shown if (m_warnings.empty()) { // nothing remains to be shown
reset(); reset();
m_msg_text = "";// save information for rescaling
return; return;
} }
} }
@ -726,6 +727,10 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool
} }
_generate(text, canvas, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...) _generate(text, canvas, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...)
// save information for rescaling
m_msg_text = text;
m_is_colored_red = red_colored;
} }
@ -794,7 +799,9 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GL
wxMemoryDC memDC; wxMemoryDC memDC;
// select default font // select default font
const float scale = canvas.get_canvas_size().get_scale_factor(); const float scale = canvas.get_canvas_size().get_scale_factor();
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale); // wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale);
wxFont font = wxGetApp().normal_font();//! #ys_FIXME_experiment
font.MakeLarger(); font.MakeLarger();
font.MakeBold(); font.MakeBold();
memDC.SetFont(font); memDC.SetFont(font);
@ -895,6 +902,14 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
} }
} }
void GLCanvas3D::WarningTexture::rescale(const GLCanvas3D& canvas)
{
if (m_msg_text.empty())
return;
_generate(m_msg_text, canvas, m_is_colored_red);
}
const unsigned char GLCanvas3D::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 }; const unsigned char GLCanvas3D::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 };
const unsigned char GLCanvas3D::LegendTexture::Default_Background_Color[3] = { (unsigned char)(DEFAULT_BG_LIGHT_COLOR[0] * 255.0f), (unsigned char)(DEFAULT_BG_LIGHT_COLOR[1] * 255.0f), (unsigned char)(DEFAULT_BG_LIGHT_COLOR[2] * 255.0f) }; const unsigned char GLCanvas3D::LegendTexture::Default_Background_Color[3] = { (unsigned char)(DEFAULT_BG_LIGHT_COLOR[0] * 255.0f), (unsigned char)(DEFAULT_BG_LIGHT_COLOR[1] * 255.0f), (unsigned char)(DEFAULT_BG_LIGHT_COLOR[2] * 255.0f) };
const unsigned char GLCanvas3D::LegendTexture::Error_Background_Color[3] = { (unsigned char)(ERROR_BG_LIGHT_COLOR[0] * 255.0f), (unsigned char)(ERROR_BG_LIGHT_COLOR[1] * 255.0f), (unsigned char)(ERROR_BG_LIGHT_COLOR[2] * 255.0f) }; const unsigned char GLCanvas3D::LegendTexture::Error_Background_Color[3] = { (unsigned char)(ERROR_BG_LIGHT_COLOR[0] * 255.0f), (unsigned char)(ERROR_BG_LIGHT_COLOR[1] * 255.0f), (unsigned char)(ERROR_BG_LIGHT_COLOR[2] * 255.0f) };
@ -965,7 +980,8 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
const int scaled_border = Px_Border * scale; const int scaled_border = Px_Border * scale;
// select default font // select default font
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); // wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl);
wxFont font = wxGetApp().normal_font();//! #ys_FIXME_experiment
#ifdef __WXMSW__ #ifdef __WXMSW__
// Disabling ClearType works, but the font returned is very different (much thicker) from the default. // Disabling ClearType works, but the font returned is very different (much thicker) from the default.
// msw_disable_cleartype(font); // msw_disable_cleartype(font);
@ -3285,6 +3301,11 @@ void GLCanvas3D::set_cursor(ECursorType type)
} }
} }
void GLCanvas3D::msw_rescale()
{
m_warning_texture.rescale(*this);
}
bool GLCanvas3D::_is_shown_on_screen() const bool GLCanvas3D::_is_shown_on_screen() const
{ {
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
@ -4009,7 +4030,8 @@ void GLCanvas3D::_render_gizmos_overlay() const
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor()); m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor());
#else #else
m_gizmos.set_overlay_scale(m_canvas->GetContentScaleFactor()); // m_gizmos.set_overlay_scale(m_canvas->GetContentScaleFactor());
m_gizmos.set_overlay_scale(wxGetApp().em_unit()*0.1f);//! #ys_FIXME_experiment
#endif /* __WXMSW__ */ #endif /* __WXMSW__ */
m_gizmos.render_overlay(*this, m_selection); m_gizmos.render_overlay(*this, m_selection);
@ -4021,7 +4043,8 @@ void GLCanvas3D::_render_toolbar() const
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
m_toolbar.set_scale(m_retina_helper->get_scale_factor()); m_toolbar.set_scale(m_retina_helper->get_scale_factor());
#else #else
m_toolbar.set_scale(m_canvas->GetContentScaleFactor()); // m_toolbar.set_scale(m_canvas->GetContentScaleFactor());
m_toolbar.set_scale(wxGetApp().em_unit()*0.1f);//! #ys_FIXME_experiment
#endif // ENABLE_RETINA_GL #endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size(); Size cnv_size = get_canvas_size();
@ -4084,7 +4107,8 @@ void GLCanvas3D::_render_view_toolbar() const
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
m_view_toolbar.set_scale(m_retina_helper->get_scale_factor()); m_view_toolbar.set_scale(m_retina_helper->get_scale_factor());
#else #else
m_view_toolbar.set_scale(m_canvas->GetContentScaleFactor()); // m_view_toolbar.set_scale(m_canvas->GetContentScaleFactor());
m_view_toolbar.set_scale(wxGetApp().em_unit()*0.1f); //! #ys_FIXME_experiment
#endif // ENABLE_RETINA_GL #endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size(); Size cnv_size = get_canvas_size();

View File

@ -352,6 +352,9 @@ class GLCanvas3D
void activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas); void activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas);
void render(const GLCanvas3D& canvas) const; void render(const GLCanvas3D& canvas) const;
// function used to get an information for rescaling of the warning
void rescale(const GLCanvas3D& canvas);
private: private:
static const unsigned char Background_Color[3]; static const unsigned char Background_Color[3];
static const unsigned char Opacity; static const unsigned char Opacity;
@ -359,6 +362,10 @@ class GLCanvas3D
int m_original_width; int m_original_width;
int m_original_height; int m_original_height;
// information for rescaling of the warning legend
std::string m_msg_text = "";
bool m_is_colored_red{false};
// Information about which warnings are currently active. // Information about which warnings are currently active.
std::vector<Warning> m_warnings; std::vector<Warning> m_warnings;
@ -612,6 +619,7 @@ public:
double get_size_proportional_to_max_bed_size(double factor) const; double get_size_proportional_to_max_bed_size(double factor) const;
void set_cursor(ECursorType type); void set_cursor(ECursorType type);
void msw_rescale();
private: private:
bool _is_shown_on_screen() const; bool _is_shown_on_screen() const;

View File

@ -325,6 +325,17 @@ void GUI_App::init_fonts()
#endif /*__WXMAC__*/ #endif /*__WXMAC__*/
} }
void GUI_App::update_fonts()
{
/* Only normal and bold fonts are used for an application rescale,
* because of under MSW small and normal fonts are the same.
* To avoid same rescaling twice, just fill this values
* from rescaled MainFrame
*/
m_normal_font = mainframe->normal_font();
m_bold_font = mainframe->normal_font().Bold();
}
void GUI_App::set_label_clr_modified(const wxColour& clr) { void GUI_App::set_label_clr_modified(const wxColour& clr) {
m_color_label_modified = clr; m_color_label_modified = clr;
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue()); auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue());
@ -669,6 +680,12 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
// Take a configuration snapshot. // Take a configuration snapshot.
if (check_unsaved_changes()) { if (check_unsaved_changes()) {
wxTextEntryDialog dlg(nullptr, _(L("Taking configuration snapshot")), _(L("Snapshot name"))); wxTextEntryDialog dlg(nullptr, _(L("Taking configuration snapshot")), _(L("Snapshot name")));
// set current normal font for dialog children,
// because of just dlg.SetFont(normal_font()) has no result;
for (auto child : dlg.GetChildren())
child->SetFont(normal_font());
if (dlg.ShowModal() == wxID_OK) if (dlg.ShowModal() == wxID_OK)
app_config->set("on_snapshot", app_config->set("on_snapshot",
Slic3r::GUI::Config::SnapshotDB::singleton().take_snapshot( Slic3r::GUI::Config::SnapshotDB::singleton().take_snapshot(
@ -718,7 +735,6 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
get_installed_languages(names, identifiers); get_installed_languages(names, identifiers);
if (select_language(names, identifiers)) { if (select_language(names, identifiers)) {
save_language(); save_language();
// show_info(mainframe->m_tabpanel, _(L("Application will be restarted")), _(L("Attention!")));
_3DScene::remove_all_canvases();// remove all canvas before recreate GUI _3DScene::remove_all_canvases();// remove all canvas before recreate GUI
recreate_GUI(); recreate_GUI();
} }

View File

@ -98,6 +98,7 @@ public:
void init_label_colours(); void init_label_colours();
void update_label_colours_from_appconfig(); void update_label_colours_from_appconfig();
void init_fonts(); void init_fonts();
void update_fonts();
void set_label_clr_modified(const wxColour& clr); void set_label_clr_modified(const wxColour& clr);
void set_label_clr_sys(const wxColour& clr); void set_label_clr_sys(const wxColour& clr);

View File

@ -163,7 +163,7 @@ void ObjectList::create_objects_ctrl()
m_sizer = new wxBoxSizer(wxVERTICAL); m_sizer = new wxBoxSizer(wxVERTICAL);
m_sizer->Add(this, 1, wxGROW); m_sizer->Add(this, 1, wxGROW);
m_objects_model = new PrusaObjectDataViewModel; m_objects_model = new ObjectDataViewModel;
AssociateModel(m_objects_model); AssociateModel(m_objects_model);
m_objects_model->SetAssociatedControl(this); m_objects_model->SetAssociatedControl(this);
#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE #if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
@ -173,7 +173,7 @@ void ObjectList::create_objects_ctrl()
// column 0(Icon+Text) of the view control: // column 0(Icon+Text) of the view control:
// And Icon can be consisting of several bitmaps // And Icon can be consisting of several bitmaps
AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(), AppendColumn(new wxDataViewColumn(_(L("Name")), new BitmapTextRenderer(),
0, 20*wxGetApp().em_unit()/*200*/, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); 0, 20*wxGetApp().em_unit()/*200*/, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE));
// column 1 of the view control: // column 1 of the view control:
@ -203,7 +203,7 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt)
if (col->GetTitle() == " " && GetSelectedItemsCount()<2) if (col->GetTitle() == " " && GetSelectedItemsCount()<2)
GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings"))); GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings")));
else if (col->GetTitle() == _("Name") && else if (col->GetTitle() == _("Name") &&
m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData()) { m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.bmp().GetRefData()) {
int obj_idx = m_objects_model->GetIdByItem(item); int obj_idx = m_objects_model->GetIdByItem(item);
auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats; auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats;
int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
@ -395,27 +395,71 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const
void ObjectList::init_icons() void ObjectList::init_icons()
{ {
m_bmp_modifiermesh = create_scaled_bitmap(nullptr, "add_modifier"); m_bmp_modifiermesh = ScalableBitmap(nullptr, "add_modifier"); // Add part
m_bmp_solidmesh = create_scaled_bitmap(nullptr, "add_part"); m_bmp_solidmesh = ScalableBitmap(nullptr, "add_part"); // Add modifier
m_bmp_support_enforcer = create_scaled_bitmap(nullptr, "support_enforcer"); m_bmp_support_enforcer = ScalableBitmap(nullptr, "support_enforcer");// Add support enforcer
m_bmp_support_blocker = create_scaled_bitmap(nullptr, "support_blocker"); m_bmp_support_blocker = ScalableBitmap(nullptr, "support_blocker"); // Add support blocker
m_bmp_vector.reserve(4); // bitmaps for different types of parts m_bmp_vector.reserve(4); // bitmaps for different types of parts
m_bmp_vector.push_back(&m_bmp_solidmesh); // Add part m_bmp_vector.push_back(&m_bmp_solidmesh.bmp());
m_bmp_vector.push_back(&m_bmp_modifiermesh); // Add modifier m_bmp_vector.push_back(&m_bmp_modifiermesh.bmp());
m_bmp_vector.push_back(&m_bmp_support_enforcer); // Add support enforcer m_bmp_vector.push_back(&m_bmp_support_enforcer.bmp());
m_bmp_vector.push_back(&m_bmp_support_blocker); // Add support blocker m_bmp_vector.push_back(&m_bmp_support_blocker.bmp());
// Set volumes default bitmaps for the model
m_objects_model->SetVolumeBitmaps(m_bmp_vector); m_objects_model->SetVolumeBitmaps(m_bmp_vector);
// init icon for manifold warning // init icon for manifold warning
m_bmp_manifold_warning = create_scaled_bitmap(nullptr, "exclamation"); m_bmp_manifold_warning = ScalableBitmap(nullptr, "exclamation");
// init bitmap for "Split to sub-objects" context menu // init bitmap for "Split to sub-objects" context menu
m_bmp_split = create_scaled_bitmap(nullptr, "split_parts_SMALL"); m_bmp_split = ScalableBitmap(nullptr, "split_parts_SMALL");
// init bitmap for "Add Settings" context menu // init bitmap for "Add Settings" context menu
m_bmp_cog = create_scaled_bitmap(nullptr, "cog"); m_bmp_cog = ScalableBitmap(nullptr, "cog");
}
void ObjectList::rescale_icons()
{
m_bmp_vector.clear();
m_bmp_vector.reserve(4); // bitmaps for different types of parts
for (ScalableBitmap* bitmap : std::vector<ScalableBitmap*> {
&m_bmp_modifiermesh, // Add part
&m_bmp_solidmesh, // Add modifier
&m_bmp_support_enforcer, // Add support enforcer
&m_bmp_support_blocker }) // Add support blocker
{
bitmap->msw_rescale();
m_bmp_vector.push_back(& bitmap->bmp());
}
// Set volumes default bitmaps for the model
m_objects_model->SetVolumeBitmaps(m_bmp_vector);
m_bmp_manifold_warning.msw_rescale();
m_bmp_split.msw_rescale();
m_bmp_cog.msw_rescale();
// Update CATEGORY_ICON according to new scale
{
// Note: `this` isn't passed to create_scaled_bitmap() here because of bugs in the widget,
// see note in PresetBundle::load_compatible_bitmaps()
// ptFFF
CATEGORY_ICON[L("Layers and Perimeters")] = create_scaled_bitmap(nullptr, "layers");
CATEGORY_ICON[L("Infill")] = create_scaled_bitmap(nullptr, "infill");
CATEGORY_ICON[L("Support material")] = create_scaled_bitmap(nullptr, "support");
CATEGORY_ICON[L("Speed")] = create_scaled_bitmap(nullptr, "time");
CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap(nullptr, "funnel");
CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap(nullptr, "funnel");
// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap(nullptr, "skirt+brim");
// CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap(nullptr, "time");
CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap(nullptr, "wrench");
// ptSLA
CATEGORY_ICON[L("Supports")] = create_scaled_bitmap(nullptr, "support"/*"sla_supports"*/);
CATEGORY_ICON[L("Pad")] = create_scaled_bitmap(nullptr, "pad");
}
} }
@ -463,8 +507,7 @@ void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& vol
items.Add(vol_item); items.Add(vol_item);
} }
m_parts_changed = true; changed_object(obj_idx);
parts_changed(obj_idx);
if (items.size() > 1) if (items.size() > 1)
{ {
@ -490,9 +533,7 @@ void ObjectList::paste_objects_into_list(const std::vector<size_t>& object_idxs)
items.Add(m_objects_model->GetItemById(object)); items.Add(m_objects_model->GetItemById(object));
} }
m_parts_changed = true;
wxGetApp().plater()->changed_objects(object_idxs); wxGetApp().plater()->changed_objects(object_idxs);
m_parts_changed = false;
select_items(items); select_items(items);
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
@ -534,7 +575,7 @@ void ObjectList::OnContextMenu(wxDataViewEvent&)
if (title == " ") if (title == " ")
show_context_menu(); show_context_menu();
else if (title == _("Name") && pt.x >15 && else if (title == _("Name") && pt.x >15 &&
m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData()) m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.bmp().GetRefData())
{ {
if (is_windows10()) if (is_windows10())
fix_through_netfabb(); fix_through_netfabb();
@ -703,8 +744,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
select_item(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id, select_item(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id,
m_objects_model->GetParent(item))); m_objects_model->GetParent(item)));
m_parts_changed = true; changed_object(m_dragged_data.obj_idx());
parts_changed(m_dragged_data.obj_idx());
m_dragged_data.clear(); m_dragged_data.clear();
} }
@ -1000,12 +1040,12 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu) wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu)
{ {
return append_menu_item(menu, wxID_ANY, _(L("Split to parts")), "", return append_menu_item(menu, wxID_ANY, _(L("Split to parts")), "",
[this](wxCommandEvent&) { split(); }, m_bmp_split, menu); [this](wxCommandEvent&) { split(); }, m_bmp_split.bmp(), menu);
} }
wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
{ {
PrusaMenu* menu = dynamic_cast<PrusaMenu*>(menu_); MenuWithSeparators* menu = dynamic_cast<MenuWithSeparators*>(menu_);
const wxString menu_name = _(L("Add settings")); const wxString menu_name = _(L("Add settings"));
// Delete old items from settings popupmenu // Delete old items from settings popupmenu
@ -1053,7 +1093,7 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
if (printer_technology() == ptFFF || if (printer_technology() == ptFFF ||
menu->GetMenuItems().size() > 0 && !menu->GetMenuItems().back()->IsSeparator()) menu->GetMenuItems().size() > 0 && !menu->GetMenuItems().back()->IsSeparator())
menu->m_separator_frst = menu->AppendSeparator(); menu->SetFirstSeparator();
// Add frequently settings // Add frequently settings
create_freq_settings_popupmenu(menu); create_freq_settings_popupmenu(menu);
@ -1061,11 +1101,11 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
if (mode == comAdvanced) if (mode == comAdvanced)
return nullptr; return nullptr;
menu->m_separator_scnd = menu->AppendSeparator(); menu->SetSecondSeparator();
// 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(m_bmp_cog); menu_item->SetBitmap(m_bmp_cog.bmp());
menu_item->SetSubMenu(create_settings_popupmenu(menu)); menu_item->SetSubMenu(create_settings_popupmenu(menu));
@ -1290,7 +1330,7 @@ void ObjectList::load_subobject(ModelVolumeType type)
wxArrayString part_names; wxArrayString part_names;
load_part((*m_objects)[obj_idx], part_names, type); load_part((*m_objects)[obj_idx], part_names, type);
parts_changed(obj_idx); changed_object(obj_idx);
for (int i = 0; i < part_names.size(); ++i) { for (int i = 0; i < part_names.size(); ++i) {
const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), type); const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), type);
@ -1306,7 +1346,6 @@ void ObjectList::load_part( ModelObject* model_object,
{ {
wxWindow* parent = wxGetApp().tab_panel()->GetPage(0); wxWindow* parent = wxGetApp().tab_panel()->GetPage(0);
m_parts_changed = false;
wxArrayString input_files; wxArrayString input_files;
wxGetApp().import_model(parent, input_files); wxGetApp().import_model(parent, input_files);
for (int i = 0; i < input_files.size(); ++i) { for (int i = 0; i < input_files.size(); ++i) {
@ -1342,8 +1381,6 @@ void ObjectList::load_part( ModelObject* model_object,
// set a default extruder value, since user can't add it manually // set a default extruder value, since user can't add it manually
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
m_parts_changed = true;
} }
} }
} }
@ -1493,8 +1530,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
// set a default extruder value, since user can't add it manually // set a default extruder value, since user can't add it manually
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
m_parts_changed = true; changed_object(obj_idx);
parts_changed(obj_idx);
const auto object_item = m_objects_model->GetTopParent(GetSelection()); const auto object_item = m_objects_model->GetTopParent(GetSelection());
select_item(m_objects_model->AddVolumeChild(object_item, name, type)); select_item(m_objects_model->AddVolumeChild(object_item, name, type));
@ -1558,8 +1594,7 @@ void ObjectList::del_instances_from_object(const int obj_idx)
(*m_objects)[obj_idx]->invalidate_bounding_box(); // ? #ys_FIXME (*m_objects)[obj_idx]->invalidate_bounding_box(); // ? #ys_FIXME
m_parts_changed = true; changed_object(obj_idx);
parts_changed(obj_idx);
} }
bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type) bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type)
@ -1604,8 +1639,7 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
else else
return false; return false;
m_parts_changed = true; changed_object(obj_idx);
parts_changed(obj_idx);
return true; return true;
} }
@ -1655,8 +1689,7 @@ void ObjectList::split()
if (parent == item) if (parent == item)
Expand(parent); Expand(parent);
m_parts_changed = true; changed_object(obj_idx);
parts_changed(obj_idx);
} }
bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume) bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume)
@ -1713,17 +1746,10 @@ bool ObjectList::can_split_instances()
return selection.is_multiple_full_instance() || selection.is_single_full_instance(); return selection.is_multiple_full_instance() || selection.is_single_full_instance();
} }
void ObjectList::part_settings_changed() // NO_PARAMETERS function call means that changed object index will be determine from Selection()
void ObjectList::changed_object(const int obj_idx/* = -1*/) const
{ {
m_part_settings_changed = true; wxGetApp().plater()->changed_object(obj_idx < 0 ? get_selected_obj_idx() : obj_idx);
wxGetApp().plater()->changed_object(get_selected_obj_idx());
m_part_settings_changed = false;
}
void ObjectList::parts_changed(int obj_idx)
{
wxGetApp().plater()->changed_object(obj_idx);
m_parts_changed = false;
} }
void ObjectList::part_selection_changed() void ObjectList::part_selection_changed()
@ -1826,7 +1852,7 @@ void ObjectList::add_object_to_list(size_t obj_idx)
stats.facets_added + stats.facets_reversed + stats.backwards_edges; stats.facets_added + stats.facets_reversed + stats.backwards_edges;
if (errors > 0) { if (errors > 0) {
wxVariant variant; wxVariant variant;
variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning); variant << DataViewBitmapText(item_name, m_bmp_manifold_warning.bmp());
m_objects_model->SetValue(variant, item, 0); m_objects_model->SetValue(variant, item, 0);
} }
@ -2446,8 +2472,7 @@ void ObjectList::change_part_type()
volume->set_type(new_type); volume->set_type(new_type);
m_objects_model->SetVolumeType(item, new_type); m_objects_model->SetVolumeType(item, new_type);
m_parts_changed = true; changed_object(get_selected_obj_idx());
parts_changed(get_selected_obj_idx());
// Update settings showing, if we have it // Update settings showing, if we have it
//(we show additional settings for Part and Modifier and hide it for Support Blocker/Enforcer) //(we show additional settings for Part and Modifier and hide it for Support Blocker/Enforcer)
@ -2627,7 +2652,7 @@ void ObjectList::rename_item()
wxVariant valueOld; wxVariant valueOld;
m_objects_model->GetValue(valueOld, item, 0); m_objects_model->GetValue(valueOld, item, 0);
PrusaDataViewBitmapText bmpText; DataViewBitmapText bmpText;
bmpText << valueOld; bmpText << valueOld;
// But replace the text with the value entered by user. // But replace the text with the value entered by user.
@ -2675,11 +2700,29 @@ void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) co
if (errors == 0) { if (errors == 0) {
// delete Error_icon if all errors are fixed // delete Error_icon if all errors are fixed
wxVariant variant; wxVariant variant;
variant << PrusaDataViewBitmapText(from_u8(model_object->name), wxNullBitmap); variant << DataViewBitmapText(from_u8(model_object->name), wxNullBitmap);
m_objects_model->SetValue(variant, item, 0); m_objects_model->SetValue(variant, item, 0);
} }
} }
void ObjectList::msw_rescale()
{
// update min size !!! A width of control shouldn't be a wxDefaultCoord
SetMinSize(wxSize(1, 15 * wxGetApp().em_unit()));
GetColumn(0)->SetWidth(19 * wxGetApp().em_unit());
GetColumn(1)->SetWidth(8 * wxGetApp().em_unit());
GetColumn(2)->SetWidth(int(2 * wxGetApp().em_unit()));
// rescale all icons, used by ObjectList
rescale_icons();
// rescale/update existingitems with bitmaps
m_objects_model->Rescale();
Layout();
}
void ObjectList::ItemValueChanged(wxDataViewEvent &event) void ObjectList::ItemValueChanged(wxDataViewEvent &event)
{ {
if (event.GetColumn() == 0) if (event.GetColumn() == 0)
@ -2693,7 +2736,7 @@ void ObjectList::OnEditingDone(wxDataViewEvent &event)
if (event.GetColumn() != 0) if (event.GetColumn() != 0)
return; return;
const auto renderer = dynamic_cast<PrusaBitmapTextRenderer*>(GetColumn(0)->GetRenderer()); const auto renderer = dynamic_cast<BitmapTextRenderer*>(GetColumn(0)->GetRenderer());
if (renderer->WasCanceled()) if (renderer->WasCanceled())
show_error(this, _(L("The supplied name is not valid;")) + "\n" + show_error(this, _(L("The supplied name is not valid;")) + "\n" +

View File

@ -13,8 +13,8 @@
class wxBoxSizer; class wxBoxSizer;
class wxMenuItem; class wxMenuItem;
class PrusaObjectDataViewModel; class ObjectDataViewModel;
class PrusaMenu; class MenuWithSeparators;
namespace Slic3r { namespace Slic3r {
class ConfigOptionsGroup; class ConfigOptionsGroup;
@ -108,18 +108,18 @@ class ObjectList : public wxDataViewCtrl
wxBoxSizer *m_sizer {nullptr}; wxBoxSizer *m_sizer {nullptr};
wxWindow *m_parent {nullptr}; wxWindow *m_parent {nullptr};
wxBitmap m_bmp_modifiermesh; ScalableBitmap m_bmp_modifiermesh;
wxBitmap m_bmp_solidmesh; ScalableBitmap m_bmp_solidmesh;
wxBitmap m_bmp_support_enforcer; ScalableBitmap m_bmp_support_enforcer;
wxBitmap m_bmp_support_blocker; ScalableBitmap m_bmp_support_blocker;
wxBitmap m_bmp_manifold_warning; ScalableBitmap m_bmp_manifold_warning;
wxBitmap m_bmp_cog; ScalableBitmap m_bmp_cog;
wxBitmap m_bmp_split; ScalableBitmap m_bmp_split;
PrusaMenu m_menu_object; MenuWithSeparators m_menu_object;
PrusaMenu m_menu_part; MenuWithSeparators m_menu_part;
PrusaMenu m_menu_sla_object; MenuWithSeparators m_menu_sla_object;
PrusaMenu m_menu_instance; MenuWithSeparators m_menu_instance;
wxMenuItem* m_menu_item_split { nullptr }; wxMenuItem* m_menu_item_split { nullptr };
wxMenuItem* m_menu_item_split_part { nullptr }; wxMenuItem* m_menu_item_split_part { nullptr };
wxMenuItem* m_menu_item_settings { nullptr }; wxMenuItem* m_menu_item_settings { nullptr };
@ -139,9 +139,6 @@ class ObjectList : public wxDataViewCtrl
// update_settings_items - updating canvas selection is undesirable, // update_settings_items - updating canvas selection is undesirable,
// because it would turn off the gizmos (mainly a problem for the SLA gizmo) // because it would turn off the gizmos (mainly a problem for the SLA gizmo)
bool m_parts_changed = false;
bool m_part_settings_changed = false;
int m_selected_row = 0; int m_selected_row = 0;
wxDataViewItem m_last_selected_item {nullptr}; wxDataViewItem m_last_selected_item {nullptr};
@ -157,7 +154,7 @@ public:
std::map<std::string, wxBitmap> CATEGORY_ICON; std::map<std::string, wxBitmap> CATEGORY_ICON;
PrusaObjectDataViewModel *m_objects_model{ nullptr }; ObjectDataViewModel *m_objects_model{ nullptr };
DynamicPrintConfig *m_config {nullptr}; DynamicPrintConfig *m_config {nullptr};
std::vector<ModelObject*> *m_objects{ nullptr }; std::vector<ModelObject*> *m_objects{ nullptr };
@ -176,6 +173,7 @@ public:
void update_extruder_values_for_items(const int max_extruder); void update_extruder_values_for_items(const int max_extruder);
void init_icons(); void init_icons();
void rescale_icons();
void set_tooltip_for_item(const wxPoint& pt); void set_tooltip_for_item(const wxPoint& pt);
@ -225,11 +223,8 @@ public:
wxBoxSizer* get_sizer() {return m_sizer;} wxBoxSizer* get_sizer() {return m_sizer;}
int get_selected_obj_idx() const; int get_selected_obj_idx() const;
DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const;
bool is_parts_changed() const { return m_parts_changed; }
bool is_part_settings_changed() const { return m_part_settings_changed; }
void part_settings_changed();
void parts_changed(int obj_idx); void changed_object(const int obj_idx = -1) const;
void part_selection_changed(); void part_selection_changed();
// Add object to the list // Add object to the list
@ -291,6 +286,8 @@ public:
void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes); void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes);
void paste_objects_into_list(const std::vector<size_t>& object_idxs); void paste_objects_into_list(const std::vector<size_t>& object_idxs);
void msw_rescale();
private: private:
void OnChar(wxKeyEvent& event); void OnChar(wxKeyEvent& event);
void OnContextMenu(wxDataViewEvent &event); void OnContextMenu(wxDataViewEvent &event);

View File

@ -23,7 +23,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
#endif // __APPLE__ #endif // __APPLE__
{ {
m_og->set_name(_(L("Object Manipulation"))); m_og->set_name(_(L("Object Manipulation")));
m_og->label_width = 12 * wxGetApp().em_unit();//125; m_og->label_width = 12;//125;
m_og->set_grid_vgap(5); m_og->set_grid_vgap(5);
m_og->m_on_change = std::bind(&ObjectManipulation::on_change, this, std::placeholders::_1, std::placeholders::_2); m_og->m_on_change = std::bind(&ObjectManipulation::on_change, this, std::placeholders::_1, std::placeholders::_2);
@ -45,11 +45,11 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
def.label = L("Name"); def.label = L("Name");
def.gui_type = "legend"; def.gui_type = "legend";
def.tooltip = L("Object name"); def.tooltip = L("Object name");
def.width = 21 * wxGetApp().em_unit(); def.width = 21;
def.default_value = new ConfigOptionString{ " " }; def.default_value = new ConfigOptionString{ " " };
m_og->append_single_option_line(Option(def, "object_name")); m_og->append_single_option_line(Option(def, "object_name"));
const int field_width = 5 * wxGetApp().em_unit()/*50*/; const int field_width = 5;
// Legend for object modification // Legend for object modification
auto line = Line{ "", "" }; auto line = Line{ "", "" };
@ -78,7 +78,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
// Add "uniform scaling" button in front of "Scale" option // Add "uniform scaling" button in front of "Scale" option
if (option_name == "Scale") { if (option_name == "Scale") {
line.near_label_widget = [this](wxWindow* parent) { line.near_label_widget = [this](wxWindow* parent) {
auto btn = new PrusaLockButton(parent, wxID_ANY); auto btn = new LockButton(parent, wxID_ANY);
btn->Bind(wxEVT_BUTTON, [btn, this](wxCommandEvent &event){ btn->Bind(wxEVT_BUTTON, [btn, this](wxCommandEvent &event){
event.Skip(); event.Skip();
wxTheApp->CallAfter([btn, this]() { set_uniform_scaling(btn->IsLocked()); }); wxTheApp->CallAfter([btn, this]() { set_uniform_scaling(btn->IsLocked()); });
@ -117,15 +117,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
m_og->append_line(add_og_to_object_settings(L("Scale"), "%"), &m_scale_Label); m_og->append_line(add_og_to_object_settings(L("Scale"), "%"), &m_scale_Label);
m_og->append_line(add_og_to_object_settings(L("Size"), "mm")); m_og->append_line(add_og_to_object_settings(L("Size"), "mm"));
/* Unused parameter at this time // call back for a rescale of button "Set uniform scale"
def.label = L("Place on bed"); m_og->rescale_near_label_widget = [this](wxWindow* win) {
def.type = coBool; auto *ctrl = dynamic_cast<LockButton*>(win);
def.tooltip = L("Automatic placing of models on printing bed in Y axis"); if (ctrl == nullptr)
def.gui_type = ""; return;
def.sidetext = ""; ctrl->msw_rescale();
def.default_value = new ConfigOptionBool{ false }; };
m_og->append_single_option_line(Option(def, "place_on_bed"));
*/
} }
void ObjectManipulation::Show(const bool show) void ObjectManipulation::Show(const bool show)

View File

@ -7,7 +7,7 @@
#include "GLCanvas3D.hpp" #include "GLCanvas3D.hpp"
class wxStaticText; class wxStaticText;
class PrusaLockButton; class LockButton;
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -76,7 +76,7 @@ class ObjectManipulation : public OG_Settings
Vec3d m_new_size; Vec3d m_new_size;
bool m_new_enabled; bool m_new_enabled;
bool m_uniform_scale {true}; bool m_uniform_scale {true};
PrusaLockButton* m_lock_bnt{ nullptr }; LockButton* m_lock_bnt{ nullptr };
#ifndef __APPLE__ #ifndef __APPLE__
// Currently focused option name (empty if none) // Currently focused option name (empty if none)

View File

@ -59,6 +59,8 @@ ObjectSettings::ObjectSettings(wxWindow* parent) :
m_settings_list_sizer = new wxBoxSizer(wxVERTICAL); m_settings_list_sizer = new wxBoxSizer(wxVERTICAL);
m_og->sizer->Add(m_settings_list_sizer, 1, wxEXPAND | wxLEFT, 5); m_og->sizer->Add(m_settings_list_sizer, 1, wxEXPAND | wxLEFT, 5);
m_bmp_delete = ScalableBitmap(parent, "cross");
} }
void ObjectSettings::update_settings_list() void ObjectSettings::update_settings_list()
@ -77,14 +79,11 @@ void ObjectSettings::update_settings_list()
{ {
auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line
auto btn = new wxBitmapButton(parent, wxID_ANY, create_scaled_bitmap(m_parent, "cross"/*"colorchange_delete_on.png"*/), auto btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete);
wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
#ifdef __WXMSW__
btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__
btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) { btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) {
config->erase(opt_key); config->erase(opt_key);
wxGetApp().obj_list()->part_settings_changed(); wxGetApp().obj_list()->changed_object();
wxTheApp->CallAfter([this]() { wxTheApp->CallAfter([this]() {
wxWindowUpdateLocker noUpdates(m_parent); wxWindowUpdateLocker noUpdates(m_parent);
update_settings_list(); update_settings_list();
@ -123,22 +122,31 @@ void ObjectSettings::update_settings_list()
continue; continue;
auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), cat.first, config, false, extra_column); auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), cat.first, config, false, extra_column);
optgroup->label_width = 15 * wxGetApp().em_unit(); optgroup->label_width = 15;
optgroup->sidetext_width = 5.5 * wxGetApp().em_unit(); optgroup->sidetext_width = 5.5;
optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) { optgroup->m_on_change = [](const t_config_option_key& opt_id, const boost::any& value) {
wxGetApp().obj_list()->part_settings_changed(); }; wxGetApp().obj_list()->changed_object(); };
for (auto& opt : cat.second) for (auto& opt : cat.second)
{ {
if (opt == "extruder") if (opt == "extruder")
continue; continue;
Option option = optgroup->get_option(opt); Option option = optgroup->get_option(opt);
option.opt.width = 12 * wxGetApp().em_unit(); option.opt.width = 12;
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
} }
optgroup->reload_config(); optgroup->reload_config();
m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); m_settings_list_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0);
// call back for rescaling of the extracolumn control
optgroup->rescale_extra_column_item = [this](wxWindow* win) {
auto *ctrl = dynamic_cast<ScalableButton*>(win);
if (ctrl == nullptr)
return;
ctrl->SetBitmap_(m_bmp_delete);
};
m_og_settings.push_back(optgroup); m_og_settings.push_back(optgroup);
categories.push_back(cat.first); categories.push_back(cat.first);
@ -163,5 +171,13 @@ void ObjectSettings::UpdateAndShow(const bool show)
OG_Settings::UpdateAndShow(show); OG_Settings::UpdateAndShow(show);
} }
void ObjectSettings::msw_rescale()
{
m_bmp_delete.msw_rescale();
for (auto group : m_og_settings)
group->msw_rescale();
}
} //namespace GUI } //namespace GUI
} //namespace Slic3r } //namespace Slic3r

View File

@ -4,6 +4,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <wx/panel.h> #include <wx/panel.h>
#include "wxExtensions.hpp"
class wxBoxSizer; class wxBoxSizer;
@ -37,12 +38,15 @@ class ObjectSettings : public OG_Settings
// option groups for settings // option groups for settings
std::vector <std::shared_ptr<ConfigOptionsGroup>> m_og_settings; std::vector <std::shared_ptr<ConfigOptionsGroup>> m_og_settings;
ScalableBitmap m_bmp_delete;
public: public:
ObjectSettings(wxWindow* parent); ObjectSettings(wxWindow* parent);
~ObjectSettings() {} ~ObjectSettings() {}
void update_settings_list(); void update_settings_list();
void UpdateAndShow(const bool show) override; void UpdateAndShow(const bool show) override;
void msw_rescale();
}; };
}} }}

View File

@ -396,6 +396,18 @@ void Preview::refresh_print()
load_print(true); load_print(true);
} }
void Preview::msw_rescale()
{
// rescale slider
if (m_slider) m_slider->msw_rescale();
// rescale warning legend on the canvas
get_canvas3d()->msw_rescale();
// rescale legend
refresh_print();
}
void Preview::bind_event_handlers() void Preview::bind_event_handlers()
{ {
this->Bind(wxEVT_SIZE, &Preview::on_size, this); this->Bind(wxEVT_SIZE, &Preview::on_size, this);
@ -507,7 +519,7 @@ void Preview::on_checkbox_shells(wxCommandEvent& evt)
void Preview::create_double_slider() void Preview::create_double_slider()
{ {
m_slider = new PrusaDoubleSlider(this, wxID_ANY, 0, 0, 0, 100); m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100);
m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0);
// sizer, m_canvas_widget // sizer, m_canvas_widget

View File

@ -13,7 +13,7 @@ class wxStaticText;
class wxChoice; class wxChoice;
class wxComboCtrl; class wxComboCtrl;
class wxCheckBox; class wxCheckBox;
class PrusaDoubleSlider; class DoubleSlider;
namespace Slic3r { namespace Slic3r {
@ -99,7 +99,7 @@ class Preview : public wxPanel
bool m_loaded; bool m_loaded;
bool m_enabled; bool m_enabled;
PrusaDoubleSlider* m_slider {nullptr}; DoubleSlider* m_slider {nullptr};
public: public:
Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
@ -120,6 +120,8 @@ public:
void reload_print(bool keep_volumes = false); void reload_print(bool keep_volumes = false);
void refresh_print(); void refresh_print();
void msw_rescale();
private: private:
bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model); bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model);

View File

@ -16,6 +16,7 @@
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/dcclient.h> #include <wx/dcclient.h>
#include <wx/debug.h> #include <wx/debug.h>
#include <wx/settings.h>
class wxCheckBox; class wxCheckBox;
class wxTopLevelWindow; class wxTopLevelWindow;
@ -58,35 +59,119 @@ public:
: P(parent, id, title, pos, size, style, name) : P(parent, id, title, pos, size, style, name)
{ {
m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT; m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT;
m_normal_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
// An analog of em_unit value from GUI_App.
m_em_unit = std::max<size_t>(10, 10 * m_scale_factor);
m_prev_scale_factor = m_scale_factor;
recalc_font(); recalc_font();
this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) { this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) {
m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT; m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT;
on_dpi_changed(evt.rect);
if (!m_can_rescale)
return;
if (is_new_scale_factor())
rescale(evt.rect);
});
this->Bind(wxEVT_MOVE_START, [this](wxMoveEvent& event)
{
event.Skip();
// Suppress application rescaling, when a MainFrame moving is not ended
m_can_rescale = false;
});
this->Bind(wxEVT_MOVE_END, [this](wxMoveEvent& event)
{
event.Skip();
m_can_rescale = is_new_scale_factor();
// If scale factor is different after moving of MainFrame ...
if (m_can_rescale)
// ... rescale application
rescale(event.GetRect());
else
// set value to _true_ in purpose of possibility of a display dpi changing from System Settings
m_can_rescale = true;
}); });
} }
virtual ~DPIAware() {} virtual ~DPIAware() {}
float scale_factor() const { return m_scale_factor; } float scale_factor() const { return m_scale_factor; }
int em_unit() const { return m_em_unit; } float prev_scale_factor() const { return m_prev_scale_factor; }
int font_size() const { return m_font_size; }
int em_unit() const { return m_em_unit; }
int font_size() const { return m_font_size; }
const wxFont& normal_font() const { return m_normal_font; }
protected: protected:
virtual void on_dpi_changed(const wxRect &suggested_rect) = 0; virtual void on_dpi_changed(const wxRect &suggested_rect) = 0;
private: private:
int m_scale_factor; float m_scale_factor;
int m_em_unit; int m_em_unit;
int m_font_size; int m_font_size;
wxFont m_normal_font;
float m_prev_scale_factor;
bool m_can_rescale{ true };
void recalc_font() void recalc_font()
{ {
wxClientDC dc(this); wxClientDC dc(this);
const auto metrics = dc.GetFontMetrics(); const auto metrics = dc.GetFontMetrics();
m_font_size = metrics.height; m_font_size = metrics.height;
m_em_unit = metrics.averageWidth; // m_em_unit = metrics.averageWidth;
} }
// check if new scale is differ from previous
bool is_new_scale_factor() const { return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; }
// recursive function for scaling fonts for all controls in Window
void scale_controls_fonts(wxWindow *window, const float scale_f)
{
auto children = window->GetChildren();
for (auto child : children) {
scale_controls_fonts(child, scale_f);
child->SetFont(child->GetFont().Scaled(scale_f));
}
window->Layout();
}
void rescale(const wxRect &suggested_rect)
{
this->Freeze();
const float relative_scale_factor = m_scale_factor / m_prev_scale_factor;
// rescale fonts of all controls
scale_controls_fonts(this, relative_scale_factor);
this->SetFont(this->GetFont().Scaled(relative_scale_factor));
// rescale normal_font value
m_normal_font = m_normal_font.Scaled(relative_scale_factor);
// An analog of em_unit value from GUI_App.
m_em_unit = std::max<size_t>(10, 10 * m_scale_factor);
// rescale missed controls sizes and images
on_dpi_changed(suggested_rect);
this->Layout();
this->Thaw();
// reset previous scale factor from current scale factor value
m_prev_scale_factor = m_scale_factor;
}
}; };
typedef DPIAware<wxFrame> DPIFrame; typedef DPIAware<wxFrame> DPIFrame;

View File

@ -10,26 +10,28 @@ namespace Slic3r {
namespace GUI { namespace GUI {
KBShortcutsDialog::KBShortcutsDialog() KBShortcutsDialog::KBShortcutsDialog()
: wxDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Keyboard Shortcuts")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Keyboard Shortcuts")),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{ {
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
auto main_sizer = new wxBoxSizer(wxVERTICAL); auto main_sizer = new wxBoxSizer(wxVERTICAL);
// logo // logo
const wxBitmap logo_bmp = create_scaled_bitmap(this, "Slic3r_32px.png", 32); m_logo_bmp = ScalableBitmap(this, "Slic3r_32px.png", 32);
// fonts // fonts
wxFont head_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); const wxFont& font = wxGetApp().normal_font();
const wxFont& bold_font = wxGetApp().bold_font();
SetFont(font);
wxFont head_font = bold_font;
#ifdef __WXOSX__ #ifdef __WXOSX__
head_font.SetPointSize(14); head_font.SetPointSize(14);
#else #else
head_font.SetPointSize(12); head_font.SetPointSize(bold_font.GetPointSize() + 2);
#endif // __WXOSX__ #endif // __WXOSX__
const wxFont& font = wxGetApp().small_font();
const wxFont& bold_font = wxGetApp().bold_font();
fill_shortcuts(); fill_shortcuts();
auto panel = new wxPanel(this); auto panel = new wxPanel(this);
@ -43,22 +45,25 @@ KBShortcutsDialog::KBShortcutsDialog()
wxBoxSizer* r_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* r_sizer = new wxBoxSizer(wxVERTICAL);
main_grid_sizer->Add(r_sizer, 0); main_grid_sizer->Add(r_sizer, 0);
m_head_bitmaps.reserve(m_full_shortcuts.size());
const wxSize topic_size = wxSize(10 * wxGetApp().em_unit(), -1);
for (auto& sc : m_full_shortcuts) for (auto& sc : m_full_shortcuts)
{ {
// auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer; auto sizer = sc.second.second == szLeft ? l_sizer : r_sizer;
auto sizer = sc.second.second == 0 ? l_sizer : r_sizer;
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10); sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
// logo // logo
auto *logo = new wxStaticBitmap(panel, wxID_ANY, logo_bmp); m_head_bitmaps.push_back(new wxStaticBitmap(panel, wxID_ANY, m_logo_bmp.bmp()));
hsizer->Add(logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 15); hsizer->Add(m_head_bitmaps.back(), 0, wxEXPAND | wxLEFT | wxRIGHT, 15);
// head // head
wxStaticText* head = new wxStaticText(panel, wxID_ANY, sc.first, wxDefaultPosition, wxSize(20 * wxGetApp().em_unit(), -1)); wxStaticText* head = new wxStaticText(panel, wxID_ANY, sc.first, wxDefaultPosition, topic_size);
head->SetFont(head_font); head->SetFont(head_font);
hsizer->Add(head, 0, wxALIGN_CENTER_VERTICAL); hsizer->Add(head, 0, wxALIGN_CENTER_VERTICAL);
// Shortcuts list // Shortcuts list
auto grid_sizer = new wxFlexGridSizer(2, 5, 15); auto grid_sizer = new wxFlexGridSizer(2, 5, 15);
sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT| wxRIGHT, 15); sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT| wxRIGHT, 15);
@ -121,7 +126,7 @@ void KBShortcutsDialog::fill_shortcuts()
main_shortcuts.push_back(Shortcut("?" ,L("Show keyboard shortcuts list"))); main_shortcuts.push_back(Shortcut("?" ,L("Show keyboard shortcuts list")));
main_shortcuts.push_back(Shortcut(ctrl+"LeftMouse" ,L("Select multiple object/Move multiple object"))); main_shortcuts.push_back(Shortcut(ctrl+"LeftMouse" ,L("Select multiple object/Move multiple object")));
m_full_shortcuts.push_back(std::make_pair( _(L("Main Shortcuts")), std::make_pair(main_shortcuts, 0) )); m_full_shortcuts.push_back(std::make_pair(_(L("Main Shortcuts")), std::make_pair(main_shortcuts, szLeft)));
Shortcuts plater_shortcuts; Shortcuts plater_shortcuts;
@ -148,7 +153,7 @@ void KBShortcutsDialog::fill_shortcuts()
plater_shortcuts.push_back(Shortcut("O", L("Zoom out"))); plater_shortcuts.push_back(Shortcut("O", L("Zoom out")));
plater_shortcuts.push_back(Shortcut("ESC", L("Unselect gizmo, keep object selection"))); plater_shortcuts.push_back(Shortcut("ESC", L("Unselect gizmo, keep object selection")));
m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, 1))); m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, szRight)));
// Shortcuts gizmo_shortcuts; // Shortcuts gizmo_shortcuts;
@ -168,7 +173,7 @@ void KBShortcutsDialog::fill_shortcuts()
preview_shortcuts.push_back(Shortcut("U", L("Upper Layer"))); preview_shortcuts.push_back(Shortcut("U", L("Upper Layer")));
preview_shortcuts.push_back(Shortcut("D", L("Lower Layer"))); preview_shortcuts.push_back(Shortcut("D", L("Lower Layer")));
m_full_shortcuts.push_back(std::make_pair( _(L("Preview Shortcuts")), std::make_pair(preview_shortcuts, 0) )); m_full_shortcuts.push_back(std::make_pair(_(L("Preview Shortcuts")), std::make_pair(preview_shortcuts, szLeft)));
Shortcuts layers_slider_shortcuts; Shortcuts layers_slider_shortcuts;
@ -181,7 +186,23 @@ void KBShortcutsDialog::fill_shortcuts()
layers_slider_shortcuts.push_back(Shortcut("+", L("Add color change marker for current layer"))); layers_slider_shortcuts.push_back(Shortcut("+", L("Add color change marker for current layer")));
layers_slider_shortcuts.push_back(Shortcut("-", L("Delete color change marker for current layer"))); layers_slider_shortcuts.push_back(Shortcut("-", L("Delete color change marker for current layer")));
m_full_shortcuts.push_back(std::make_pair( _(L("Layers Slider Shortcuts")), std::make_pair(layers_slider_shortcuts, 1) )); m_full_shortcuts.push_back(std::make_pair(_(L("Layers Slider Shortcuts")), std::make_pair(layers_slider_shortcuts, szRight)));
}
void KBShortcutsDialog::on_dpi_changed(const wxRect &suggested_rect)
{
m_logo_bmp.msw_rescale();
for (wxStaticBitmap* bmp : m_head_bitmaps)
bmp->SetBitmap(m_logo_bmp.bmp());
const int& em = em_unit();
const wxSize& size = wxSize(85 * em, 75 * em);
SetMinSize(size);
SetSize(size);
Refresh();
} }
void KBShortcutsDialog::onCloseDialog(wxEvent &) void KBShortcutsDialog::onCloseDialog(wxEvent &)

View File

@ -5,24 +5,38 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include "GUI_Utils.hpp"
#include "wxExtensions.hpp"
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
class KBShortcutsDialog : public wxDialog class KBShortcutsDialog : public DPIDialog
{ {
enum PLACED_SIZER_ID
{
szLeft = 0,
szRight
};
typedef std::pair<std::string, std::string> Shortcut; typedef std::pair<std::string, std::string> Shortcut;
typedef std::vector< Shortcut > Shortcuts; typedef std::vector< Shortcut > Shortcuts;
typedef std::vector< std::pair<wxString, std::pair<Shortcuts, int>> > ShortcutsVec; typedef std::vector< std::pair<wxString, std::pair<Shortcuts, PLACED_SIZER_ID>> > ShortcutsVec;
wxString text_info {wxEmptyString}; wxString text_info {wxEmptyString};
ShortcutsVec m_full_shortcuts; ShortcutsVec m_full_shortcuts;
ScalableBitmap m_logo_bmp;
std::vector<wxStaticBitmap*> m_head_bitmaps;
public: public:
KBShortcutsDialog(); KBShortcutsDialog();
void fill_shortcuts(); void fill_shortcuts();
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private: private:
void onCloseDialog(wxEvent &); void onCloseDialog(wxEvent &);
}; };

View File

@ -258,7 +258,30 @@ bool MainFrame::can_delete_all() const
void MainFrame::on_dpi_changed(const wxRect &suggested_rect) void MainFrame::on_dpi_changed(const wxRect &suggested_rect)
{ {
// TODO wxGetApp().update_fonts();
// _strange_ workaround for correct em_unit calculation
const int new_em_unit = scale_factor() * 10;
wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit));
/* Load default preset bitmaps before a tabpanel initialization,
* but after filling of an em_unit value
*/
wxGetApp().preset_bundle->load_default_preset_bitmaps(this);
// update Plater
wxGetApp().plater()->msw_rescale();
// update Tabs
for (auto tab : wxGetApp().tabs_list)
tab->msw_rescale();
/* To correct window rendering (especially redraw of a status bar)
* we should imitate window resizing.
*/
const wxSize& sz = this->GetSize();
this->SetSize(sz.x + 1, sz.y + 1);
this->SetSize(sz);
} }
void MainFrame::init_menubar() void MainFrame::init_menubar()

View File

@ -4,6 +4,7 @@
#include "libslic3r/PrintConfig.hpp" #include "libslic3r/PrintConfig.hpp"
#include <wx/frame.h> #include <wx/frame.h>
#include <wx/settings.h>
#include <wx/string.h> #include <wx/string.h>
#include <string> #include <string>

View File

@ -25,12 +25,14 @@ namespace GUI {
MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id, wxBitmap bitmap) MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id, wxBitmap bitmap)
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, boldfont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)) , boldfont(wxGetApp().normal_font()/*wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)*/)
, content_sizer(new wxBoxSizer(wxVERTICAL)) , content_sizer(new wxBoxSizer(wxVERTICAL))
, btn_sizer(new wxBoxSizer(wxHORIZONTAL)) , btn_sizer(new wxBoxSizer(wxHORIZONTAL))
{ {
boldfont.SetWeight(wxFONTWEIGHT_BOLD); boldfont.SetWeight(wxFONTWEIGHT_BOLD);
this->SetFont(wxGetApp().normal_font());
auto *topsizer = new wxBoxSizer(wxHORIZONTAL); auto *topsizer = new wxBoxSizer(wxHORIZONTAL);
auto *rightsizer = new wxBoxSizer(wxVERTICAL); auto *rightsizer = new wxBoxSizer(wxVERTICAL);

View File

@ -166,8 +166,11 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
#endif /* __WXGTK__ */ #endif /* __WXGTK__ */
// if we have an extra column, build it // if we have an extra column, build it
if (extra_column) if (extra_column)
grid_sizer->Add(extra_column(this->ctrl_parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); {
m_extra_column_item_ptrs.push_back(extra_column(this->ctrl_parent(), line));
grid_sizer->Add(m_extra_column_item_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3);
}
// Build a label if we have it // Build a label if we have it
wxStaticText* label=nullptr; wxStaticText* label=nullptr;
@ -180,21 +183,25 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END; label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END;
#endif /* __WXGTK__ */ #endif /* __WXGTK__ */
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "), label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "),
wxDefaultPosition, wxSize(label_width, -1), label_style); wxDefaultPosition, wxSize(label_width*wxGetApp().em_unit(), -1), label_style);
label->SetBackgroundStyle(wxBG_STYLE_PAINT); label->SetBackgroundStyle(wxBG_STYLE_PAINT);
label->SetFont(label_font); label->SetFont(wxGetApp().normal_font());
label->Wrap(label_width); // avoid a Linux/GTK bug label->Wrap(label_width*wxGetApp().em_unit()); // avoid a Linux/GTK bug
if (!line.near_label_widget) if (!line.near_label_widget)
grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5); grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5);
else if (line.near_label_widget && line.label.IsEmpty())
grid_sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7);
else { else {
// If we're here, we have some widget near the label m_near_label_widget_ptrs.push_back(line.near_label_widget(this->ctrl_parent()));
// so we need a horizontal sizer to arrange these things
auto sizer = new wxBoxSizer(wxHORIZONTAL); if (line.label.IsEmpty())
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); grid_sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7);
sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT, 7); else {
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); // If we're here, we have some widget near the label
// so we need a horizontal sizer to arrange these things
auto sizer = new wxBoxSizer(wxHORIZONTAL);
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT, 7);
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5);
}
} }
if (line.label_tooltip.compare("") != 0) if (line.label_tooltip.compare("") != 0)
label->SetToolTip(line.label_tooltip); label->SetToolTip(line.label_tooltip);
@ -235,14 +242,13 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
wxSizer* sizer_tmp = sizer; wxSizer* sizer_tmp = sizer;
// add label if any // add label if any
if (option.label != "") { if (option.label != "") {
// wxString str_label = _(option.label);
//! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1 //! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1
wxString str_label = (option.label == "Top" || option.label == "Bottom") ? wxString str_label = (option.label == "Top" || option.label == "Bottom") ?
_CTX(option.label, "Layers") : _CTX(option.label, "Layers") :
_(option.label); _(option.label);
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize); label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize);
label->SetBackgroundStyle(wxBG_STYLE_PAINT); label->SetBackgroundStyle(wxBG_STYLE_PAINT);
label->SetFont(label_font); label->SetFont(wxGetApp().normal_font());
sizer_tmp->Add(label, 0, /*wxALIGN_RIGHT |*/ wxALIGN_CENTER_VERTICAL, 0); sizer_tmp->Add(label, 0, /*wxALIGN_RIGHT |*/ wxALIGN_CENTER_VERTICAL, 0);
} }
@ -267,9 +273,9 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
// add sidetext if any // add sidetext if any
if (option.sidetext != "") { if (option.sidetext != "") {
auto sidetext = new wxStaticText( this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition, auto sidetext = new wxStaticText( this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition,
wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT); /*wxSize(sidetext_width*wxGetApp().em_unit(), -1)*/wxDefaultSize, wxALIGN_LEFT);
sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT); sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT);
sidetext->SetFont(sidetext_font); sidetext->SetFont(wxGetApp().normal_font());
sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
field->set_side_text_ptr(sidetext); field->set_side_text_ptr(sidetext);
} }
@ -478,6 +484,57 @@ bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) {
return true; return true;
} }
void ConfigOptionsGroup::msw_rescale()
{
// update bitmaps for extra column items (like "mode markers" or buttons on settings panel)
if (rescale_extra_column_item)
for (auto extra_col : m_extra_column_item_ptrs)
rescale_extra_column_item(extra_col);
// update bitmaps for near label widgets (like "Set uniform scale" button on settings panel)
if (rescale_near_label_widget)
for (auto near_label_widget : m_near_label_widget_ptrs)
rescale_near_label_widget(near_label_widget);
// update undo buttons : rescale bitmaps
for (const auto& field : m_fields)
field.second->msw_rescale();
const int em = em_unit(parent());
// rescale width of label column
if (!m_options_mode.empty() && label_width > 1)
{
const int cols = m_grid_sizer->GetCols();
const int rows = m_grid_sizer->GetEffectiveRowsCount();
const int label_col = extra_column == nullptr ? 0 : 1;
for (int i = 0; i < rows; i++)
{
const wxSizerItem* label_item = m_grid_sizer->GetItem(i*cols+label_col);
if (label_item->IsWindow())
{
auto label = dynamic_cast<wxStaticText*>(label_item->GetWindow());
if (label != nullptr) {
label->SetMinSize(wxSize(label_width*em, -1));
}
}
else if (label_item->IsSizer()) // case when we nave near_label_widget
{
const wxSizerItem* l_item = label_item->GetSizer()->GetItem(1);
if (l_item->IsWindow())
{
auto label = dynamic_cast<wxStaticText*>(l_item->GetWindow());
if (label != nullptr) {
label->SetMinSize(wxSize(label_width*em, -1));
}
}
}
}
m_grid_sizer->Layout();
}
}
boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize) { boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize) {
if (deserialize) { if (deserialize) {

View File

@ -72,7 +72,7 @@ private:
std::vector<widget_t> m_extra_widgets;//! {std::vector<widget_t>()}; std::vector<widget_t> m_extra_widgets;//! {std::vector<widget_t>()};
}; };
using column_t = std::function<wxWindow*(wxWindow* parent, const Line&)>;//std::function<wxSizer*(const Line&)>; using column_t = std::function<wxWindow*(wxWindow* parent, const Line&)>;
using t_optionfield_map = std::map<t_config_option_key, t_field>; 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> >;
@ -82,7 +82,7 @@ class OptionsGroup {
public: public:
const bool staticbox {true}; const bool staticbox {true};
const wxString title {wxString("")}; const wxString title {wxString("")};
size_t label_width = 20 * wxGetApp().em_unit();// {200}; size_t label_width = 20 ;// {200};
wxSizer* sizer {nullptr}; wxSizer* sizer {nullptr};
column_t extra_column {nullptr}; column_t extra_column {nullptr};
t_change m_on_change { nullptr }; t_change m_on_change { nullptr };
@ -94,6 +94,9 @@ public:
std::function<DynamicPrintConfig()> m_get_sys_config{ nullptr }; std::function<DynamicPrintConfig()> m_get_sys_config{ nullptr };
std::function<bool()> have_sys_config{ nullptr }; std::function<bool()> have_sys_config{ nullptr };
std::function<void(wxWindow* win)> rescale_extra_column_item { nullptr };
std::function<void(wxWindow* win)> rescale_near_label_widget { nullptr };
wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
int sidetext_width{ -1 }; int sidetext_width{ -1 };
@ -193,6 +196,8 @@ protected:
std::map<t_config_option_key, Option> m_options; std::map<t_config_option_key, Option> m_options;
wxWindow* m_parent {nullptr}; wxWindow* m_parent {nullptr};
std::vector<ConfigOptionMode> m_options_mode; std::vector<ConfigOptionMode> m_options_mode;
std::vector<wxWindow*> m_extra_column_item_ptrs;
std::vector<wxWindow*> m_near_label_widget_ptrs;
/// Field list, contains unique_ptrs of the derived type. /// Field list, contains unique_ptrs of the derived type.
/// using types that need to know what it is beyond the public interface /// using types that need to know what it is beyond the public interface
@ -261,6 +266,7 @@ public:
void Hide(); void Hide();
void Show(const bool show); void Show(const bool show);
bool update_visibility(ConfigOptionMode mode); bool update_visibility(ConfigOptionMode mode);
void msw_rescale();
boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize); boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize);
// return option value from config // return option value from config
boost::any get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1); boost::any get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1);

View File

@ -111,6 +111,7 @@ public:
bool showing_manifold_warning_icon; bool showing_manifold_warning_icon;
void show_sizer(bool show); void show_sizer(bool show);
void msw_rescale();
}; };
ObjectInfo::ObjectInfo(wxWindow *parent) : ObjectInfo::ObjectInfo(wxWindow *parent) :
@ -118,10 +119,10 @@ ObjectInfo::ObjectInfo(wxWindow *parent) :
{ {
GetStaticBox()->SetFont(wxGetApp().bold_font()); GetStaticBox()->SetFont(wxGetApp().bold_font());
auto *grid_sizer = new wxFlexGridSizer(4, 5, 5); auto *grid_sizer = new wxFlexGridSizer(4, 5, 15);
grid_sizer->SetFlexibleDirection(wxHORIZONTAL); grid_sizer->SetFlexibleDirection(wxHORIZONTAL);
grid_sizer->AddGrowableCol(1, 1); // grid_sizer->AddGrowableCol(1, 1);
grid_sizer->AddGrowableCol(3, 1); // grid_sizer->AddGrowableCol(3, 1);
auto init_info_label = [parent, grid_sizer](wxStaticText **info_label, wxString text_label) { auto init_info_label = [parent, grid_sizer](wxStaticText **info_label, wxString text_label) {
auto *text = new wxStaticText(parent, wxID_ANY, text_label+":"); auto *text = new wxStaticText(parent, wxID_ANY, text_label+":");
@ -160,6 +161,11 @@ void ObjectInfo::show_sizer(bool show)
manifold_warning_icon->Show(showing_manifold_warning_icon && show); manifold_warning_icon->Show(showing_manifold_warning_icon && show);
} }
void ObjectInfo::msw_rescale()
{
manifold_warning_icon->SetBitmap(create_scaled_bitmap(nullptr, "exclamation"));
}
enum SlisedInfoIdx enum SlisedInfoIdx
{ {
siFilament_m, siFilament_m,
@ -229,7 +235,8 @@ void SlicedInfo::SetTextAndShow(SlisedInfoIdx idx, const wxString& text, const w
PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) : PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), 0, nullptr, wxCB_READONLY), wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), 0, nullptr, wxCB_READONLY),
preset_type(preset_type), preset_type(preset_type),
last_selected(wxNOT_FOUND) last_selected(wxNOT_FOUND),
m_em_unit(wxGetApp().em_unit())
{ {
Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) { Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) {
auto selected_item = this->GetSelection(); auto selected_item = this->GetSelection();
@ -281,11 +288,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 *
}); });
} }
edit_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); edit_btn = new ScalableButton(parent, wxID_ANY, "cog");
#ifdef __WINDOWS__
edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
edit_btn->SetBitmap(create_scaled_bitmap(this, "cog"));
edit_btn->SetToolTip(_(L("Click to edit preset"))); edit_btn->SetToolTip(_(L("Click to edit preset")));
edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent)
@ -331,6 +334,12 @@ void PresetComboBox::check_selection()
this->last_selected = GetSelection(); this->last_selected = GetSelection();
} }
void PresetComboBox::msw_rescale()
{
m_em_unit = wxGetApp().em_unit();
edit_btn->msw_rescale();
}
// Frequently changed parameters // Frequently changed parameters
class FreqChangedParams : public OG_Settings class FreqChangedParams : public OG_Settings
@ -428,7 +437,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
option = m_og->get_option("fill_density"); option = m_og->get_option("fill_density");
option.opt.label = L("Infill"); option.opt.label = L("Infill");
option.opt.width = 6 * wxGetApp().em_unit(); option.opt.width = 6;
option.opt.sidetext = " "; option.opt.sidetext = " ";
line.append_option(option); line.append_option(option);
@ -566,7 +575,7 @@ struct Sidebar::priv
wxScrolledWindow *scrolled; wxScrolledWindow *scrolled;
wxPanel* presets_panel; // Used for MSW better layouts wxPanel* presets_panel; // Used for MSW better layouts
PrusaModeSizer *mode_sizer; ModeSizer *mode_sizer;
wxFlexGridSizer *sizer_presets; wxFlexGridSizer *sizer_presets;
PresetComboBox *combo_print; PresetComboBox *combo_print;
std::vector<PresetComboBox*> combos_filament; std::vector<PresetComboBox*> combos_filament;
@ -614,9 +623,9 @@ void Sidebar::priv::show_preset_comboboxes()
// Sidebar / public // Sidebar / public
Sidebar::Sidebar(Plater *parent) Sidebar::Sidebar(Plater *parent)
: wxPanel(parent), p(new priv(parent)) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(40 * wxGetApp().em_unit(), -1)), p(new priv(parent))
{ {
p->scrolled = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(40 * wxGetApp().em_unit(), -1)); p->scrolled = new wxScrolledWindow(this, wxID_ANY/*, wxDefaultPosition, wxSize(40 * wxGetApp().em_unit(), -1)*/);
p->scrolled->SetScrollbars(0, 20, 1, 2); p->scrolled->SetScrollbars(0, 20, 1, 2);
@ -625,7 +634,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 PrusaModeSizer(p->scrolled, 2 * wxGetApp().em_unit()); p->mode_sizer = new ModeSizer(p->scrolled, 2 * 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);
@ -675,13 +684,8 @@ Sidebar::Sidebar(Plater *parent)
init_combo(&p->combo_sla_material, _(L("SLA material")), Preset::TYPE_SLA_MATERIAL, false); init_combo(&p->combo_sla_material, _(L("SLA material")), Preset::TYPE_SLA_MATERIAL, false);
init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false); init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false);
// calculate width of the preset labels
// p->sizer_presets->Layout();
// const wxArrayInt& ar = p->sizer_presets->GetColWidths();
// const int label_width = ar.IsEmpty() ? 10*wxGetApp().em_unit() : ar.front()-4;
const int margin_5 = int(0.5*wxGetApp().em_unit());// 5; const int margin_5 = int(0.5*wxGetApp().em_unit());// 5;
const int margin_10 = int(1.5*wxGetApp().em_unit());// 15; const int margin_10 = 10;//int(1.5*wxGetApp().em_unit());// 15;
p->sizer_params = new wxBoxSizer(wxVERTICAL); p->sizer_params = new wxBoxSizer(wxVERTICAL);
@ -703,10 +707,6 @@ Sidebar::Sidebar(Plater *parent)
p->object_settings->Hide(); p->object_settings->Hide();
p->sizer_params->Add(p->object_settings->get_sizer(), 0, wxEXPAND | wxTOP, margin_5); p->sizer_params->Add(p->object_settings->get_sizer(), 0, wxEXPAND | wxTOP, margin_5);
p->btn_send_gcode = new wxButton(this, wxID_ANY, _(L("Send to printer")));
p->btn_send_gcode->SetFont(wxGetApp().bold_font());
p->btn_send_gcode->Hide();
// Info boxes // Info boxes
p->object_info = new ObjectInfo(p->scrolled); p->object_info = new ObjectInfo(p->scrolled);
p->sliced_info = new SlicedInfo(p->scrolled); p->sliced_info = new SlicedInfo(p->scrolled);
@ -721,10 +721,17 @@ Sidebar::Sidebar(Plater *parent)
scrolled_sizer->Add(p->sliced_info, 0, wxEXPAND | wxTOP | wxLEFT, margin_5); scrolled_sizer->Add(p->sliced_info, 0, wxEXPAND | wxTOP | wxLEFT, margin_5);
// Buttons underneath the scrolled area // Buttons underneath the scrolled area
p->btn_export_gcode = new wxButton(this, wxID_ANY, _(L("Export G-code")) + dots);
p->btn_export_gcode->SetFont(wxGetApp().bold_font()); auto init_btn = [this](wxButton **btn, wxString label) {
p->btn_reslice = new wxButton(this, wxID_ANY, _(L("Slice now"))); *btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition,
p->btn_reslice->SetFont(wxGetApp().bold_font()); wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
(*btn)->SetFont(wxGetApp().bold_font());
};
init_btn(&p->btn_send_gcode, _(L("Send to printer")));
p->btn_send_gcode->Hide();
init_btn(&p->btn_export_gcode, _(L("Export G-code")) + dots);
init_btn(&p->btn_reslice, _(L("Slice now")));
enable_buttons(false); enable_buttons(false);
auto *btns_sizer = new wxBoxSizer(wxVERTICAL); auto *btns_sizer = new wxBoxSizer(wxVERTICAL);
@ -781,6 +788,28 @@ void Sidebar::remove_unused_filament_combos(const int current_extruder_count)
} }
} }
void Sidebar::update_all_preset_comboboxes()
{
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology();
// Update the print choosers to only contain the compatible presets, update the dirty flags.
if (print_tech == ptFFF)
preset_bundle.prints.update_platter_ui(p->combo_print);
else {
preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print);
preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material);
}
// Update the printer choosers, update the dirty flags.
preset_bundle.printers.update_platter_ui(p->combo_printer);
// Update the filament choosers to only contain the compatible presets, update the color preview,
// update the dirty flags.
if (print_tech == ptFFF) {
for (size_t i = 0; i < p->combos_filament.size(); ++i)
preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]);
}
}
void Sidebar::update_presets(Preset::Type preset_type) void Sidebar::update_presets(Preset::Type preset_type)
{ {
PresetBundle &preset_bundle = *wxGetApp().preset_bundle; PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
@ -820,23 +849,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
case Preset::TYPE_PRINTER: case Preset::TYPE_PRINTER:
{ {
// wxWindowUpdateLocker noUpdates_scrolled(p->scrolled); update_all_preset_comboboxes();
// Update the print choosers to only contain the compatible presets, update the dirty flags.
if (print_tech == ptFFF)
preset_bundle.prints.update_platter_ui(p->combo_print);
else {
preset_bundle.sla_prints.update_platter_ui(p->combo_sla_print);
preset_bundle.sla_materials.update_platter_ui(p->combo_sla_material);
}
// Update the printer choosers, update the dirty flags.
preset_bundle.printers.update_platter_ui(p->combo_printer);
// Update the filament choosers to only contain the compatible presets, update the color preview,
// update the dirty flags.
if (print_tech == ptFFF) {
for (size_t i = 0; i < p->combos_filament.size(); ++ i)
preset_bundle.update_platter_filament_ui(i, p->combos_filament[i]);
}
p->show_preset_comboboxes(); p->show_preset_comboboxes();
break; break;
} }
@ -861,6 +874,37 @@ void Sidebar::update_reslice_btn_tooltip() const
p->btn_reslice->SetToolTip(tooltip); p->btn_reslice->SetToolTip(tooltip);
} }
void Sidebar::msw_rescale()
{
SetMinSize(wxSize(40 * wxGetApp().em_unit(), -1));
p->mode_sizer->msw_rescale();
// Rescale preset comboboxes in respect to the current em_unit ...
for (PresetComboBox* combo : std::vector<PresetComboBox*> { p->combo_print,
p->combo_sla_print,
p->combo_sla_material,
p->combo_printer } )
combo->msw_rescale();
for (PresetComboBox* combo : p->combos_filament)
combo->msw_rescale();
// ... then refill them and set min size to correct layout of the sidebar
update_all_preset_comboboxes();
p->frequently_changed_parameters->get_og(true)->msw_rescale();
p->frequently_changed_parameters->get_og(false)->msw_rescale();
p->object_list->msw_rescale();
p->object_manipulation->get_og()->msw_rescale();
p->object_settings->msw_rescale();
p->object_info->msw_rescale();
p->scrolled->Layout();
}
ObjectManipulation* Sidebar::obj_manipul() ObjectManipulation* Sidebar::obj_manipul()
{ {
return p->object_manipulation; return p->object_manipulation;
@ -1132,11 +1176,11 @@ struct Plater::priv
MainFrame *main_frame; MainFrame *main_frame;
// Object popup menu // Object popup menu
PrusaMenu object_menu; MenuWithSeparators object_menu;
// Part popup menu // Part popup menu
PrusaMenu part_menu; MenuWithSeparators part_menu;
// SLA-Object popup menu // SLA-Object popup menu
PrusaMenu sla_object_menu; MenuWithSeparators sla_object_menu;
// Removed/Prepended Items according to the view mode // Removed/Prepended Items according to the view mode
std::vector<wxMenuItem*> items_increase; std::vector<wxMenuItem*> items_increase;
@ -3709,22 +3753,16 @@ void Plater::changed_object(int obj_idx)
{ {
if (obj_idx < 0) if (obj_idx < 0)
return; return;
auto list = wxGetApp().obj_list(); // recenter and re - align to Z = 0
wxASSERT(list != nullptr); auto model_object = p->model.objects[obj_idx];
if (list == nullptr) model_object->ensure_on_bed();
return; if (this->p->printer_technology == ptSLA) {
// Update the SLAPrint from the current Model, so that the reload_scene()
if (list->is_parts_changed()) { // pulls the correct data, update the 3D scene.
// recenter and re - align to Z = 0 this->p->update_restart_background_process(true, false);
auto model_object = p->model.objects[obj_idx];
model_object->ensure_on_bed();
if (this->p->printer_technology == ptSLA) {
// Update the SLAPrint from the current Model, so that the reload_scene()
// pulls the correct data, update the 3D scene.
this->p->update_restart_background_process(true, false);
} else
p->view3D->reload_scene(false);
} }
else
p->view3D->reload_scene(false);
// update print // update print
this->p->schedule_background_process(); this->p->schedule_background_process();
@ -3735,26 +3773,19 @@ void Plater::changed_objects(const std::vector<size_t>& object_idxs)
if (object_idxs.empty()) if (object_idxs.empty())
return; return;
auto list = wxGetApp().obj_list(); for (int obj_idx : object_idxs)
wxASSERT(list != nullptr); {
if (list == nullptr) if (obj_idx < p->model.objects.size())
return; // recenter and re - align to Z = 0
p->model.objects[obj_idx]->ensure_on_bed();
if (list->is_parts_changed()) {
for (int obj_idx : object_idxs)
{
if (obj_idx < p->model.objects.size())
// recenter and re - align to Z = 0
p->model.objects[obj_idx]->ensure_on_bed();
}
if (this->p->printer_technology == ptSLA) {
// Update the SLAPrint from the current Model, so that the reload_scene()
// pulls the correct data, update the 3D scene.
this->p->update_restart_background_process(true, false);
}
else
p->view3D->reload_scene(false);
} }
if (this->p->printer_technology == ptSLA) {
// Update the SLAPrint from the current Model, so that the reload_scene()
// pulls the correct data, update the 3D scene.
this->p->update_restart_background_process(true, false);
}
else
p->view3D->reload_scene(false);
// update print // update print
this->p->schedule_background_process(); this->p->schedule_background_process();
@ -3797,6 +3828,18 @@ bool Plater::can_paste_from_clipboard() const
return true; return true;
} }
void Plater::msw_rescale()
{
p->preview->msw_rescale();
p->view3D->get_canvas3d()->msw_rescale();
p->sidebar->msw_rescale();
Layout();
GetParent()->Layout();
}
bool Plater::can_delete() const { return p->can_delete(); } bool Plater::can_delete() const { return p->can_delete(); }
bool Plater::can_delete_all() const { return p->can_delete_all(); } bool Plater::can_delete_all() const { return p->can_delete_all(); }
bool Plater::can_increase_instances() const { return p->can_increase_instances(); } bool Plater::can_increase_instances() const { return p->can_increase_instances(); }

View File

@ -14,6 +14,7 @@
#include "GLTexture.hpp" #include "GLTexture.hpp"
class wxButton; class wxButton;
class ScalableButton;
class wxBoxSizer; class wxBoxSizer;
class wxGLCanvas; class wxGLCanvas;
class wxScrolledWindow; class wxScrolledWindow;
@ -46,7 +47,7 @@ public:
PresetComboBox(wxWindow *parent, Preset::Type preset_type); PresetComboBox(wxWindow *parent, Preset::Type preset_type);
~PresetComboBox(); ~PresetComboBox();
wxButton* edit_btn { nullptr }; ScalableButton* edit_btn { nullptr };
enum LabelItemType { enum LabelItemType {
LABEL_ITEM_MARKER = 0x4d, LABEL_ITEM_MARKER = 0x4d,
@ -56,14 +57,18 @@ public:
void set_label_marker(int item, LabelItemType label_item_type = LABEL_ITEM_MARKER); void set_label_marker(int item, LabelItemType label_item_type = LABEL_ITEM_MARKER);
void set_extruder_idx(const int extr_idx) { extruder_idx = extr_idx; } void set_extruder_idx(const int extr_idx) { extruder_idx = extr_idx; }
int get_extruder_idx() const { return extruder_idx; } int get_extruder_idx() const { return extruder_idx; }
int em_unit() const { return m_em_unit; }
void check_selection(); void check_selection();
void msw_rescale();
private: private:
typedef std::size_t Marker; typedef std::size_t Marker;
Preset::Type preset_type; Preset::Type preset_type;
int last_selected; int last_selected;
int extruder_idx = -1; int extruder_idx = -1;
int m_em_unit;
}; };
class Sidebar : public wxPanel class Sidebar : public wxPanel
@ -79,9 +84,11 @@ public:
void init_filament_combo(PresetComboBox **combo, const int extr_idx); void init_filament_combo(PresetComboBox **combo, const int extr_idx);
void remove_unused_filament_combos(const int current_extruder_count); void remove_unused_filament_combos(const int current_extruder_count);
void update_all_preset_comboboxes();
void update_presets(Slic3r::Preset::Type preset_type); void update_presets(Slic3r::Preset::Type preset_type);
void update_mode_sizer() const; void update_mode_sizer() const;
void update_reslice_btn_tooltip() const; void update_reslice_btn_tooltip() const;
void msw_rescale();
ObjectManipulation* obj_manipul(); ObjectManipulation* obj_manipul();
ObjectList* obj_list(); ObjectList* obj_list();
@ -199,6 +206,8 @@ public:
bool can_copy() const; bool can_copy() const;
bool can_paste() const; bool can_paste() const;
void msw_rescale();
private: private:
struct priv; struct priv;
std::unique_ptr<priv> p; std::unique_ptr<priv> p;

View File

@ -7,7 +7,9 @@ namespace Slic3r {
namespace GUI { namespace GUI {
PreferencesDialog::PreferencesDialog(wxWindow* parent) : PreferencesDialog::PreferencesDialog(wxWindow* parent) :
wxDialog(parent, wxID_ANY, _(L("Preferences")), wxDefaultPosition, wxDefaultSize) { DPIDialog(parent, wxID_ANY, _(L("Preferences")), wxDefaultPosition,
wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
build(); build();
} }
@ -15,7 +17,7 @@ void PreferencesDialog::build()
{ {
auto app_config = get_app_config(); auto app_config = get_app_config();
m_optgroup = std::make_shared<ConfigOptionsGroup>(this, _(L("General"))); m_optgroup = std::make_shared<ConfigOptionsGroup>(this, _(L("General")));
m_optgroup->label_width = 40 * wxGetApp().em_unit(); //400; m_optgroup->label_width = 40;
m_optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ m_optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0"; m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
}; };
@ -110,6 +112,8 @@ void PreferencesDialog::build()
auto sizer = new wxBoxSizer(wxVERTICAL); auto sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(m_optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); sizer->Add(m_optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
SetFont(wxGetApp().normal_font());
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(); });
@ -138,5 +142,18 @@ void PreferencesDialog::accept()
wxGetApp().update_ui_from_settings(); wxGetApp().update_ui_from_settings();
} }
void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect)
{
m_optgroup->msw_rescale();
const int& em = em_unit();
const wxSize& size = wxSize(50 * em, 29 * em);
SetMinSize(size);
SetSize(size);
Refresh();
}
} // GUI } // GUI
} // Slic3r } // Slic3r

View File

@ -2,6 +2,7 @@
#define slic3r_Preferences_hpp_ #define slic3r_Preferences_hpp_
#include "GUI.hpp" #include "GUI.hpp"
#include "GUI_Utils.hpp"
#include <wx/dialog.h> #include <wx/dialog.h>
#include <map> #include <map>
@ -11,7 +12,7 @@ namespace GUI {
class ConfigOptionsGroup; class ConfigOptionsGroup;
class PreferencesDialog : public wxDialog class PreferencesDialog : public DPIDialog
{ {
std::map<std::string, std::string> m_values; std::map<std::string, std::string> m_values;
std::shared_ptr<ConfigOptionsGroup> m_optgroup; std::shared_ptr<ConfigOptionsGroup> m_optgroup;
@ -21,6 +22,9 @@ public:
void build(); void build();
void accept(); void accept();
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
}; };
} // GUI } // GUI

View File

@ -914,6 +914,16 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
// and draw a red flag in front of the selected preset. // and draw a red flag in front of the selected preset.
bool wide_icons = ! selected_preset.is_compatible && m_bitmap_incompatible != nullptr; bool wide_icons = ! selected_preset.is_compatible && m_bitmap_incompatible != nullptr;
/* It's supposed that standard size of an icon is 16px*16px for 100% scaled display.
* So set sizes for solid_colored icons used for filament preset
* and scale them in respect to em_unit value
*/
const float scale_f = ui->em_unit() * 0.1f;
const int icon_height = 16 * scale_f + 0.5f;
const int icon_width = 16 * scale_f + 0.5f;
const int thin_space_icon_width = 4 * scale_f + 0.5f;
const int wide_space_icon_width = 6 * scale_f + 0.5f;
std::map<wxString, wxBitmap*> nonsys_presets; std::map<wxString, wxBitmap*> nonsys_presets;
wxString selected = ""; wxString selected = "";
if (!this->m_presets.front().is_visible) if (!this->m_presets.front().is_visible)
@ -934,13 +944,13 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
std::vector<wxBitmap> bmps; std::vector<wxBitmap> bmps;
if (wide_icons) if (wide_icons)
// Paint a red flag for incompatible presets. // Paint a red flag for incompatible presets.
bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(16, 16) : *m_bitmap_incompatible); bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(icon_width, icon_height) : *m_bitmap_incompatible);
// Paint the color bars. // Paint the color bars.
bmps.emplace_back(m_bitmap_cache->mkclear(4, 16)); bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height));
bmps.emplace_back(*m_bitmap_main_frame); bmps.emplace_back(*m_bitmap_main_frame);
// Paint a lock at the system presets. // Paint a lock at the system presets.
bmps.emplace_back(m_bitmap_cache->mkclear(6, 16)); bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height));
bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 16)); bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(icon_width, icon_height));
bmp = m_bitmap_cache->insert(bitmap_key, bmps); bmp = m_bitmap_cache->insert(bitmap_key, bmps);
} }
@ -981,12 +991,12 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
std::vector<wxBitmap> bmps; std::vector<wxBitmap> bmps;
if (wide_icons) if (wide_icons)
// Paint a red flag for incompatible presets. // Paint a red flag for incompatible presets.
bmps.emplace_back(m_bitmap_cache->mkclear(16, 16)); bmps.emplace_back(m_bitmap_cache->mkclear(icon_width, icon_height));
// Paint the color bars. // Paint the color bars.
bmps.emplace_back(m_bitmap_cache->mkclear(4, 16)); bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height));
bmps.emplace_back(*m_bitmap_main_frame); bmps.emplace_back(*m_bitmap_main_frame);
// Paint a lock at the system presets. // Paint a lock at the system presets.
bmps.emplace_back(m_bitmap_cache->mkclear(6, 16)); bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height));
bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap); bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap);
bmp = m_bitmap_cache->insert(bitmap_key, bmps); bmp = m_bitmap_cache->insert(bitmap_key, bmps);
} }
@ -996,10 +1006,14 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
ui->SetSelection(selected_preset_item); ui->SetSelection(selected_preset_item);
ui->SetToolTip(ui->GetString(selected_preset_item)); ui->SetToolTip(ui->GetString(selected_preset_item));
ui->check_selection(); ui->check_selection();
ui->Thaw(); ui->Thaw();
// Update control min size after rescale (changed Display DPI under MSW)
if (ui->GetMinWidth() != 20 * ui->em_unit())
ui->SetMinSize(wxSize(20 * ui->em_unit(), ui->GetSize().GetHeight()));
} }
size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible) size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible, const int em/* = 10*/)
{ {
if (ui == nullptr) if (ui == nullptr)
return 0; return 0;
@ -1007,6 +1021,14 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati
ui->Clear(); ui->Clear();
size_t selected_preset_item = 0; size_t selected_preset_item = 0;
/* It's supposed that standard size of an icon is 16px*16px for 100% scaled display.
* So set sizes for solid_colored(empty) icons used for preset
* and scale them in respect to em_unit value
*/
const float scale_f = em * 0.1f;
const int icon_height = 16 * scale_f + 0.5f;
const int icon_width = 16 * scale_f + 0.5f;
std::map<wxString, wxBitmap*> nonsys_presets; std::map<wxString, wxBitmap*> nonsys_presets;
wxString selected = ""; wxString selected = "";
if (!this->m_presets.front().is_visible) if (!this->m_presets.front().is_visible)
@ -1025,7 +1047,7 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati
const wxBitmap* tmp_bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible; const wxBitmap* tmp_bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible;
bmps.emplace_back((tmp_bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *tmp_bmp); bmps.emplace_back((tmp_bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *tmp_bmp);
// Paint a lock at the system presets. // Paint a lock at the system presets.
bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 16)); bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(icon_width, icon_height));
bmp = m_bitmap_cache->insert(bitmap_key, bmps); bmp = m_bitmap_cache->insert(bitmap_key, bmps);
} }
@ -1292,6 +1314,11 @@ std::string PresetCollection::path_from_name(const std::string &new_name) const
return (boost::filesystem::path(m_dir_path) / file_name).make_preferred().string(); return (boost::filesystem::path(m_dir_path) / file_name).make_preferred().string();
} }
void PresetCollection::clear_bitmap_cache()
{
m_bitmap_cache->clear();
}
wxString PresetCollection::separator(const std::string &label) wxString PresetCollection::separator(const std::string &label)
{ {
return wxString::FromUTF8(PresetCollection::separator_head()) + _(label) + wxString::FromUTF8(PresetCollection::separator_tail()); return wxString::FromUTF8(PresetCollection::separator_head()) + _(label) + wxString::FromUTF8(PresetCollection::separator_tail());

View File

@ -394,7 +394,7 @@ public:
// Update the choice UI from the list of presets. // Update the choice UI from the list of presets.
// If show_incompatible, all presets are shown, otherwise only the compatible presets are shown. // If show_incompatible, all presets are shown, otherwise only the compatible presets are shown.
// If an incompatible preset is selected, it is shown as well. // If an incompatible preset is selected, it is shown as well.
size_t update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible); size_t update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible, const int em = 10);
// Update the choice UI from the list of presets. // Update the choice UI from the list of presets.
// Only the compatible presets are shown. // Only the compatible presets are shown.
// If an incompatible preset is selected, it is shown as well. // If an incompatible preset is selected, it is shown as well.
@ -412,6 +412,8 @@ public:
// Generate a file path from a profile name. Add the ".ini" suffix if it is missing. // Generate a file path from a profile name. Add the ".ini" suffix if it is missing.
std::string path_from_name(const std::string &new_name) const; std::string path_from_name(const std::string &new_name) const;
void clear_bitmap_cache();
#ifdef __linux__ #ifdef __linux__
static const char* separator_head() { return "------- "; } static const char* separator_head() { return "------- "; }
static const char* separator_tail() { return " -------"; } static const char* separator_tail() { return " -------"; }

View File

@ -1434,6 +1434,14 @@ bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out
void PresetBundle::load_default_preset_bitmaps(wxWindow *window) void PresetBundle::load_default_preset_bitmaps(wxWindow *window)
{ {
// Clear bitmap cache, before load new scaled default preset bitmaps
m_bitmapCache->clear();
this->prints.clear_bitmap_cache();
this->sla_prints.clear_bitmap_cache();
this->filaments.clear_bitmap_cache();
this->sla_materials.clear_bitmap_cache();
this->printers.clear_bitmap_cache();
this->prints.load_bitmap_default(window, "cog"); this->prints.load_bitmap_default(window, "cog");
this->sla_prints.load_bitmap_default(window, "cog"); this->sla_prints.load_bitmap_default(window, "cog");
this->filaments.load_bitmap_default(window, "spool.png"); this->filaments.load_bitmap_default(window, "spool.png");
@ -1468,6 +1476,18 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr
wxString selected_str = ""; wxString selected_str = "";
if (!this->filaments().front().is_visible) if (!this->filaments().front().is_visible)
ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap)); ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap));
/* It's supposed that standard size of an icon is 16px*16px for 100% scaled display.
* So set sizes for solid_colored icons used for filament preset
* and scale them in respect to em_unit value
*/
const float scale_f = ui->em_unit() * 0.1f;
const int icon_height = 16 * scale_f + 0.5f;
const int normal_icon_width = 16 * scale_f + 0.5f;
const int space_icon_width = 2 * scale_f + 0.5f;
const int wide_icon_width = 24 * scale_f + 0.5f;
const int thin_icon_width = 8 * scale_f + 0.5f;
for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++i) { for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++i) {
const Preset &preset = this->filaments.preset(i); const Preset &preset = this->filaments.preset(i);
bool selected = this->filament_presets[idx_extruder] == preset.name; bool selected = this->filament_presets[idx_extruder] == preset.name;
@ -1491,17 +1511,17 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr
std::vector<wxBitmap> bmps; std::vector<wxBitmap> bmps;
if (wide_icons) if (wide_icons)
// Paint a red flag for incompatible presets. // Paint a red flag for incompatible presets.
bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(16, 16) : *m_bitmapIncompatible); bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(normal_icon_width, icon_height) : *m_bitmapIncompatible);
// Paint the color bars. // Paint the color bars.
parse_color(filament_rgb, rgb); parse_color(filament_rgb, rgb);
bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? 24 : 16, 16, rgb)); bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? wide_icon_width : normal_icon_width, icon_height, rgb));
if (! single_bar) { if (! single_bar) {
parse_color(extruder_rgb, rgb); parse_color(extruder_rgb, rgb);
bmps.emplace_back(m_bitmapCache->mksolid(8, 16, rgb)); bmps.emplace_back(m_bitmapCache->mksolid(thin_icon_width, icon_height, rgb));
} }
// Paint a lock at the system presets. // Paint a lock at the system presets.
bmps.emplace_back(m_bitmapCache->mkclear(2, 16)); bmps.emplace_back(m_bitmapCache->mkclear(space_icon_width, icon_height));
bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(16, 16)); bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(normal_icon_width, icon_height));
// (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16)); // (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16));
bitmap = m_bitmapCache->insert(bitmap_key, bmps); bitmap = m_bitmapCache->insert(bitmap_key, bmps);
} }
@ -1536,6 +1556,10 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::Pr
ui->SetToolTip(ui->GetString(selected_preset_item)); ui->SetToolTip(ui->GetString(selected_preset_item));
ui->check_selection(); ui->check_selection();
ui->Thaw(); ui->Thaw();
// Update control min size after rescale (changed Display DPI under MSW)
if (ui->GetMinWidth() != 20 * ui->em_unit())
ui->SetMinSize(wxSize(20 * ui->em_unit(), ui->GetSize().GetHeight()));
} }
void PresetBundle::set_default_suppressed(bool default_suppressed) void PresetBundle::set_default_suppressed(bool default_suppressed)

View File

@ -131,7 +131,7 @@ wxEvent *PrintHostQueueDialog::Event::Clone() const
} }
PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent) PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent)
: wxDialog(parent, wxID_ANY, _(L("Print host upload queue")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) : DPIDialog(parent, wxID_ANY, _(L("Print host upload queue")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, on_progress_evt(this, EVT_PRINTHOST_PROGRESS, &PrintHostQueueDialog::on_progress, this) , on_progress_evt(this, EVT_PRINTHOST_PROGRESS, &PrintHostQueueDialog::on_progress, this)
, on_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this) , on_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this)
, on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this) , on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this)

View File

@ -41,7 +41,7 @@ private:
}; };
class PrintHostQueueDialog : public wxDialog class PrintHostQueueDialog : public DPIDialog
{ {
public: public:
class Event : public wxEvent class Event : public wxEvent
@ -62,6 +62,10 @@ public:
PrintHostQueueDialog(wxWindow *parent); PrintHostQueueDialog(wxWindow *parent);
void append_job(const PrintHostJob &job); void append_job(const PrintHostJob &job);
protected:
void on_dpi_changed(const wxRect &suggested_rect) override { Refresh(); }
private: private:
enum Column { enum Column {
COL_ID, COL_ID,

View File

@ -41,10 +41,12 @@ std::string get_main_info(bool format_as_html)
} }
SysInfoDialog::SysInfoDialog() SysInfoDialog::SysInfoDialog()
: wxDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("System Information")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("System Information")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
{ {
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
SetBackgroundColour(bgr_clr); SetBackgroundColour(bgr_clr);
SetFont(wxGetApp().normal_font());
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
hsizer->SetMinSize(wxSize(50 * wxGetApp().em_unit(), -1)); hsizer->SetMinSize(wxSize(50 * wxGetApp().em_unit(), -1));
@ -52,8 +54,9 @@ SysInfoDialog::SysInfoDialog()
main_sizer->Add(hsizer, 1, wxEXPAND | wxALL, 10); main_sizer->Add(hsizer, 1, wxEXPAND | wxALL, 10);
// logo // logo
auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); m_logo_bmp = ScalableBitmap(this, "Slic3r_192px.png", 192);
hsizer->Add(logo, 0, wxALIGN_CENTER_VERTICAL); m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bmp.bmp());
hsizer->Add(m_logo, 0, wxALIGN_CENTER_VERTICAL);
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
hsizer->Add(vsizer, 1, wxEXPAND|wxLEFT, 20); hsizer->Add(vsizer, 1, wxEXPAND|wxLEFT, 20);
@ -61,8 +64,7 @@ SysInfoDialog::SysInfoDialog()
// title // title
{ {
wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize); wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize);
wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont title_font = wxGetApp().bold_font();
title_font.SetWeight(wxFONTWEIGHT_BOLD);
title_font.SetFamily(wxFONTFAMILY_ROMAN); title_font.SetFamily(wxFONTFAMILY_ROMAN);
title_font.SetPointSize(22); title_font.SetPointSize(22);
title->SetFont(title_font); title->SetFont(title_font);
@ -70,7 +72,7 @@ SysInfoDialog::SysInfoDialog()
} }
// main_info_text // main_info_text
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont font = wxGetApp().normal_font();
const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); const auto text_clr = 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());
@ -78,10 +80,10 @@ SysInfoDialog::SysInfoDialog()
const int fs = font.GetPointSize() - 1; const int fs = font.GetPointSize() - 1;
int size[] = { static_cast<int>(fs*1.5), static_cast<int>(fs*1.4), static_cast<int>(fs*1.3), fs, fs, fs, fs }; int size[] = { static_cast<int>(fs*1.5), static_cast<int>(fs*1.4), static_cast<int>(fs*1.3), fs, fs, fs, fs };
wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER); m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER);
{ {
html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
html->SetBorders(2); m_html->SetBorders(2);
const auto text = wxString::Format( const auto text = wxString::Format(
"<html>" "<html>"
"<body bgcolor= %s link= %s>" "<body bgcolor= %s link= %s>"
@ -91,16 +93,16 @@ SysInfoDialog::SysInfoDialog()
"</body>" "</body>"
"</html>", bgr_clr_str, text_clr_str, text_clr_str, "</html>", bgr_clr_str, text_clr_str, text_clr_str,
get_main_info(true)); get_main_info(true));
html->SetPage(text); m_html->SetPage(text);
vsizer->Add(html, 1, wxEXPAND | wxBOTTOM, wxGetApp().em_unit()); vsizer->Add(m_html, 1, wxEXPAND | wxBOTTOM, wxGetApp().em_unit());
} }
// opengl_info // opengl_info
wxHtmlWindow* opengl_info_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); m_opengl_info_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
{ {
opengl_info_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit())); m_opengl_info_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
opengl_info_html->SetBorders(10); m_opengl_info_html->SetBorders(10);
const auto text = wxString::Format( const auto text = wxString::Format(
"<html>" "<html>"
"<body bgcolor= %s link= %s>" "<body bgcolor= %s link= %s>"
@ -110,8 +112,8 @@ SysInfoDialog::SysInfoDialog()
"</body>" "</body>"
"</html>", bgr_clr_str, text_clr_str, text_clr_str, "</html>", bgr_clr_str, text_clr_str, text_clr_str,
_3DScene::get_gl_info(true, true)); _3DScene::get_gl_info(true, true));
opengl_info_html->SetPage(text); m_opengl_info_html->SetPage(text);
main_sizer->Add(opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15); main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15);
} }
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK); wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK);
@ -130,6 +132,32 @@ SysInfoDialog::SysInfoDialog()
main_sizer->SetSizeHints(this); main_sizer->SetSizeHints(this);
} }
void SysInfoDialog::on_dpi_changed(const wxRect &suggested_rect)
{
m_logo_bmp.msw_rescale();
m_logo->SetBitmap(m_logo_bmp.bmp());
wxFont font = GetFont();
const int fs = font.GetPointSize() - 1;
int font_size[] = { static_cast<int>(fs*1.5), static_cast<int>(fs*1.4), static_cast<int>(fs*1.3), fs, fs, fs, fs };
m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size);
m_html->Refresh();
const int& em = em_unit();
m_opengl_info_html->SetMinSize(wxSize(-1, 16 * em));
m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), font_size);
m_opengl_info_html->Refresh();
const wxSize& size = wxSize(65 * em, 55 * em);
SetMinSize(size);
SetSize(size);
Refresh();
}
void SysInfoDialog::onCopyToClipboard(wxEvent &) void SysInfoDialog::onCopyToClipboard(wxEvent &)
{ {
wxTheClipboard->Open(); wxTheClipboard->Open();

View File

@ -4,15 +4,25 @@
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/html/htmlwin.h> #include <wx/html/htmlwin.h>
#include "GUI_Utils.hpp"
#include "wxExtensions.hpp"
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
class SysInfoDialog : public wxDialog class SysInfoDialog : public DPIDialog
{ {
wxString text_info {wxEmptyString}; ScalableBitmap m_logo_bmp;
wxStaticBitmap* m_logo;
wxHtmlWindow* m_opengl_info_html;
wxHtmlWindow* m_html;
public: public:
SysInfoDialog(); SysInfoDialog();
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private: private:
void onCopyToClipboard(wxEvent &); void onCopyToClipboard(wxEvent &);
void onCloseDialog(wxEvent &); void onCloseDialog(wxEvent &);

View File

@ -110,37 +110,28 @@ void Tab::create_preset_tab()
#endif //__WXOSX__ #endif //__WXOSX__
// preset chooser // preset chooser
m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(25 * m_em_unit, -1), 0, 0, wxCB_READONLY); m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(35 * m_em_unit, -1), 0, 0, wxCB_READONLY);
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
//buttons //buttons
wxBitmap bmpMenu; m_scaled_buttons.reserve(6);
bmpMenu = create_scaled_bitmap(this, "save"); m_scaled_buttons.reserve(2);
m_btn_save_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
if (wxMSW) m_btn_save_preset->SetBackgroundColour(color); add_scaled_button(panel, &m_btn_save_preset, "save");
bmpMenu = create_scaled_bitmap(this, "cross"/*"delete.png"*/); add_scaled_button(panel, &m_btn_delete_preset, "cross");
m_btn_delete_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
if (wxMSW) m_btn_delete_preset->SetBackgroundColour(color);
m_show_incompatible_presets = false; m_show_incompatible_presets = false;
m_bmp_show_incompatible_presets = create_scaled_bitmap(this, "flag_red"); add_scaled_bitmap(this, m_bmp_show_incompatible_presets, "flag_red");
m_bmp_hide_incompatible_presets = create_scaled_bitmap(this, "flag_green"); add_scaled_bitmap(this, m_bmp_hide_incompatible_presets, "flag_green");
m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
if (wxMSW) m_btn_hide_incompatible_presets->SetBackgroundColour(color); add_scaled_button(panel, &m_btn_hide_incompatible_presets, m_bmp_hide_incompatible_presets.name());
m_btn_save_preset->SetToolTip(_(L("Save current ")) + m_title); m_btn_save_preset->SetToolTip(_(L("Save current ")) + m_title);
m_btn_delete_preset->SetToolTip(_(L("Delete this preset"))); m_btn_delete_preset->SetToolTip(_(L("Delete this preset")));
m_btn_delete_preset->Disable(); m_btn_delete_preset->Disable();
m_undo_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); add_scaled_button(panel, &m_question_btn, "question");
m_undo_to_sys_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
m_question_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
if (wxMSW) {
m_undo_btn->SetBackgroundColour(color);
m_undo_to_sys_btn->SetBackgroundColour(color);
m_question_btn->SetBackgroundColour(color);
}
m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n" m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n"
"or click this button."))); "or click this button.")));
@ -148,22 +139,21 @@ void Tab::create_preset_tab()
// Determine the theme color of OS (dark or light) // Determine the theme color of OS (dark or light)
auto luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); auto luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
// Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
m_bmp_value_lock = create_scaled_bitmap(this, luma >= 128 ? "lock_closed" : "lock_closed_white"); add_scaled_bitmap(this, m_bmp_value_lock , luma >= 128 ? "lock_closed" : "lock_closed_white");
m_bmp_value_unlock = create_scaled_bitmap(this, "lock_open"); add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open");
m_bmp_non_system = &m_bmp_white_bullet; m_bmp_non_system = &m_bmp_white_bullet;
// Bitmaps to be shown on the "Undo user changes" button next to each input field. // Bitmaps to be shown on the "Undo user changes" button next to each input field.
m_bmp_value_revert = create_scaled_bitmap(this, "undo"); add_scaled_bitmap(this, m_bmp_value_revert, "undo");
m_bmp_white_bullet = create_scaled_bitmap(this, luma >= 128 ? "dot" : "dot_white"/*"bullet_white.png"*/); add_scaled_bitmap(this, m_bmp_white_bullet, luma >= 128 ? "dot" : "dot_white");
m_bmp_question = create_scaled_bitmap(this, "question");
fill_icon_descriptions(); fill_icon_descriptions();
set_tooltips_text(); set_tooltips_text();
m_undo_btn->SetBitmap(m_bmp_white_bullet); add_scaled_button(panel, &m_undo_btn, m_bmp_white_bullet.name());
add_scaled_button(panel, &m_undo_to_sys_btn, m_bmp_white_bullet.name());
m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(); })); m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(); }));
m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet);
m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); })); m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); }));
m_question_btn->SetBitmap(m_bmp_question);
m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent)
{ {
auto dlg = new ButtonsDescription(this, &m_icon_descriptions); auto dlg = new ButtonsDescription(this, &m_icon_descriptions);
@ -183,7 +173,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 PrusaModeSizer(panel); m_mode_sizer = new ModeSizer(panel);
const float scale_factor = wxGetApp().em_unit()*0.1;// GetContentScaleFactor(); const float scale_factor = wxGetApp().em_unit()*0.1;// GetContentScaleFactor();
m_hsizer = new wxBoxSizer(wxHORIZONTAL); m_hsizer = new wxBoxSizer(wxHORIZONTAL);
@ -259,12 +249,36 @@ void Tab::create_preset_tab()
toggle_show_hide_incompatible(); toggle_show_hide_incompatible();
})); }));
// Fill cache for mode bitmaps
m_mode_bitmap_cache.reserve(3);
m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_simple_.png"));
m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_middle_.png"));
m_mode_bitmap_cache.push_back(ScalableBitmap(this, "mode_expert_.png"));
// Initialize the DynamicPrintConfig by default keys/values. // Initialize the DynamicPrintConfig by default keys/values.
build(); build();
rebuild_page_tree(); rebuild_page_tree();
m_complited = true; m_complited = true;
} }
void Tab::add_scaled_button(wxWindow* parent,
ScalableButton** btn,
const std::string& icon_name,
const wxString& label/* = wxEmptyString*/,
long style /*= wxBU_EXACTFIT | wxNO_BORDER*/)
{
*btn = new ScalableButton(parent, wxID_ANY, icon_name, label, wxDefaultSize, wxDefaultPosition, style);
m_scaled_buttons.push_back(*btn);
}
void Tab::add_scaled_bitmap(wxWindow* parent,
ScalableBitmap& bmp,
const std::string& icon_name)
{
bmp = ScalableBitmap(parent, icon_name);
m_scaled_bitmaps.push_back(&bmp);
}
void Tab::load_initial_data() void Tab::load_initial_data()
{ {
m_config = &m_presets->get_edited_preset().config; m_config = &m_presets->get_edited_preset().config;
@ -281,9 +295,8 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str
icon_idx = (m_icon_index.find(icon) == m_icon_index.end()) ? -1 : m_icon_index.at(icon); icon_idx = (m_icon_index.find(icon) == m_icon_index.end()) ? -1 : m_icon_index.at(icon);
if (icon_idx == -1) { if (icon_idx == -1) {
// Add a new icon to the icon list. // Add a new icon to the icon list.
// wxIcon img_icon(from_u8(Slic3r::var(icon)), wxBITMAP_TYPE_PNG); m_scaled_icons_list.push_back(ScalableBitmap(this, icon));
// m_icons->Add(img_icon); m_icons->Add(m_scaled_icons_list.back().bmp());
m_icons->Add(create_scaled_bitmap(this, icon));
icon_idx = ++m_icon_count; icon_idx = ++m_icon_count;
m_icon_index[icon] = icon_idx; m_icon_index[icon] = icon_idx;
} }
@ -294,7 +307,7 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str
#else #else
auto panel = this; auto panel = this;
#endif #endif
PageShp page(new Page(panel, title, icon_idx)); PageShp page(new Page(panel, title, icon_idx, m_mode_bitmap_cache));
// page->SetBackgroundStyle(wxBG_STYLE_SYSTEM); // page->SetBackgroundStyle(wxBG_STYLE_SYSTEM);
#ifdef __WINDOWS__ #ifdef __WINDOWS__
// page->SetDoubleBuffered(true); // page->SetDoubleBuffered(true);
@ -402,8 +415,8 @@ void Tab::update_changed_ui()
{ {
bool is_nonsys_value = false; bool is_nonsys_value = false;
bool is_modified_value = true; bool is_modified_value = true;
const wxBitmap *sys_icon = &m_bmp_value_lock; const ScalableBitmap *sys_icon = &m_bmp_value_lock;
const wxBitmap *icon = &m_bmp_value_revert; const ScalableBitmap *icon = &m_bmp_value_revert;
const wxColour *color = &m_sys_label_clr; const wxColour *color = &m_sys_label_clr;
@ -595,8 +608,8 @@ void Tab::update_changed_tree_ui()
void Tab::update_undo_buttons() void Tab::update_undo_buttons()
{ {
m_undo_btn->SetBitmap(m_is_modified_values ? m_bmp_value_revert : m_bmp_white_bullet); m_undo_btn-> SetBitmap_(m_is_modified_values ? m_bmp_value_revert: m_bmp_white_bullet);
m_undo_to_sys_btn->SetBitmap(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock); m_undo_to_sys_btn-> SetBitmap_(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock);
m_undo_btn->SetToolTip(m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet); m_undo_btn->SetToolTip(m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet);
m_undo_to_sys_btn->SetToolTip(m_is_nonsys_values ? *m_ttg_non_system : m_ttg_value_lock); m_undo_to_sys_btn->SetToolTip(m_is_nonsys_values ? *m_ttg_non_system : m_ttg_value_lock);
@ -673,7 +686,7 @@ void Tab::update_dirty()
void Tab::update_tab_ui() void Tab::update_tab_ui()
{ {
m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets); m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets, m_em_unit);
} }
// Load a provied DynamicConfig into the tab, modifying the active preset. // Load a provied DynamicConfig into the tab, modifying the active preset.
@ -726,6 +739,42 @@ void Tab::update_visibility()
update_changed_tree_ui(); update_changed_tree_ui();
} }
void Tab::msw_rescale()
{
m_em_unit = wxGetApp().em_unit();
m_mode_sizer->msw_rescale();
m_presets_choice->SetSize(35 * m_em_unit, -1);
m_treectrl->SetMinSize(wxSize(20 * m_em_unit, -1));
update_tab_ui();
// rescale buttons and cached bitmaps
for (const auto btn : m_scaled_buttons)
btn->msw_rescale();
for (const auto bmp : m_scaled_bitmaps)
bmp->msw_rescale();
for (ScalableBitmap& bmp : m_mode_bitmap_cache)
bmp.msw_rescale();
// rescale icons for tree_ctrl
for (ScalableBitmap& bmp : m_scaled_icons_list)
bmp.msw_rescale();
// recreate and set new ImageList for tree_ctrl
m_icons->RemoveAll();
m_icons = new wxImageList(m_scaled_icons_list.front().bmp().GetWidth(), m_scaled_icons_list.front().bmp().GetHeight());
for (ScalableBitmap& bmp : m_scaled_icons_list)
m_icons->Add(bmp.bmp());
m_treectrl->AssignImageList(m_icons);
// rescale options_groups
for (auto page : m_pages)
page->msw_rescale();
Layout();
}
Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const
{ {
Field* field = nullptr; Field* field = nullptr;
@ -1121,10 +1170,10 @@ void TabPrint::build()
optgroup->append_single_option_line("complete_objects"); optgroup->append_single_option_line("complete_objects");
line = { _(L("Extruder clearance (mm)")), "" }; line = { _(L("Extruder clearance (mm)")), "" };
Option option = optgroup->get_option("extruder_clearance_radius"); Option option = optgroup->get_option("extruder_clearance_radius");
option.opt.width = 60; option.opt.width = 6;
line.append_option(option); line.append_option(option);
option = optgroup->get_option("extruder_clearance_height"); option = optgroup->get_option("extruder_clearance_height");
option.opt.width = 60; option.opt.width = 6;
line.append_option(option); line.append_option(option);
optgroup->append_line(line); optgroup->append_line(line);
@ -1138,14 +1187,14 @@ void TabPrint::build()
optgroup = page->new_optgroup(_(L("Post-processing scripts")), 0); optgroup = page->new_optgroup(_(L("Post-processing scripts")), 0);
option = optgroup->get_option("post_process"); option = optgroup->get_option("post_process");
option.opt.full_width = true; option.opt.full_width = true;
option.opt.height = 5 * m_em_unit;//50; option.opt.height = 5;//50;
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
page = add_options_page(_(L("Notes")), "note.png"); page = add_options_page(_(L("Notes")), "note.png");
optgroup = page->new_optgroup(_(L("Notes")), 0); optgroup = page->new_optgroup(_(L("Notes")), 0);
option = optgroup->get_option("notes"); option = optgroup->get_option("notes");
option.opt.full_width = true; option.opt.full_width = true;
option.opt.height = 25 * m_em_unit;//250; option.opt.height = 25;//250;
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
page = add_options_page(_(L("Dependencies")), "wrench.png"); page = add_options_page(_(L("Dependencies")), "wrench.png");
@ -1458,7 +1507,7 @@ void TabFilament::build()
optgroup->append_single_option_line("bridge_fan_speed"); optgroup->append_single_option_line("bridge_fan_speed");
optgroup->append_single_option_line("disable_fan_first_layers"); optgroup->append_single_option_line("disable_fan_first_layers");
optgroup = page->new_optgroup(_(L("Cooling thresholds")), 250); optgroup = page->new_optgroup(_(L("Cooling thresholds")), 25);
optgroup->append_single_option_line("fan_below_layer_time"); optgroup->append_single_option_line("fan_below_layer_time");
optgroup->append_single_option_line("slowdown_below_layer_time"); optgroup->append_single_option_line("slowdown_below_layer_time");
optgroup->append_single_option_line("min_print_speed"); optgroup->append_single_option_line("min_print_speed");
@ -1508,8 +1557,8 @@ void TabFilament::build()
}; };
optgroup->append_line(line); optgroup->append_line(line);
const int gcode_field_height = 15 * m_em_unit; // 150 const int gcode_field_height = 15; // 150
const int notes_field_height = 25 * m_em_unit; // 250 const int notes_field_height = 25; // 250
page = add_options_page(_(L("Custom G-code")), "cog"); page = add_options_page(_(L("Custom G-code")), "cog");
optgroup = page->new_optgroup(_(L("Start G-code")), 0); optgroup = page->new_optgroup(_(L("Start G-code")), 0);
@ -1606,8 +1655,8 @@ wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticTex
{ {
*StaticText = new ogStaticText(parent, ""); *StaticText = new ogStaticText(parent, "");
auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT); // auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT);
(*StaticText)->SetFont(font); (*StaticText)->SetFont(wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(*StaticText, 1, wxEXPAND|wxALL, 0); sizer->Add(*StaticText, 1, wxEXPAND|wxALL, 0);
@ -1629,10 +1678,10 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
} }
auto printhost_browse = [=](wxWindow* parent) { auto printhost_browse = [=](wxWindow* parent) {
auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots, add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L(" Browse ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); ScalableButton* btn = m_printhost_browse_btn;
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
btn->SetBitmap(create_scaled_bitmap(this, "browse"));
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn); sizer->Add(btn);
@ -1648,10 +1697,9 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
}; };
auto print_host_test = [this](wxWindow* parent) { auto print_host_test = [this](wxWindow* parent) {
auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), add_scaled_button(parent, &m_print_host_test_btn, "test", _(L("Test")), wxBU_LEFT | wxBU_EXACTFIT);
wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); ScalableButton* btn = m_print_host_test_btn;
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
btn->SetBitmap(create_scaled_bitmap(this, "test"));
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn); sizer->Add(btn);
@ -1755,6 +1803,8 @@ void TabPrinter::build_fff()
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter")); auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"));
m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size();
wxGetApp().sidebar().update_objects_list_extruder_column(m_initial_extruders_count);
const Preset* parent_preset = m_presets->get_selected_preset_parent(); const Preset* parent_preset = m_presets->get_selected_preset_parent();
m_sys_extruders_count = parent_preset == nullptr ? 0 : m_sys_extruders_count = parent_preset == nullptr ? 0 :
static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size(); static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size();
@ -1764,9 +1814,9 @@ void TabPrinter::build_fff()
Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
line.widget = [this](wxWindow* parent) { line.widget = [this](wxWindow* parent) {
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); ScalableButton* btn;
btn->SetFont(wxGetApp().small_font()); add_scaled_button(parent, &btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetBitmap(create_scaled_bitmap(this, "printer_white")); btn->SetFont(wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn); sizer->Add(btn);
@ -1881,7 +1931,7 @@ void TabPrinter::build_fff()
m_use_silent_mode = val; m_use_silent_mode = val;
} }
} }
build_extruder_pages(); build_unregular_pages();
update_dirty(); update_dirty();
on_value_change(opt_key, value); on_value_change(opt_key, value);
}); });
@ -1893,8 +1943,8 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line("use_volumetric_e"); optgroup->append_single_option_line("use_volumetric_e");
optgroup->append_single_option_line("variable_layer_height"); optgroup->append_single_option_line("variable_layer_height");
const int gcode_field_height = 15 * m_em_unit; // 150 const int gcode_field_height = 15; // 150
const int notes_field_height = 25 * m_em_unit; // 250 const int notes_field_height = 25; // 250
page = add_options_page(_(L("Custom G-code")), "cog"); page = add_options_page(_(L("Custom G-code")), "cog");
optgroup = page->new_optgroup(_(L("Start G-code")), 0); optgroup = page->new_optgroup(_(L("Start G-code")), 0);
option = optgroup->get_option("start_gcode"); option = optgroup->get_option("start_gcode");
@ -1948,7 +1998,7 @@ void TabPrinter::build_fff()
}; };
optgroup->append_line(line); optgroup->append_line(line);
build_extruder_pages(); build_unregular_pages();
#if 0 #if 0
if (!m_no_controller) if (!m_no_controller)
@ -1965,9 +2015,10 @@ void TabPrinter::build_sla()
Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
line.widget = [this](wxWindow* parent) { line.widget = [this](wxWindow* parent) {
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); ScalableButton* btn;
btn->SetFont(wxGetApp().small_font()); add_scaled_button(parent, &btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetBitmap(create_scaled_bitmap(this, "printer_white")); btn->SetFont(wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn); sizer->Add(btn);
@ -2023,7 +2074,7 @@ void TabPrinter::build_sla()
optgroup = page->new_optgroup(_(L("Print Host upload"))); optgroup = page->new_optgroup(_(L("Print Host upload")));
build_printhost(optgroup.get()); build_printhost(optgroup.get());
const int notes_field_height = 25 * m_em_unit; // 250 const int notes_field_height = 25; // 250
page = add_options_page(_(L("Notes")), "note.png"); page = add_options_page(_(L("Notes")), "note.png");
optgroup = page->new_optgroup(_(L("Notes")), 0); optgroup = page->new_optgroup(_(L("Notes")), 0);
@ -2051,13 +2102,23 @@ void TabPrinter::update_serial_ports()
void TabPrinter::extruders_count_changed(size_t extruders_count) void TabPrinter::extruders_count_changed(size_t extruders_count)
{ {
m_extruders_count = extruders_count; bool is_count_changed = false;
m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count); if (m_extruders_count != extruders_count) {
m_preset_bundle->update_multi_material_filament_presets(); m_extruders_count = extruders_count;
build_extruder_pages(); m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count);
reload_config(); m_preset_bundle->update_multi_material_filament_presets();
on_value_change("extruders_count", extruders_count); is_count_changed = true;
wxGetApp().sidebar().update_objects_list_extruder_column(extruders_count); }
/* This function should be call in any case because of correct updating/rebuilding
* of unregular pages of a Printer Settings
*/
build_unregular_pages();
if (is_count_changed) {
on_value_change("extruders_count", extruders_count);
wxGetApp().sidebar().update_objects_list_extruder_column(extruders_count);
}
} }
void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key) void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key)
@ -2078,12 +2139,12 @@ PageShp TabPrinter::build_kinematics_page()
// Legend for OptionsGroups // Legend for OptionsGroups
auto optgroup = page->new_optgroup(""); auto optgroup = page->new_optgroup("");
optgroup->set_show_modified_btns_val(false); optgroup->set_show_modified_btns_val(false);
optgroup->label_width = 23 * m_em_unit;// 230; optgroup->label_width = 23;// 230;
auto line = Line{ "", "" }; auto line = Line{ "", "" };
ConfigOptionDef def; ConfigOptionDef def;
def.type = coString; def.type = coString;
def.width = 150; def.width = 15;
def.gui_type = "legend"; def.gui_type = "legend";
def.mode = comAdvanced; def.mode = comAdvanced;
def.tooltip = L("Values in this column are for Full Power mode"); def.tooltip = L("Values in this column are for Full Power mode");
@ -2125,12 +2186,23 @@ PageShp TabPrinter::build_kinematics_page()
return page; return page;
} }
/* Previous name build_extruder_pages().
void TabPrinter::build_extruder_pages() *
* This function was renamed because of now it implements not just an extruder pages building,
* but "Machine limits" and "Single extruder MM setup" too
* (These pages can changes according to the another values of a current preset)
* */
void TabPrinter::build_unregular_pages()
{ {
size_t n_before_extruders = 2; // Count of pages before Extruder pages size_t n_before_extruders = 2; // Count of pages before Extruder pages
bool is_marlin_flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin; bool is_marlin_flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin;
/* ! Freeze/Thaw in this function is needed to avoid call OnPaint() for erased pages
* and be cause of application crash, when try to change Preset in moment,
* when one of unregular pages is selected.
* */
Freeze();
// Add/delete Kinematics page according to is_marlin_flavor // Add/delete Kinematics page according to is_marlin_flavor
size_t existed_page = 0; size_t existed_page = 0;
for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already
@ -2175,12 +2247,11 @@ void TabPrinter::build_extruder_pages()
m_has_single_extruder_MM_page = true; m_has_single_extruder_MM_page = true;
} }
// Build missed extruder pages
for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) { for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) {
//# build page //# build page
char buf[512]; const wxString& page_name = wxString::Format(_(L("Extruder %d")), int(extruder_idx + 1));
sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1); auto page = add_options_page(page_name, "funnel", true);
auto page = add_options_page(from_u8(buf), "funnel", true);
m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page); m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page);
auto optgroup = page->new_optgroup(_(L("Size"))); auto optgroup = page->new_optgroup(_(L("Size")));
@ -2223,8 +2294,13 @@ void TabPrinter::build_extruder_pages()
m_pages.erase( m_pages.begin() + n_before_extruders + m_extruders_count, m_pages.erase( m_pages.begin() + n_before_extruders + m_extruders_count,
m_pages.begin() + n_before_extruders + m_extruders_count_old); m_pages.begin() + n_before_extruders + m_extruders_count_old);
Thaw();
m_extruders_count_old = m_extruders_count; m_extruders_count_old = m_extruders_count;
rebuild_page_tree(); rebuild_page_tree();
// Reload preset pages with current configuration values
reload_config();
} }
// this gets executed after preset is loaded and before GUI fields are updated // this gets executed after preset is loaded and before GUI fields are updated
@ -2492,7 +2568,6 @@ void Tab::rebuild_page_tree()
m_treectrl->SelectItem(item); m_treectrl->SelectItem(item);
} }
} }
// Thaw();
} }
void Tab::update_page_tree_visibility() void Tab::update_page_tree_visibility()
@ -2728,7 +2803,8 @@ bool Tab::may_switch_to_SLA_preset()
void Tab::OnTreeSelChange(wxTreeEvent& event) void Tab::OnTreeSelChange(wxTreeEvent& event)
{ {
if (m_disable_tree_sel_changed_event) return; if (m_disable_tree_sel_changed_event)
return;
// There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952. // There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952.
// The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason, // The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason,
@ -2877,7 +2953,7 @@ void Tab::toggle_show_hide_incompatible()
void Tab::update_show_hide_incompatible_button() void Tab::update_show_hide_incompatible_button()
{ {
m_btn_hide_incompatible_presets->SetBitmap(m_show_incompatible_presets ? m_btn_hide_incompatible_presets->SetBitmap_(m_show_incompatible_presets ?
m_bmp_show_incompatible_presets : m_bmp_hide_incompatible_presets); m_bmp_show_incompatible_presets : m_bmp_hide_incompatible_presets);
m_btn_hide_incompatible_presets->SetToolTip(m_show_incompatible_presets ? m_btn_hide_incompatible_presets->SetToolTip(m_show_incompatible_presets ?
"Both compatible an incompatible presets are shown. Click to hide presets not compatible with the current printer." : "Both compatible an incompatible presets are shown. Click to hide presets not compatible with the current printer." :
@ -2909,10 +2985,8 @@ 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());
deps.btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); add_scaled_button(parent, &deps.btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
deps.btn->SetBitmap(create_scaled_bitmap(this, "printer_white"));
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL); sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL);
@ -3069,6 +3143,12 @@ void Page::update_visibility(ConfigOptionMode mode)
m_show = ret_val; m_show = ret_val;
} }
void Page::msw_rescale()
{
for (auto group : m_optgroups)
group->msw_rescale();
}
Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const
{ {
Field* field = nullptr; Field* field = nullptr;
@ -3092,18 +3172,16 @@ bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value
// package Slic3r::GUI::Tab::Page; // package Slic3r::GUI::Tab::Page;
ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_label_width /*= -1*/) ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_label_width /*= -1*/)
{ {
auto extra_column = [](wxWindow* parent, const Line& line) auto extra_column = [this](wxWindow* parent, const Line& line)
{ {
std::string bmp_name; std::string bmp_name;
const std::vector<Option>& options = line.get_options(); const std::vector<Option>& options = line.get_options();
if (options.size() == 0 || options[0].opt.gui_type == "legend") int mode_id = int(options[0].opt.mode);
bmp_name = "";// "error.png"; const wxBitmap& bitmap = options.size() == 0 || options[0].opt.gui_type == "legend" ? wxNullBitmap :
else { m_mode_bitmap_cache[mode_id].bmp();
auto mode = options[0].opt.mode; //we assume that we have one option per line auto bmp = new wxStaticBitmap(parent, wxID_ANY, bitmap);
bmp_name = mode == comExpert ? "mode_expert_.png" : bmp->SetClientData((void*)&m_mode_bitmap_cache[mode_id]);
mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png";
}
auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(parent, bmp_name));
bmp->SetBackgroundStyle(wxBG_STYLE_PAINT); bmp->SetBackgroundStyle(wxBG_STYLE_PAINT);
return bmp; return bmp;
}; };
@ -3142,6 +3220,14 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
return static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent() != nullptr; return static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent() != nullptr;
}; };
optgroup->rescale_extra_column_item = [this](wxWindow* win) {
auto *ctrl = dynamic_cast<wxStaticBitmap*>(win);
if (ctrl == nullptr)
return;
ctrl->SetBitmap(reinterpret_cast<ScalableBitmap*>(ctrl->GetClientData())->bmp());
};
vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);
m_optgroups.push_back(optgroup); m_optgroups.push_back(optgroup);
@ -3222,7 +3308,7 @@ void TabSLAMaterial::build()
optgroup->append_single_option_line("initial_exposure_time"); optgroup->append_single_option_line("initial_exposure_time");
optgroup = page->new_optgroup(_(L("Corrections"))); optgroup = page->new_optgroup(_(L("Corrections")));
optgroup->label_width = 19 * m_em_unit;//190; optgroup->label_width = 19;//190;
std::vector<std::string> corrections = {"material_correction"}; std::vector<std::string> corrections = {"material_correction"};
// std::vector<std::string> axes{ "X", "Y", "Z" }; // std::vector<std::string> axes{ "X", "Y", "Z" };
std::vector<std::string> axes{ "XY", "Z" }; std::vector<std::string> axes{ "XY", "Z" };
@ -3232,7 +3318,7 @@ void TabSLAMaterial::build()
for (auto& axis : axes) { for (auto& axis : axes) {
auto opt = optgroup->get_option(opt_key, id); auto opt = optgroup->get_option(opt_key, id);
opt.opt.label = axis; opt.opt.label = axis;
opt.opt.width = 60; opt.opt.width = 6;
line.append_option(opt); line.append_option(opt);
++id; ++id;
} }
@ -3244,7 +3330,7 @@ void TabSLAMaterial::build()
optgroup->label_width = 0; optgroup->label_width = 0;
Option option = optgroup->get_option("material_notes"); Option option = optgroup->get_option("material_notes");
option.opt.full_width = true; option.opt.full_width = true;
option.opt.height = 25 * m_em_unit;//250; option.opt.height = 25;//250;
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
page = add_options_page(_(L("Dependencies")), "wrench.png"); page = add_options_page(_(L("Dependencies")), "wrench.png");

View File

@ -30,14 +30,14 @@
#include "BedShapeDialog.hpp" #include "BedShapeDialog.hpp"
#include "Event.hpp" #include "Event.hpp"
#include "wxExtensions.hpp"
class PrusaModeSizer;
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
typedef std::pair<wxBitmap*, std::string> t_icon_description;
typedef std::vector<std::pair<wxBitmap*, std::string>> t_icon_descriptions; typedef std::pair<ScalableBitmap*, std::string> t_icon_description;
typedef std::vector<std::pair<ScalableBitmap*, std::string>> t_icon_descriptions;
// Single Tab page containing a{ vsizer } of{ optgroups } // Single Tab page containing a{ vsizer } of{ optgroups }
// package Slic3r::GUI::Tab::Page; // package Slic3r::GUI::Tab::Page;
@ -50,10 +50,11 @@ class Page : public wxScrolledWindow
wxBoxSizer* m_vsizer; wxBoxSizer* m_vsizer;
bool m_show = true; bool m_show = true;
public: public:
Page(wxWindow* parent, const wxString title, const int iconID) : Page(wxWindow* parent, const wxString title, const int iconID, const std::vector<ScalableBitmap>& mode_bmp_cache) :
m_parent(parent), m_parent(parent),
m_title(title), m_title(title),
m_iconID(iconID) m_iconID(iconID),
m_mode_bitmap_cache(mode_bmp_cache)
{ {
Create(m_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); Create(m_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_vsizer = new wxBoxSizer(wxVERTICAL); m_vsizer = new wxBoxSizer(wxVERTICAL);
@ -67,6 +68,7 @@ public:
// Delayed layout after resizing the main window. // Delayed layout after resizing the main window.
bool layout_valid = false; bool layout_valid = false;
const std::vector<ScalableBitmap>& m_mode_bitmap_cache;
public: public:
std::vector <ConfigOptionsGroupShp> m_optgroups; std::vector <ConfigOptionsGroupShp> m_optgroups;
@ -79,6 +81,7 @@ public:
void set_config(DynamicPrintConfig* config_in) { m_config = config_in; } void set_config(DynamicPrintConfig* config_in) { m_config = config_in; }
void reload_config(); void reload_config();
void update_visibility(ConfigOptionMode mode); void update_visibility(ConfigOptionMode mode);
void msw_rescale();
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
bool set_value(const t_config_option_key& opt_key, const boost::any& value); bool set_value(const t_config_option_key& opt_key, const boost::any& value);
ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1); ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1);
@ -119,20 +122,20 @@ protected:
std::string m_name; std::string m_name;
const wxString m_title; const wxString m_title;
wxBitmapComboBox* m_presets_choice; wxBitmapComboBox* m_presets_choice;
wxBitmapButton* m_btn_save_preset; ScalableButton* m_btn_save_preset;
wxBitmapButton* m_btn_delete_preset; ScalableButton* m_btn_delete_preset;
wxBitmapButton* m_btn_hide_incompatible_presets; ScalableButton* m_btn_hide_incompatible_presets;
wxBoxSizer* m_hsizer; wxBoxSizer* m_hsizer;
wxBoxSizer* m_left_sizer; wxBoxSizer* m_left_sizer;
wxTreeCtrl* m_treectrl; wxTreeCtrl* m_treectrl;
wxImageList* m_icons; wxImageList* m_icons;
PrusaModeSizer* m_mode_sizer; ModeSizer* m_mode_sizer;
struct PresetDependencies { struct PresetDependencies {
Preset::Type type = Preset::TYPE_INVALID; Preset::Type type = Preset::TYPE_INVALID;
wxCheckBox *checkbox = nullptr; wxCheckBox *checkbox = nullptr;
wxButton *btn = nullptr; ScalableButton *btn = nullptr;
std::string key_list; // "compatible_printers" std::string key_list; // "compatible_printers"
std::string key_condition; std::string key_condition;
std::string dialog_title; std::string dialog_title;
@ -141,25 +144,27 @@ protected:
PresetDependencies m_compatible_printers; PresetDependencies m_compatible_printers;
PresetDependencies m_compatible_prints; PresetDependencies m_compatible_prints;
wxButton* m_undo_btn; ScalableButton* m_undo_btn;
wxButton* m_undo_to_sys_btn; ScalableButton* m_undo_to_sys_btn;
wxButton* m_question_btn; ScalableButton* m_question_btn;
wxImageList* m_preset_icons;
// Cached bitmaps. // Cached bitmaps.
// A "flag" icon to be displayned next to the preset name in the Tab's combo box. // A "flag" icon to be displayned next to the preset name in the Tab's combo box.
wxBitmap m_bmp_show_incompatible_presets; ScalableBitmap m_bmp_show_incompatible_presets;
wxBitmap m_bmp_hide_incompatible_presets; ScalableBitmap m_bmp_hide_incompatible_presets;
// Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
wxBitmap m_bmp_value_lock; ScalableBitmap m_bmp_value_lock;
wxBitmap m_bmp_value_unlock; ScalableBitmap m_bmp_value_unlock;
wxBitmap m_bmp_white_bullet; ScalableBitmap m_bmp_white_bullet;
// The following bitmap points to either m_bmp_value_unlock or m_bmp_white_bullet, depending on whether the current preset has a parent preset. // The following bitmap points to either m_bmp_value_unlock or m_bmp_white_bullet, depending on whether the current preset has a parent preset.
wxBitmap *m_bmp_non_system; ScalableBitmap *m_bmp_non_system;
// Bitmaps to be shown on the "Undo user changes" button next to each input field. // Bitmaps to be shown on the "Undo user changes" button next to each input field.
wxBitmap m_bmp_value_revert; ScalableBitmap m_bmp_value_revert;
// wxBitmap m_bmp_value_unmodified;
wxBitmap m_bmp_question; std::vector<ScalableButton*> m_scaled_buttons = {};
std::vector<ScalableBitmap*> m_scaled_bitmaps = {};
std::vector<ScalableBitmap> m_scaled_icons_list = {};
std::vector<ScalableBitmap> m_mode_bitmap_cache = {};
// Colors for ui "decoration" // Colors for ui "decoration"
wxColour m_sys_label_clr; wxColour m_sys_label_clr;
@ -236,7 +241,11 @@ public:
virtual bool supports_printer_technology(const PrinterTechnology tech) = 0; virtual bool supports_printer_technology(const PrinterTechnology tech) = 0;
void create_preset_tab(); void create_preset_tab();
void load_current_preset(); void add_scaled_button(wxWindow* parent, ScalableButton** btn, const std::string& icon_name,
const wxString& label = wxEmptyString,
long style = wxBU_EXACTFIT | wxNO_BORDER);
void add_scaled_bitmap(wxWindow* parent, ScalableBitmap& btn, const std::string& icon_name);
void load_current_preset();
void rebuild_page_tree(); void rebuild_page_tree();
void update_page_tree_visibility(); void update_page_tree_visibility();
// Select a new preset, possibly delete the current one. // Select a new preset, possibly delete the current one.
@ -274,6 +283,7 @@ public:
virtual void reload_config(); virtual void reload_config();
void update_mode(); void update_mode();
void update_visibility(); void update_visibility();
void msw_rescale();
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
bool set_value(const t_config_option_key& opt_key, const boost::any& value); bool set_value(const t_config_option_key& opt_key, const boost::any& value);
wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText); wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText);
@ -345,8 +355,8 @@ class TabPrinter : public Tab
void build_printhost(ConfigOptionsGroup *optgroup); void build_printhost(ConfigOptionsGroup *optgroup);
public: public:
wxButton* m_serial_test_btn = nullptr; wxButton* m_serial_test_btn = nullptr;
wxButton* m_print_host_test_btn = nullptr; ScalableButton* m_print_host_test_btn = nullptr;
wxButton* m_printhost_browse_btn = nullptr; ScalableButton* m_printhost_browse_btn = nullptr;
size_t m_extruders_count; size_t m_extruders_count;
size_t m_extruders_count_old = 0; size_t m_extruders_count_old = 0;
@ -368,7 +378,7 @@ public:
void update_serial_ports(); void update_serial_ports();
void extruders_count_changed(size_t extruders_count); void extruders_count_changed(size_t extruders_count);
PageShp build_kinematics_page(); PageShp build_kinematics_page();
void build_extruder_pages(); void build_unregular_pages();
void on_preset_loaded() override; void on_preset_loaded() override;
void init_options_list() override; void init_options_list() override;
bool supports_printer_technology(const PrinterTechnology /* tech */) override { return true; } bool supports_printer_technology(const PrinterTechnology /* tech */) override { return true; }

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,9 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin
wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler); std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler);
wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt=16, const bool is_horizontal = false); int em_unit(wxWindow* win);
wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt = 16, const bool is_horizontal = false);
class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup
{ {
@ -94,91 +96,20 @@ public:
}; };
// *** PrusaCollapsiblePane ***
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class PrusaCollapsiblePane : public wxCollapsiblePane // DataViewBitmapText: helper class used by PrusaBitmapTextRenderer
// ----------------------------------------------------------------------------
class DataViewBitmapText : public wxObject
{ {
public: public:
PrusaCollapsiblePane() {} DataViewBitmapText( const wxString &text = wxEmptyString,
PrusaCollapsiblePane(wxWindow *parent, const wxBitmap& bmp = wxNullBitmap) :
wxWindowID winid, m_text(text),
const wxString& label, m_bmp(bmp)
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxCP_DEFAULT_STYLE,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxCollapsiblePaneNameStr)
{
Create(parent, winid, label, pos, size, style, val, name);
}
~PrusaCollapsiblePane() {}
void OnStateChange(const wxSize& sz); //override/hide of OnStateChange from wxCollapsiblePane
virtual bool Show(bool show = true) override {
wxCollapsiblePane::Show(show);
OnStateChange(GetBestSize());
return true;
}
};
// *** PrusaCollapsiblePaneMSW *** used only #ifdef __WXMSW__
// ----------------------------------------------------------------------------
#ifdef __WXMSW__
class PrusaCollapsiblePaneMSW : public PrusaCollapsiblePane//wxCollapsiblePane
{
wxButton* m_pDisclosureTriangleButton = nullptr;
wxBitmap m_bmp_close;
wxBitmap m_bmp_open;
wxString m_strLabel;
public:
PrusaCollapsiblePaneMSW() {}
PrusaCollapsiblePaneMSW( wxWindow *parent,
wxWindowID winid,
const wxString& label,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxCP_DEFAULT_STYLE,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxCollapsiblePaneNameStr)
{
Create(parent, winid, label, pos, size, style, val, name);
}
~PrusaCollapsiblePaneMSW() {}
bool Create(wxWindow *parent,
wxWindowID id,
const wxString& label,
const wxPoint& pos,
const wxSize& size,
long style,
const wxValidator& val,
const wxString& name);
void UpdateBtnBmp();
void SetLabel(const wxString &label) override;
bool Layout() override;
void Collapse(bool collapse) override;
};
#endif //__WXMSW__
// *****************************************************************************
// ----------------------------------------------------------------------------
// PrusaDataViewBitmapText: helper class used by PrusaBitmapTextRenderer
// ----------------------------------------------------------------------------
class PrusaDataViewBitmapText : public wxObject
{
public:
PrusaDataViewBitmapText(const wxString &text = wxEmptyString,
const wxBitmap& bmp = wxNullBitmap) :
m_text(text), m_bmp(bmp)
{ } { }
PrusaDataViewBitmapText(const PrusaDataViewBitmapText &other) DataViewBitmapText(const DataViewBitmapText &other)
: wxObject(), : wxObject(),
m_text(other.m_text), m_text(other.m_text),
m_bmp(other.m_bmp) m_bmp(other.m_bmp)
@ -186,18 +117,18 @@ public:
void SetText(const wxString &text) { m_text = text; } void SetText(const wxString &text) { m_text = text; }
wxString GetText() const { return m_text; } wxString GetText() const { return m_text; }
void SetBitmap(const wxBitmap &bmp) { m_bmp = bmp; } void SetBitmap(const wxBitmap &bmp) { m_bmp = bmp; }
const wxBitmap &GetBitmap() const { return m_bmp; } const wxBitmap &GetBitmap() const { return m_bmp; }
bool IsSameAs(const PrusaDataViewBitmapText& other) const { bool IsSameAs(const DataViewBitmapText& other) const {
return m_text == other.m_text && m_bmp.IsSameAs(other.m_bmp); return m_text == other.m_text && m_bmp.IsSameAs(other.m_bmp);
} }
bool operator==(const PrusaDataViewBitmapText& other) const { bool operator==(const DataViewBitmapText& other) const {
return IsSameAs(other); return IsSameAs(other);
} }
bool operator!=(const PrusaDataViewBitmapText& other) const { bool operator!=(const DataViewBitmapText& other) const {
return !IsSameAs(other); return !IsSameAs(other);
} }
@ -205,13 +136,13 @@ private:
wxString m_text; wxString m_text;
wxBitmap m_bmp; wxBitmap m_bmp;
wxDECLARE_DYNAMIC_CLASS(PrusaDataViewBitmapText); wxDECLARE_DYNAMIC_CLASS(DataViewBitmapText);
}; };
DECLARE_VARIANT_OBJECT(PrusaDataViewBitmapText) DECLARE_VARIANT_OBJECT(DataViewBitmapText)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// PrusaObjectDataViewModelNode: a node inside PrusaObjectDataViewModel // ObjectDataViewModelNode: a node inside PrusaObjectDataViewModel
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
enum ItemType { enum ItemType {
@ -223,56 +154,73 @@ enum ItemType {
itSettings = 16 itSettings = 16
}; };
class PrusaObjectDataViewModelNode; class ObjectDataViewModelNode;
WX_DEFINE_ARRAY_PTR(PrusaObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray); WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray);
class PrusaObjectDataViewModelNode class ObjectDataViewModelNode
{ {
PrusaObjectDataViewModelNode* m_parent; ObjectDataViewModelNode* m_parent;
MyObjectTreeModelNodePtrArray m_children; MyObjectTreeModelNodePtrArray m_children;
wxBitmap m_empty_bmp; wxBitmap m_empty_bmp;
size_t m_volumes_cnt = 0; size_t m_volumes_cnt = 0;
std::vector< std::string > m_opt_categories; std::vector< std::string > m_opt_categories;
wxString m_name;
wxBitmap& m_bmp = m_empty_bmp;
ItemType m_type;
int m_idx = -1;
bool m_container = false;
wxString m_extruder = "default";
wxBitmap m_action_icon;
std::string m_action_icon_name = "";
Slic3r::ModelVolumeType m_volume_type;
public: public:
PrusaObjectDataViewModelNode(const wxString &name, ObjectDataViewModelNode(const wxString &name,
const wxString& extruder) { const wxString& extruder):
m_parent = NULL; m_parent(NULL),
m_name = name; m_name(name),
m_type = itObject; m_type(itObject),
m_extruder(extruder)
{
#ifdef __WXGTK__ #ifdef __WXGTK__
// it's necessary on GTK because of control have to know if this item will be container // it's necessary on GTK because of control have to know if this item will be container
// in another case you couldn't to add subitem for this item // in another case you couldn't to add subitem for this item
// it will be produce "segmentation fault" // it will be produce "segmentation fault"
m_container = true; m_container = true;
#endif //__WXGTK__ #endif //__WXGTK__
m_extruder = extruder;
set_object_action_icon(); set_action_icon();
} }
PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, ObjectDataViewModelNode(ObjectDataViewModelNode* parent,
const wxString& sub_obj_name, const wxString& sub_obj_name,
const wxBitmap& bmp, const wxBitmap& bmp,
const wxString& extruder, const wxString& extruder,
const int idx = -1 ) { const int idx = -1 ) :
m_parent = parent; m_parent (parent),
m_name = sub_obj_name; m_name (sub_obj_name),
m_bmp = bmp; m_type (itVolume),
m_type = itVolume; m_idx (idx),
m_idx = idx; m_extruder (extruder)
m_extruder = extruder; {
m_bmp = bmp;
#ifdef __WXGTK__ #ifdef __WXGTK__
// it's necessary on GTK because of control have to know if this item will be container // it's necessary on GTK because of control have to know if this item will be container
// in another case you couldn't to add subitem for this item // in another case you couldn't to add subitem for this item
// it will be produce "segmentation fault" // it will be produce "segmentation fault"
m_container = true; m_container = true;
#endif //__WXGTK__ #endif //__WXGTK__
set_part_action_icon();
set_action_icon();
} }
PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, const ItemType type) : ObjectDataViewModelNode(ObjectDataViewModelNode* parent,
m_parent(parent), const ItemType type) :
m_type(type), m_parent(parent),
m_extruder(wxEmptyString) m_type(type),
m_extruder(wxEmptyString)
{ {
if (type == itSettings) { if (type == itSettings) {
m_name = "Settings to modified"; m_name = "Settings to modified";
@ -286,35 +234,28 @@ public:
else if (type == itInstance) { else if (type == itInstance) {
m_idx = parent->GetChildCount(); m_idx = parent->GetChildCount();
m_name = wxString::Format("Instance_%d", m_idx+1); m_name = wxString::Format("Instance_%d", m_idx+1);
set_part_action_icon();
set_action_icon();
} }
} }
~PrusaObjectDataViewModelNode() ~ObjectDataViewModelNode()
{ {
// free all our children nodes // free all our children nodes
size_t count = m_children.GetCount(); size_t count = m_children.GetCount();
for (size_t i = 0; i < count; i++) for (size_t i = 0; i < count; i++)
{ {
PrusaObjectDataViewModelNode *child = m_children[i]; ObjectDataViewModelNode *child = m_children[i];
delete child; delete child;
} }
} }
wxString m_name;
wxBitmap& m_bmp = m_empty_bmp;
ItemType m_type;
int m_idx = -1;
bool m_container = false;
wxString m_extruder = "default";
wxBitmap m_action_icon;
bool IsContainer() const bool IsContainer() const
{ {
return m_container; return m_container;
} }
PrusaObjectDataViewModelNode* GetParent() ObjectDataViewModelNode* GetParent()
{ {
return m_parent; return m_parent;
} }
@ -322,17 +263,17 @@ public:
{ {
return m_children; return m_children;
} }
PrusaObjectDataViewModelNode* GetNthChild(unsigned int n) ObjectDataViewModelNode* GetNthChild(unsigned int n)
{ {
return m_children.Item(n); return m_children.Item(n);
} }
void Insert(PrusaObjectDataViewModelNode* child, unsigned int n) void Insert(ObjectDataViewModelNode* child, unsigned int n)
{ {
if (!m_container) if (!m_container)
m_container = true; m_container = true;
m_children.Insert(child, n); m_children.Insert(child, n);
} }
void Append(PrusaObjectDataViewModelNode* child) void Append(ObjectDataViewModelNode* child)
{ {
if (!m_container) if (!m_container)
m_container = true; m_container = true;
@ -362,7 +303,7 @@ public:
switch (col) switch (col)
{ {
case 0:{ case 0:{
PrusaDataViewBitmapText data; DataViewBitmapText data;
data << variant; data << variant;
m_bmp = data.GetBitmap(); m_bmp = data.GetBitmap();
m_name = data.GetText(); m_name = data.GetText();
@ -400,7 +341,7 @@ public:
} }
// use this function only for childrens // use this function only for childrens
void AssignAllVal(PrusaObjectDataViewModelNode& from_node) void AssignAllVal(ObjectDataViewModelNode& from_node)
{ {
// ! Don't overwrite other values because of equality of this values for all children -- // ! Don't overwrite other values because of equality of this values for all children --
m_name = from_node.m_name; m_name = from_node.m_name;
@ -416,8 +357,8 @@ public:
scnd_id < 0 || scnd_id >= GetChildCount()) scnd_id < 0 || scnd_id >= GetChildCount())
return false; return false;
PrusaObjectDataViewModelNode new_scnd = *GetNthChild(frst_id); ObjectDataViewModelNode new_scnd = *GetNthChild(frst_id);
PrusaObjectDataViewModelNode new_frst = *GetNthChild(scnd_id); ObjectDataViewModelNode new_frst = *GetNthChild(scnd_id);
new_scnd.m_idx = m_children.Item(scnd_id)->m_idx; new_scnd.m_idx = m_children.Item(scnd_id)->m_idx;
new_frst.m_idx = m_children.Item(frst_id)->m_idx; new_frst.m_idx = m_children.Item(frst_id)->m_idx;
@ -428,37 +369,40 @@ public:
} }
// Set action icons for node // Set action icons for node
void set_object_action_icon(); void set_action_icon();
void set_part_action_icon();
bool update_settings_digest(const std::vector<std::string>& categories); void update_settings_digest_bitmaps();
bool update_settings_digest(const std::vector<std::string>& categories);
int volume_type() const { return int(m_volume_type); }
void msw_rescale();
private: private:
friend class PrusaObjectDataViewModel; friend class ObjectDataViewModel;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// PrusaObjectDataViewModel // ObjectDataViewModel
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// custom message the model sends to associated control to notify a last volume deleted from the object: // custom message the model sends to associated control to notify a last volume deleted from the object:
wxDECLARE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent); wxDECLARE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent);
class PrusaObjectDataViewModel :public wxDataViewModel class ObjectDataViewModel :public wxDataViewModel
{ {
std::vector<PrusaObjectDataViewModelNode*> m_objects; std::vector<ObjectDataViewModelNode*> m_objects;
std::vector<wxBitmap*> m_volume_bmps; std::vector<wxBitmap*> m_volume_bmps;
wxDataViewCtrl* m_ctrl{ nullptr }; wxDataViewCtrl* m_ctrl{ nullptr };
public: public:
PrusaObjectDataViewModel(); ObjectDataViewModel();
~PrusaObjectDataViewModel(); ~ObjectDataViewModel();
wxDataViewItem Add(const wxString &name, const int extruder); wxDataViewItem Add(const wxString &name, const int extruder);
wxDataViewItem AddVolumeChild(const wxDataViewItem &parent_item, wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item,
const wxString &name, const wxString &name,
const Slic3r::ModelVolumeType volume_type, const Slic3r::ModelVolumeType volume_type,
const int extruder = 0, const int extruder = 0,
const bool create_frst_child = true); const bool create_frst_child = true);
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num);
wxDataViewItem Delete(const wxDataViewItem &item); wxDataViewItem Delete(const wxDataViewItem &item);
@ -470,76 +414,82 @@ public:
wxDataViewItem GetItemById(int obj_idx); wxDataViewItem GetItemById(int obj_idx);
wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx);
wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx);
int GetIdByItem(const wxDataViewItem& item) const; int GetIdByItem(const wxDataViewItem& item) const;
int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const; int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const;
int GetObjectIdByItem(const wxDataViewItem& item) const; int GetObjectIdByItem(const wxDataViewItem& item) const;
int GetVolumeIdByItem(const wxDataViewItem& item) const; int GetVolumeIdByItem(const wxDataViewItem& item) const;
int GetInstanceIdByItem(const wxDataViewItem& item) const; int GetInstanceIdByItem(const wxDataViewItem& item) const;
void GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx); void GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx);
int GetRowByItem(const wxDataViewItem& item) const; int GetRowByItem(const wxDataViewItem& item) const;
bool IsEmpty() { return m_objects.empty(); } bool IsEmpty() { return m_objects.empty(); }
// helper method for wxLog // helper method for wxLog
wxString GetName(const wxDataViewItem &item) const; wxString GetName(const wxDataViewItem &item) const;
wxBitmap& GetBitmap(const wxDataViewItem &item) const; wxBitmap& GetBitmap(const wxDataViewItem &item) const;
// helper methods to change the model // helper methods to change the model
virtual unsigned int GetColumnCount() const override { return 3;} virtual unsigned int GetColumnCount() const override { return 3;}
virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); } virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); }
virtual void GetValue(wxVariant &variant, virtual void GetValue( wxVariant &variant,
const wxDataViewItem &item, unsigned int col) const override; const wxDataViewItem &item,
virtual bool SetValue(const wxVariant &variant, unsigned int col) const override;
const wxDataViewItem &item, unsigned int col) override; virtual bool SetValue( const wxVariant &variant,
bool SetValue(const wxVariant &variant, const int item_idx, unsigned int col); const wxDataViewItem &item,
unsigned int col) override;
bool SetValue( const wxVariant &variant,
const int item_idx,
unsigned int col);
// wxDataViewItem MoveChildUp(const wxDataViewItem &item);
// wxDataViewItem MoveChildDown(const wxDataViewItem &item);
// For parent move child from cur_volume_id place to new_volume_id // For parent move child from cur_volume_id place to new_volume_id
// Remaining items will moved up/down accordingly // Remaining items will moved up/down accordingly
wxDataViewItem ReorganizeChildren(int cur_volume_id, wxDataViewItem ReorganizeChildren( const int cur_volume_id,
int new_volume_id, const int new_volume_id,
const wxDataViewItem &parent); const wxDataViewItem &parent);
virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override; virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override;
virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override; virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override;
// get object item // get object item
wxDataViewItem GetTopParent(const wxDataViewItem &item) const; wxDataViewItem GetTopParent(const wxDataViewItem &item) const;
virtual bool IsContainer(const wxDataViewItem &item) const override; virtual bool IsContainer(const wxDataViewItem &item) const override;
virtual unsigned int GetChildren(const wxDataViewItem &parent, virtual unsigned int GetChildren(const wxDataViewItem &parent,
wxDataViewItemArray &array) const override; wxDataViewItemArray &array) const override;
void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const; void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const;
// Is the container just a header or an item with all columns // Is the container just a header or an item with all columns
// In our case it is an item with all columns // In our case it is an item with all columns
virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; }
ItemType GetItemType(const wxDataViewItem &item) const ; ItemType GetItemType(const wxDataViewItem &item) const ;
wxDataViewItem GetItemByType(const wxDataViewItem &parent_item, ItemType type) const; wxDataViewItem GetItemByType( const wxDataViewItem &parent_item,
wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const; ItemType type) const;
wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const; wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const;
wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const;
bool IsSettingsItem(const wxDataViewItem &item) const; bool IsSettingsItem(const wxDataViewItem &item) const;
void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories); void UpdateSettingsDigest( const wxDataViewItem &item,
const std::vector<std::string>& categories);
void SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; } void SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; }
void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type); void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type);
void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; }
// Rescale bitmaps for existing Items
void Rescale();
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// PrusaBitmapTextRenderer // BitmapTextRenderer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING #if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING
class PrusaBitmapTextRenderer : public wxDataViewRenderer class BitmapTextRenderer : public wxDataViewRenderer
#else #else
class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer class BitmapTextRenderer : public wxDataViewCustomRenderer
#endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING #endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING
{ {
public: public:
PrusaBitmapTextRenderer(wxDataViewCellMode mode = BitmapTextRenderer(wxDataViewCellMode mode =
#ifdef __WXOSX__ #ifdef __WXOSX__
wxDATAVIEW_CELL_INERT wxDATAVIEW_CELL_INERT
#else #else
@ -550,7 +500,7 @@ public:
#if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING #if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING
); );
#else #else
) : wxDataViewCustomRenderer(wxT("PrusaDataViewBitmapText"), mode, align) {} ) : wxDataViewCustomRenderer(wxT("DataViewBitmapText"), mode, align) {}
#endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING #endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING
bool SetValue(const wxVariant &value); bool SetValue(const wxVariant &value);
@ -578,7 +528,7 @@ public:
bool WasCanceled() const { return m_was_unusable_symbol; } bool WasCanceled() const { return m_was_unusable_symbol; }
private: private:
PrusaDataViewBitmapText m_value; DataViewBitmapText m_value;
bool m_was_unusable_symbol {false}; bool m_was_unusable_symbol {false};
}; };
@ -676,7 +626,37 @@ private:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// PrusaDoubleSlider // ScalableBitmap
// ----------------------------------------------------------------------------
class ScalableBitmap
{
public:
ScalableBitmap() {};
ScalableBitmap( wxWindow *parent,
const std::string& icon_name = "",
const int px_cnt = 16,
const bool is_horizontal = false);
~ScalableBitmap() {}
void msw_rescale();
const wxBitmap& bmp() const { return m_bmp; }
wxBitmap& bmp() { return m_bmp; }
const std::string& name() const{ return m_icon_name; }
private:
wxWindow* m_parent{ nullptr };
wxBitmap m_bmp = wxBitmap();
std::string m_icon_name = "";
int m_px_cnt {16};
bool m_is_horizontal {false};
};
// ----------------------------------------------------------------------------
// DoubleSlider
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// custom message the slider sends to its parent to notify a tick-change: // custom message the slider sends to its parent to notify a tick-change:
@ -693,10 +673,10 @@ enum TicksAction{
taDel taDel
}; };
class PrusaDoubleSlider : public wxControl class DoubleSlider : public wxControl
{ {
public: public:
PrusaDoubleSlider( DoubleSlider(
wxWindow *parent, wxWindow *parent,
wxWindowID id, wxWindowID id,
int lowerValue, int lowerValue,
@ -708,7 +688,9 @@ public:
long style = wxSL_VERTICAL, long style = wxSL_VERTICAL,
const wxValidator& val = wxDefaultValidator, const wxValidator& val = wxDefaultValidator,
const wxString& name = wxEmptyString); const wxString& name = wxEmptyString);
~PrusaDoubleSlider() {} ~DoubleSlider() {}
void msw_rescale();
int GetMinValue() const { return m_min_value; } int GetMinValue() const { return m_min_value; }
int GetMaxValue() const { return m_max_value; } int GetMaxValue() const { return m_max_value; }
@ -717,6 +699,7 @@ public:
int GetLowerValue() const { return m_lower_value; } int GetLowerValue() const { return m_lower_value; }
int GetHigherValue() const { return m_higher_value; } int GetHigherValue() const { return m_higher_value; }
int GetActiveValue() const; int GetActiveValue() const;
wxSize get_min_size() const ;
double GetLowerValueD() { return get_double_value(ssLower); } double GetLowerValueD() { return get_double_value(ssLower); }
double GetHigherValueD() { return get_double_value(ssHigher); } double GetHigherValueD() { return get_double_value(ssHigher); }
wxSize DoGetBestSize() const override; wxSize DoGetBestSize() const override;
@ -801,16 +784,16 @@ private:
int m_max_value; int m_max_value;
int m_lower_value; int m_lower_value;
int m_higher_value; int m_higher_value;
wxBitmap m_bmp_thumb_higher; ScalableBitmap m_bmp_thumb_higher;
wxBitmap m_bmp_thumb_lower; ScalableBitmap m_bmp_thumb_lower;
wxBitmap m_bmp_add_tick_on; ScalableBitmap m_bmp_add_tick_on;
wxBitmap m_bmp_add_tick_off; ScalableBitmap m_bmp_add_tick_off;
wxBitmap m_bmp_del_tick_on; ScalableBitmap m_bmp_del_tick_on;
wxBitmap m_bmp_del_tick_off; ScalableBitmap m_bmp_del_tick_off;
wxBitmap m_bmp_one_layer_lock_on; ScalableBitmap m_bmp_one_layer_lock_on;
wxBitmap m_bmp_one_layer_lock_off; ScalableBitmap m_bmp_one_layer_lock_off;
wxBitmap m_bmp_one_layer_unlock_on; ScalableBitmap m_bmp_one_layer_unlock_on;
wxBitmap m_bmp_one_layer_unlock_off; ScalableBitmap m_bmp_one_layer_unlock_off;
SelectedSlider m_selection; SelectedSlider m_selection;
bool m_is_left_down = false; bool m_is_left_down = false;
bool m_is_right_down = false; bool m_is_right_down = false;
@ -841,26 +824,26 @@ private:
wxPen GREY_PEN; wxPen GREY_PEN;
wxPen LIGHT_GREY_PEN; wxPen LIGHT_GREY_PEN;
std::vector<wxPen*> line_pens; std::vector<wxPen*> m_line_pens;
std::vector<wxPen*> segm_pens; std::vector<wxPen*> m_segm_pens;
std::set<int> m_ticks; std::set<int> m_ticks;
std::vector<std::pair<int,double>> m_values; std::vector<std::pair<int,double>> m_values;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// PrusaLockButton // LockButton
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class PrusaLockButton : public wxButton class LockButton : public wxButton
{ {
public: public:
PrusaLockButton( LockButton(
wxWindow *parent, wxWindow *parent,
wxWindowID id, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize); const wxSize& size = wxDefaultSize);
~PrusaLockButton() {} ~LockButton() {}
void OnButton(wxCommandEvent& event); void OnButton(wxCommandEvent& event);
void OnEnterBtn(wxMouseEvent& event) { enter_button(true); event.Skip(); } void OnEnterBtn(wxMouseEvent& event) { enter_button(true); event.Skip(); }
@ -869,34 +852,72 @@ public:
bool IsLocked() const { return m_is_pushed; } bool IsLocked() const { return m_is_pushed; }
void SetLock(bool lock); void SetLock(bool lock);
void msw_rescale();
protected: protected:
void enter_button(const bool enter); void enter_button(const bool enter);
private: private:
bool m_is_pushed = false; bool m_is_pushed = false;
wxBitmap m_bmp_lock_on; ScalableBitmap m_bmp_lock_on;
wxBitmap m_bmp_lock_off; ScalableBitmap m_bmp_lock_off;
wxBitmap m_bmp_unlock_on; ScalableBitmap m_bmp_unlock_on;
wxBitmap m_bmp_unlock_off; ScalableBitmap m_bmp_unlock_off;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// PrusaModeButton // ScalableButton
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class PrusaModeButton : public wxButton class ScalableButton : public wxButton
{ {
public: public:
PrusaModeButton( ScalableButton(){}
wxWindow *parent, ScalableButton(
wxWindowID id, wxWindow * parent,
const wxString& mode = wxEmptyString, wxWindowID id,
const wxBitmap& bmp_on = wxNullBitmap, const std::string& icon_name = "",
const wxSize& size = wxDefaultSize, const wxString& label = wxEmptyString,
const wxPoint& pos = wxDefaultPosition); const wxSize& size = wxDefaultSize,
~PrusaModeButton() {} const wxPoint& pos = wxDefaultPosition,
long style = wxBU_EXACTFIT | wxNO_BORDER);
ScalableButton(
wxWindow * parent,
wxWindowID id,
const ScalableBitmap& bitmap,
const wxString& label = wxEmptyString,
long style = wxBU_EXACTFIT | wxNO_BORDER);
~ScalableButton() {}
void SetBitmap_(const ScalableBitmap& bmp);
void msw_rescale();
private:
wxWindow* m_parent;
std::string m_current_icon_name = "";
};
// ----------------------------------------------------------------------------
// ModeButton
// ----------------------------------------------------------------------------
class ModeButton : public ScalableButton
{
public:
ModeButton(
wxWindow* parent,
wxWindowID id,
const std::string& icon_name = "",
const wxString& mode = wxEmptyString,
const wxSize& size = wxDefaultSize,
const wxPoint& pos = wxDefaultPosition);
~ModeButton() {}
void OnButton(wxCommandEvent& event); void OnButton(wxCommandEvent& event);
void OnEnterBtn(wxMouseEvent& event) { focus_button(true); event.Skip(); } void OnEnterBtn(wxMouseEvent& event) { focus_button(true); event.Skip(); }
@ -910,8 +931,6 @@ protected:
private: private:
bool m_is_selected = false; bool m_is_selected = false;
wxBitmap m_bmp_on;
wxBitmap m_bmp_off;
wxString m_tt_selected; wxString m_tt_selected;
wxString m_tt_focused; wxString m_tt_focused;
}; };
@ -919,47 +938,49 @@ private:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// PrusaModeSizer // ModeSizer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class PrusaModeSizer : public wxFlexGridSizer class ModeSizer : public wxFlexGridSizer
{ {
public: public:
PrusaModeSizer( wxWindow *parent, int hgap = 10); ModeSizer( wxWindow *parent, int hgap = 10);
~PrusaModeSizer() {} ~ModeSizer() {}
void SetMode(const /*ConfigOptionMode*/int mode); void SetMode(const /*ConfigOptionMode*/int mode);
void msw_rescale();
private: private:
std::vector<PrusaModeButton*> mode_btns; std::vector<ModeButton*> m_mode_btns;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// PrusaMenu // MenuWithSeparators
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class PrusaMenu : public wxMenu class MenuWithSeparators : public wxMenu
{ {
public: public:
PrusaMenu(const wxString& title, long style = 0) MenuWithSeparators(const wxString& title, long style = 0)
: wxMenu(title, style) {} : wxMenu(title, style) {}
PrusaMenu(long style = 0) MenuWithSeparators(long style = 0)
: wxMenu(style) {} : wxMenu(style) {}
~PrusaMenu() {} ~MenuWithSeparators() {}
void DestroySeparators(); void DestroySeparators();
void SetFirstSeparator();
void SetSecondSeparator();
private:
wxMenuItem* m_separator_frst { nullptr }; // use like separator before settings item wxMenuItem* m_separator_frst { nullptr }; // use like separator before settings item
wxMenuItem* m_separator_scnd { nullptr }; // use like separator between settings items wxMenuItem* m_separator_scnd { nullptr }; // use like separator between settings items
}; };
// ******************************* EXPERIMENTS **********************************************
// ******************************************************************************************
#endif // slic3r_GUI_wxExtensions_hpp_ #endif // slic3r_GUI_wxExtensions_hpp_