Merge remote-tracking branch 'remotes/origin/master' into vb_wold_object_manipulation

This commit is contained in:
bubnikv 2019-04-26 17:42:51 +02:00
commit 16560f6e27
66 changed files with 6343 additions and 5258 deletions

View file

@ -32,8 +32,11 @@ void AboutDialogLogo::onRepaint(wxEvent &event)
}
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);
SetBackgroundColour(bgr_clr);
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
@ -42,8 +45,9 @@ AboutDialog::AboutDialog()
main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20);
// logo
auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192));
hsizer->Add(logo, 1, wxALIGN_CENTER_VERTICAL);
m_logo_bitmap = ScalableBitmap(this, "Slic3r_192px.png", 192);
m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bitmap.bmp());
hsizer->Add(m_logo, 1, wxALIGN_CENTER_VERTICAL);
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
hsizer->Add(vsizer, 2, wxEXPAND|wxLEFT, 20);
@ -51,8 +55,7 @@ AboutDialog::AboutDialog()
// title
{
wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize);
wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
title_font.SetWeight(wxFONTWEIGHT_BOLD);
wxFont title_font = GUI::wxGetApp().bold_font();
title_font.SetFamily(wxFONTFAMILY_ROMAN);
title_font.SetPointSize(24);
title->SetFont(title_font);
@ -63,9 +66,9 @@ AboutDialog::AboutDialog()
{
auto version_string = _(L("Version"))+ " " + std::string(SLIC3R_VERSION);
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__
version_font.SetPointSize(9);
version_font.SetPointSize(version_font.GetPointSize()-1);
#else
version_font.SetPointSize(11);
#endif
@ -74,18 +77,18 @@ AboutDialog::AboutDialog()
}
// 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()));
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
m_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
wxFont font = GetFont();
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 bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
const int fs = font.GetPointSize()-1;
int size[] = {fs,fs,fs,fs,fs,fs,fs};
html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
html->SetBorders(2);
m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
m_html->SetBorders(2);
const auto text = wxString::Format(
"<html>"
"<body bgcolor= %s link= %s>"
@ -101,9 +104,9 @@ AboutDialog::AboutDialog()
"</font>"
"</body>"
"</html>", bgr_clr_str, text_clr_str, text_clr_str);
html->SetPage(text);
vsizer->Add(html, 1, wxEXPAND | wxBOTTOM, 10);
html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this);
m_html->SetPage(text);
vsizer->Add(m_html, 1, wxEXPAND | wxBOTTOM, 10);
m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this);
}
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE);
@ -118,6 +121,31 @@ AboutDialog::AboutDialog()
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();
msw_buttons_rescale(this, em, { wxID_CLOSE });
m_html->SetMinSize(wxSize(-1, 16 * em));
m_html->Refresh();
const wxSize& size = wxSize(65 * em, 30 * em);
SetMinSize(size);
Fit();
Refresh();
}
void AboutDialog::onLinkClicked(wxHtmlLinkEvent &event)
{
wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());

View file

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

View file

@ -18,6 +18,7 @@ namespace GUI {
void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt)
{
SetFont(wxGetApp().normal_font());
m_panel = new BedShapePanel(this);
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)
{
// on_change(nullptr);
@ -125,7 +142,7 @@ ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(wxString title)
ConfigOptionsGroupShp optgroup;
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) {
update_shape();
};

View file

@ -16,11 +16,8 @@ namespace GUI {
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
class BedShapePanel : public wxPanel
{
wxChoicebook* m_shape_options_book;
Bed_2D* m_canvas;
std::vector <ConfigOptionsGroupShp> m_optgroups;
public:
BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY) {}
~BedShapePanel() {}
@ -35,18 +32,25 @@ public:
// 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; }
wxChoicebook* m_shape_options_book;
std::vector <ConfigOptionsGroupShp> m_optgroups;
};
class BedShapeDialog : public wxDialog
class BedShapeDialog : public DPIDialog
{
BedShapePanel* m_panel;
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) {}
~BedShapeDialog() {}
void build_dialog(ConfigOptionPoints* default_pt);
std::vector<Vec2d> GetValue() { return m_panel->GetValue(); }
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
};
} // GUI

View file

@ -23,6 +23,8 @@ void BitmapCache::clear()
{
for (std::pair<const std::string, wxBitmap*> &bitmap : m_map)
delete bitmap.second;
m_map.clear();
}
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)
{
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);
image.InitAlpha();
unsigned char* imgdata = image.GetData();

View file

@ -7,6 +7,7 @@
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "I18N.hpp"
#include "wxExtensions.hpp"
namespace Slic3r {
namespace GUI {
@ -23,7 +24,7 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, t_icon_descriptions* ic
// Icon description
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);
std::istringstream f(pair.second);

View file

@ -4,10 +4,12 @@
#include <wx/dialog.h>
#include <vector>
class ScalableBitmap;
namespace Slic3r {
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
{
@ -15,8 +17,6 @@ class ButtonsDescription : public wxDialog
public:
ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions);
~ButtonsDescription() {}
};
} // GUI

View file

@ -6,6 +6,7 @@
#include "libslic3r/Utils.hpp"
#include "GUI_App.hpp"
#include "wxExtensions.hpp"
namespace Slic3r {
namespace GUI {
@ -66,7 +67,7 @@ static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_eve
}
if (! compatible) {
text += "<p align=\"right\">" + _(L("Incompatible with this Slic3r")) + "</p>";
text += "<p align=\"right\">" + wxString::Format(_(L("Incompatible with this %s")), SLIC3R_APP_NAME) + "</p>";
}
else if (! snapshot_active)
text += "<p align=\"right\"><a href=\"" + snapshot.id + "\">" + _(L("Activate")) + "</a></p>";
@ -95,21 +96,26 @@ static wxString generate_html_page(const Config::SnapshotDB &snapshot_db, const
}
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()),
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
{
this->SetFont(wxGetApp().normal_font());
this->SetBackgroundColour(*wxWHITE);
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
this->SetSizer(vsizer);
// 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__
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
int size[] = {11,11,11,11,14,14,14};
#endif
@ -127,6 +133,28 @@ ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db
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();
msw_buttons_rescale(this, em, { wxID_CLOSE});
const wxSize& size = wxSize(45 * em, 40 * em);
SetMinSize(size);
Fit();
Refresh();
}
void ConfigSnapshotDialog::onLinkClicked(wxHtmlLinkEvent &event)
{
m_snapshot_to_activate = event.GetLinkInfo().GetHref();

View file

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

View file

@ -18,6 +18,7 @@
#include <wx/dataview.h>
#include <wx/notebook.h>
#include <wx/display.h>
#include <wx/filefn.h>
#include <wx/debug.h>
#include "libslic3r/Utils.hpp"
@ -81,11 +82,17 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
for (const auto &model : models) {
if (! filter(model)) { continue; }
wxBitmap bitmap(GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str())), wxBITMAP_TYPE_PNG);
wxBitmap bitmap;
int bitmap_width = 0;
const wxString bitmap_file = GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str()));
if (wxFileExists(bitmap_file)) {
bitmap.LoadFile(bitmap_file, wxBITMAP_TYPE_PNG);
bitmap_width = bitmap.GetWidth();
}
auto *title = new wxStaticText(this, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
title->SetFont(font_name);
const int wrap_width = std::max((int)MODEL_MIN_WRAP, bitmap.GetWidth());
const int wrap_width = std::max((int)MODEL_MIN_WRAP, bitmap_width);
title->Wrap(wrap_width);
current_row_width += wrap_width;
@ -187,6 +194,9 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
title_sizer->Add(sel_all_std, 0, wxRIGHT, BTN_SPACING);
title_sizer->Add(sel_all, 0, wxRIGHT, BTN_SPACING);
title_sizer->Add(sel_none);
// fill button indexes used later for buttons rescaling
m_button_indexes = { sel_all_std->GetId(), sel_all->GetId(), sel_none->GetId() };
}
sizer->Add(title_sizer, 0, wxEXPAND | wxBOTTOM, BTN_SPACING);
@ -399,16 +409,20 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for application updates")));
box_slic3r->SetValue(app_config->get("version_check") == "1");
append(box_slic3r);
append_text(wxString::Format(_(L("If enabled, Slic3r checks for new versions of %s online. When a new version becomes available, "
"a notification is displayed at the next application startup (never during program usage). "
"This is only a notification mechanisms, no automatic installation is done.")), SLIC3R_APP_NAME));
append_text(wxString::Format(_(L(
"If enabled, %s checks for new application versions online. When a new version becomes available, "
"a notification is displayed at the next application startup (never during program usage). "
"This is only a notification mechanisms, no automatic installation is done.")), SLIC3R_APP_NAME));
append_spacer(VERTICAL_SPACING);
auto *box_presets = new wxCheckBox(this, wxID_ANY, _(L("Update built-in Presets automatically")));
box_presets->SetValue(app_config->get("preset_update") == "1");
append(box_presets);
append_text(_(L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded into a separate temporary location. When a new preset version becomes available it is offered at application startup.")));
append_text(wxString::Format(_(L(
"If enabled, %s downloads updates of built-in system presets in the background."
"These updates are downloaded into a separate temporary location."
"When a new preset version becomes available it is offered at application startup.")), SLIC3R_APP_NAME));
const auto text_bold = _(L("Updates are never applied without user's consent and never overwrite user's customized settings."));
auto *label_bold = new wxStaticText(this, wxID_ANY, text_bold);
label_bold->SetFont(boldfont);
@ -635,19 +649,24 @@ void PageTemperatures::apply_custom_config(DynamicPrintConfig &config)
ConfigWizardIndex::ConfigWizardIndex(wxWindow *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)
, 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_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_hover(-1)
, last_page((size_t)-1)
{
SetMinSize(bg.GetSize());
SetMinSize(bg.bmp().GetSize());
const wxSize size = GetTextExtent("m");
em = size.x;
em_w = size.x;
em_h = size.y;
// Add logo bitmap.
@ -656,7 +675,10 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent)
// 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.
auto *sizer = new wxBoxSizer(wxVERTICAL);
/* #ys_FIXME_delete_after_testing by VK
auto *logo = new wxStaticBitmap(this, wxID_ANY, bg);
*/
logo = new wxStaticBitmap(this, wxID_ANY, bg.bmp());
sizer->AddStretchSpacer();
sizer->Add(logo);
SetSizer(sizer);
@ -764,8 +786,12 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
wxPaintDC dc(this);
/* #ys_FIXME_delete_after_testing by VK
const auto bullet_w = bullet_black.GetSize().GetWidth();
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_text = bullet_h > em_h ? (bullet_h - em_h) / 2 : 0;
const int yinc = item_height();
@ -775,15 +801,21 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
unsigned y = 0;
for (size_t i = 0; i < items.size(); i++) {
const Item& item = items[i];
unsigned x = em/2 + item.indent * em;
unsigned x = em_w/2 + item.indent * em_w;
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);
}
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); }
*/
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/2;
x += + bullet_w + em_w/2;
const auto text_size = dc.GetTextExtent(item.label);
dc.DrawText(item.label, x, y + yoff_text);
@ -794,6 +826,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
if (GetMinSize().x < index_width) {
CallAfter([this, index_width]() {
SetMinSize(wxSize(index_width, GetMinSize().y));
Refresh();
});
}
}
@ -813,6 +846,18 @@ void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt)
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
@ -987,9 +1032,10 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
// Public
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))
{
this->SetFont(wxGetApp().normal_font());
p->run_reason = reason;
p->load_vendors();
@ -1014,8 +1060,8 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason)
topsizer->AddSpacer(INDEX_MARGIN);
topsizer->Add(p->hscroll, 1, wxEXPAND);
auto *btn_sel_all = new wxButton(this, wxID_ANY, _(L("Select all standard printers")));
p->btnsizer->Add(btn_sel_all);
p->btn_sel_all = new wxButton(this, wxID_ANY, _(L("Select all standard printers")));
p->btnsizer->Add(p->btn_sel_all);
p->btn_prev = new wxButton(this, wxID_ANY, _(L("< &Back")));
p->btn_next = new wxButton(this, wxID_ANY, _(L("&Next >")));
@ -1073,7 +1119,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason)
9*disp_rect.width / 10,
9*disp_rect.height / 10);
const int width_hint = p->index->GetSize().GetWidth() + p->page_fff->get_width() + 300; // XXX: magic constant, I found no better solution
const int width_hint = p->index->GetSize().GetWidth() + p->page_fff->get_width() + 30 * p->em(); // XXX: magic constant, I found no better solution
if (width_hint < window_rect.width) {
window_rect.x += (window_rect.width - width_hint) / 2;
window_rect.width = width_hint;
@ -1087,7 +1133,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason)
p->btn_finish->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { this->EndModal(wxID_OK); });
p->btn_finish->Hide();
btn_sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) {
p->btn_sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) {
p->page_fff->select_all(true, false);
p->page_msla->select_all(true, false);
p->index->go_to(p->page_update);
@ -1133,5 +1179,25 @@ const wxString& ConfigWizard::name(const bool from_menu/* = false*/)
return from_menu ? config_wizard_name_menu : config_wizard_name;
}
void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect)
{
p->index->msw_rescale();
const int& em = em_unit();
msw_buttons_rescale(this, em, { wxID_APPLY,
wxID_CANCEL,
p->btn_sel_all->GetId(),
p->btn_next->GetId(),
p->btn_prev->GetId() });
for (auto printer_picker: p->page_fff->printer_pickers)
msw_buttons_rescale(this, em, printer_picker->get_button_indexes());
// FIXME VK SetSize(???)
Refresh();
}
}
}

View file

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

View file

@ -69,8 +69,11 @@ struct PrinterPicker: wxPanel
void on_checkbox(const Checkbox *cbox, bool checked);
int get_width() const { return width; }
const std::vector<int>& get_button_indexes() { return m_button_indexes; }
private:
int width;
std::vector<int> m_button_indexes;
};
struct ConfigWizardPage: wxPanel
@ -210,7 +213,9 @@ public:
void go_to(ConfigWizardPage *page);
void clear();
void msw_rescale();
int em() const { return em_w; }
private:
struct Item
{
@ -221,20 +226,29 @@ private:
bool operator==(ConfigWizardPage *page) const { return this->page == page; }
};
int em;
int em_w;
int em_h;
/* #ys_FIXME_delete_after_testing by VK
const wxBitmap bg;
const wxBitmap bullet_black;
const wxBitmap bullet_blue;
const wxBitmap bullet_white;
*/
ScalableBitmap bg;
ScalableBitmap bullet_black;
ScalableBitmap bullet_blue;
ScalableBitmap bullet_white;
wxStaticBitmap* logo;
std::vector<Item> items;
size_t item_active;
ssize_t item_hover;
size_t last_page;
int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em) + em; }
/* #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.bmp().GetSize().GetHeight(), em_w) + em_w; }
void on_paint(wxPaintEvent &evt);
void on_mouse_move(wxMouseEvent &evt);
@ -256,6 +270,7 @@ struct ConfigWizard::priv
wxBoxSizer *btnsizer = nullptr;
ConfigWizardPage *page_current = nullptr;
ConfigWizardIndex *index = nullptr;
wxButton *btn_sel_all = nullptr;
wxButton *btn_prev = nullptr;
wxButton *btn_next = nullptr;
wxButton *btn_finish = nullptr;
@ -286,6 +301,8 @@ struct ConfigWizard::priv
void on_custom_setup(bool custom_wanted);
void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater);
int em() const { return index->em(); }
};

View file

@ -21,21 +21,11 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/)
void Field::PostInitialize()
{
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
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(); }));
m_Undo_btn = new RevertButton(m_parent, "bullet_white.png");
m_Undo_to_sys_btn = new RevertButton(m_parent, "bullet_white.png");
//set default bitmap
wxBitmap bmp = create_scaled_bitmap(m_parent, "bullet_white.png");
set_undo_bitmap(&bmp);
set_undo_to_sys_bitmap(&bmp);
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(); }));
switch (m_opt.type)
{
@ -53,6 +43,9 @@ void Field::PostInitialize()
break;
}
// initialize m_unit_value
m_em_unit = em_unit(m_parent);
BUILD();
}
@ -95,6 +88,7 @@ wxString Field::get_tooltip_text(const wxString& default_string)
{
wxString tooltip_text("");
wxString tooltip = _(m_opt.tooltip);
edit_tooltip(tooltip);
if (tooltip.length() > 0)
tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " +
(boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + default_string +
@ -200,8 +194,8 @@ bool is_defined_input_value(wxWindow* win, const ConfigOptionType& type)
void TextCtrl::BUILD() {
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
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);
wxString text_value = wxString("");
@ -345,6 +339,21 @@ boost::any& TextCtrl::get_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::disable() { dynamic_cast<wxTextCtrl*>(window)->Disable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(false); }
@ -359,15 +368,16 @@ void TextCtrl::change_field_value(wxEvent& event)
void CheckBox::BUILD() {
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
bool check_value = m_opt.type == coBool ?
m_opt.default_value->getBool() : m_opt.type == coBools ?
static_cast<const ConfigOptionBools*>(m_opt.default_value)->get_at(m_opt_idx) :
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->SetBackgroundStyle(wxBG_STYLE_PAINT);
temp->SetValue(check_value);
@ -392,12 +402,20 @@ boost::any& CheckBox::get_value()
return m_value;
}
void CheckBox::msw_rescale()
{
Field::msw_rescale();
wxCheckBox* field = dynamic_cast<wxCheckBox*>(window);
field->SetMinSize(wxSize(-1, int(1.5f*field->GetFont().GetPixelSize().y +0.5f)));
}
int undef_spin_val = -9999; //! Probably, It's not necessary
void SpinCtrl::BUILD() {
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
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);
wxString text_value = wxString("");
int default_value = 0;
@ -475,6 +493,11 @@ void SpinCtrl::BUILD() {
else tmp_value = -9999;
#ifdef __WXOSX__
propagate_value();
// Forcibly set the input value for SpinControl, since the value
// inserted from the clipboard is not updated under OSX
if (tmp_value > -9999)
dynamic_cast<wxSpinCtrl*>(window)->SetValue(tmp_value);
#endif
}), temp->GetId());
@ -492,10 +515,18 @@ void SpinCtrl::propagate_value()
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() {
wxSize size(15 * wxGetApp().em_unit(), -1);
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
wxSize size(m_width * m_em_unit, -1);
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);
wxBitmapComboBox* temp;
if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) {
@ -804,11 +835,55 @@ boost::any& Choice::get_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);
size.SetWidth((m_opt.width > 0 ? m_opt.width : m_width) * m_em_unit);
// Set rescaled min height to correct layout
field->SetMinSize(wxSize(-1, int(1.5f*field->GetFont().GetPixelSize().y + 0.5f)));
// Set rescaled size
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()
{
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
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);
// Validate the color
wxString clr_str(static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx));
@ -843,7 +918,7 @@ void PointCtrl::BUILD()
{
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);
double val = default_pt(0);
@ -886,6 +961,16 @@ void PointCtrl::BUILD()
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)
{
if (!win->GetValue().empty())
@ -931,8 +1016,8 @@ boost::any& PointCtrl::get_value()
void StaticText::BUILD()
{
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
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);
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);
@ -946,6 +1031,21 @@ void StaticText::BUILD()
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()
{
auto size = wxSize(wxDefaultSize);

View file

@ -19,6 +19,7 @@
#include "libslic3r/Utils.hpp"
#include "GUI.hpp"
#include "wxExtensions.hpp"
#ifdef __WXMSW__
#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);
class MyButton : public wxButton
class RevertButton : public ScalableButton
{
bool hidden = false; // never show button if it's hidden ones
public:
MyButton() {}
MyButton(wxWindow* parent, wxWindowID id, const wxString& label = wxEmptyString,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = 0,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxTextCtrlNameStr)
{
this->Create(parent, id, label, pos, size, style, validator, name);
}
// RevertButton() {}
// RevertButton(wxWindow* parent, wxWindowID id, const wxString& label = wxEmptyString,
// const wxPoint& pos = wxDefaultPosition,
// const wxSize& size = wxDefaultSize, long style = 0,
// const wxValidator& validator = wxDefaultValidator,
// const wxString& name = wxTextCtrlNameStr)
// {
// 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
virtual bool
@ -154,19 +160,19 @@ public:
return std::move(p); //!p;
}
bool set_undo_bitmap(const wxBitmap *bmp) {
bool set_undo_bitmap(const ScalableBitmap *bmp) {
if (m_undo_bitmap != bmp) {
m_undo_bitmap = bmp;
m_Undo_btn->SetBitmap(*bmp);
m_Undo_btn->SetBitmap_(*bmp);
return true;
}
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) {
m_undo_to_sys_bitmap = bmp;
m_Undo_to_sys_btn->SetBitmap(*bmp);
m_Undo_to_sys_btn->SetBitmap_(*bmp);
return true;
}
return false;
@ -211,15 +217,23 @@ public:
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:
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.
const wxBitmap* m_undo_bitmap = nullptr;
const wxString* m_undo_tooltip = nullptr;
MyButton* m_Undo_to_sys_btn = nullptr;
const ScalableBitmap* m_undo_bitmap = nullptr;
const wxString* m_undo_tooltip = 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.
const wxBitmap* m_undo_to_sys_bitmap = nullptr;
const wxString* m_undo_to_sys_tooltip = nullptr;
const ScalableBitmap* m_undo_to_sys_bitmap = nullptr;
const wxString* m_undo_to_sys_tooltip = 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.
@ -230,6 +244,8 @@ protected:
// current value
boost::any m_value;
int m_em_unit;
bool bEnterPressed = false;
friend class OptionsGroup;
@ -273,6 +289,8 @@ public:
}
boost::any& get_value() override;
void msw_rescale() override;
virtual void enable();
virtual void disable();
@ -301,6 +319,8 @@ public:
}
boost::any& get_value() override;
void msw_rescale() override;
void enable() override { dynamic_cast<wxCheckBox*>(window)->Enable(); }
void disable() override { dynamic_cast<wxCheckBox*>(window)->Disable(); }
wxWindow* getWindow() override { return window; }
@ -337,6 +357,8 @@ public:
return m_value = tmp_value;
}
void msw_rescale() override;
void enable() override { dynamic_cast<wxSpinCtrl*>(window)->Enable(); }
void disable() override { dynamic_cast<wxSpinCtrl*>(window)->Disable(); }
wxWindow* getWindow() override { return window; }
@ -344,6 +366,7 @@ public:
class Choice : public Field {
using Field::Field;
int m_width{ 15 };
public:
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) {}
@ -363,6 +386,8 @@ public:
void set_values(const std::vector<std::string> &values);
boost::any& get_value() override;
void msw_rescale() override;
void enable() override { dynamic_cast<wxBitmapComboBox*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxBitmapComboBox*>(window)->Disable(); };
wxWindow* getWindow() override { return window; }
@ -414,6 +439,8 @@ public:
void set_value(const boost::any& value, bool change_event = false);
boost::any& get_value() override;
void msw_rescale() override;
void enable() override {
x_textctrl->Enable();
y_textctrl->Enable(); }
@ -446,6 +473,8 @@ public:
boost::any& get_value()override { return m_value; }
void msw_rescale() override;
void enable() override { dynamic_cast<wxStaticText*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxStaticText*>(window)->Disable(); };
wxWindow* getWindow() override { return window; }

View file

@ -18,6 +18,7 @@
#include "MsgDialog.hpp"
#include "../Utils/HexFile.hpp"
#include "../Utils/Serial.hpp"
#include "wxExtensions.hpp"
// wx includes need to come after asio because of the WinSock.h problem
#include "FirmwareDialog.hpp"
@ -118,6 +119,10 @@ struct FirmwareDialog::priv
wxTimer timer_pulse;
int min_width;
int min_height;
int min_height_expanded;
// Async modal dialog during flashing
std::mutex mutex;
int modal_response;
@ -732,23 +737,21 @@ const char* FirmwareDialog::priv::avr109_dev_name(Avr109Pid usb_pid) {
// Public
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))
{
enum {
DIALOG_MARGIN = 15,
SPACING = 10,
MIN_WIDTH = 50,
MIN_HEIGHT = 18,
MIN_HEIGHT_EXPANDED = 40,
};
const int em = GUI::wxGetApp().em_unit();
int min_width = MIN_WIDTH * em;
int min_height = MIN_HEIGHT * em;
int min_height_expanded = MIN_HEIGHT_EXPANDED * em;
p->min_width = MIN_WIDTH * em;
p->min_height = MIN_HEIGHT * em;
p->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();
wxFont mono_font(wxFontInfo().Family(wxFONTFAMILY_TELETYPE));
mono_font.MakeSmaller();
@ -819,10 +822,10 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
auto *topsizer = new wxBoxSizer(wxVERTICAL);
topsizer->Add(panel, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
SetMinSize(wxSize(min_width, min_height));
SetMinSize(wxSize(p->min_width, p->min_height));
SetSizerAndFit(topsizer);
const auto size = GetSize();
SetSize(std::max(size.GetWidth(), static_cast<int>(min_width)), std::max(size.GetHeight(), static_cast<int>(min_height)));
SetSize(std::max(size.GetWidth(), static_cast<int>(p->min_width)), std::max(size.GetHeight(), static_cast<int>(p->min_height)));
Layout();
SetEscapeId(wxID_CLOSE); // To close the dialog using "Esc" button
@ -838,11 +841,11 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
p->spoiler->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, [=](wxCollapsiblePaneEvent &evt) {
if (evt.GetCollapsed()) {
this->SetMinSize(wxSize(min_width, min_height));
this->SetMinSize(wxSize(p->min_width, p->min_height));
const auto new_height = this->GetSize().GetHeight() - this->p->txt_stdout->GetSize().GetHeight();
this->SetSize(this->GetSize().GetWidth(), new_height);
} else {
this->SetMinSize(wxSize(min_width, min_height_expanded));
this->SetMinSize(wxSize(p->min_width, p->min_height_expanded));
}
this->Layout();
@ -897,5 +900,25 @@ void FirmwareDialog::run(wxWindow *parent)
dialog.ShowModal();
}
void FirmwareDialog::on_dpi_changed(const wxRect &suggested_rect)
{
const int& em = em_unit();
msw_buttons_rescale(this, em, { p->btn_close->GetId(),
p->btn_rescan->GetId(),
p->btn_flash->GetId(),
p->hex_picker->GetPickerCtrl()->GetId()
});
p->min_width = MIN_WIDTH * em;
p->min_height = MIN_HEIGHT * em;
p->min_height_expanded = MIN_HEIGHT_EXPANDED * em;
const int min_height = p->spoiler->IsExpanded() ? p->min_height_expanded : p->min_height;
SetMinSize(wxSize(p->min_width, min_height));
Fit();
Refresh();
}
}

View file

@ -4,13 +4,22 @@
#include <memory>
#include <wx/dialog.h>
#include "GUI_Utils.hpp"
namespace Slic3r {
class FirmwareDialog: public wxDialog
class FirmwareDialog: public GUI::DPIDialog
{
enum {
DIALOG_MARGIN = 15,
SPACING = 10,
MIN_WIDTH = 50,
MIN_HEIGHT = /*18*/25,
MIN_HEIGHT_EXPANDED = 40,
};
public:
FirmwareDialog(wxWindow *parent);
FirmwareDialog(FirmwareDialog &&) = delete;
@ -20,6 +29,9 @@ public:
~FirmwareDialog();
static void run(wxWindow *parent);
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private:
struct priv;
std::unique_ptr<priv> p;

View file

@ -703,6 +703,7 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool
m_warnings.erase(it);
if (m_warnings.empty()) { // nothing remains to be shown
reset();
m_msg_text = "";// save information for rescaling
return;
}
}
@ -723,6 +724,10 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool
}
_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;
}
@ -789,9 +794,16 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GL
wxString msg = GUI::from_u8(msg_utf8);
wxMemoryDC memDC;
#ifdef __WXMSW__
// set scaled application normal font as default font
wxFont font = wxGetApp().normal_font();
#else
// select default font
const float scale = canvas.get_canvas_size().get_scale_factor();
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale);
#endif
font.MakeLarger();
font.MakeBold();
memDC.SetFont(font);
@ -892,6 +904,14 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
}
}
void GLCanvas3D::WarningTexture::msw_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::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) };
@ -961,13 +981,16 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
const int scaled_square_contour = Px_Square_Contour * scale;
const int scaled_border = Px_Border * scale;
// select default font
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl);
#ifdef __WXMSW__
// set scaled application normal font as default font
wxFont font = wxGetApp().normal_font();
// Disabling ClearType works, but the font returned is very different (much thicker) from the default.
// msw_disable_cleartype(font);
bool cleartype = is_font_cleartype(font);
#else
// select default font
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl);
bool cleartype = false;
#endif /* __WXMSW__ */
@ -3190,6 +3213,11 @@ double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const
return factor * m_bed.get_bounding_box().max_size();
}
void GLCanvas3D::msw_rescale()
{
m_warning_texture.msw_rescale(*this);
}
bool GLCanvas3D::_is_shown_on_screen() const
{
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
@ -3834,7 +3862,8 @@ void GLCanvas3D::_render_gizmos_overlay() const
#if ENABLE_RETINA_GL
m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor());
#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__ */
m_gizmos.render_overlay(*this, m_selection);
@ -3846,7 +3875,8 @@ void GLCanvas3D::_render_toolbar() const
#if ENABLE_RETINA_GL
m_toolbar.set_scale(m_retina_helper->get_scale_factor());
#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
Size cnv_size = get_canvas_size();
@ -3909,7 +3939,8 @@ void GLCanvas3D::_render_view_toolbar() const
#if ENABLE_RETINA_GL
m_view_toolbar.set_scale(m_retina_helper->get_scale_factor());
#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
Size cnv_size = get_canvas_size();

View file

@ -353,6 +353,9 @@ private:
void activate(WarningTexture::Warning warning, bool state, const GLCanvas3D& canvas);
void render(const GLCanvas3D& canvas) const;
// function used to get an information for rescaling of the warning
void msw_rescale(const GLCanvas3D& canvas);
private:
static const unsigned char Background_Color[3];
static const unsigned char Opacity;
@ -360,6 +363,10 @@ private:
int m_original_width;
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.
std::vector<Warning> m_warnings;
@ -587,6 +594,8 @@ public:
double get_size_proportional_to_max_bed_size(double factor) const;
void msw_rescale();
private:
bool _is_shown_on_screen() const;

View file

@ -325,6 +325,17 @@ void GUI_App::init_fonts()
#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) {
m_color_label_modified = clr;
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue());
@ -652,7 +663,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Check(get_mode() == comAdvanced); }, config_id_base + ConfigMenuModeAdvanced);
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Check(get_mode() == comExpert); }, config_id_base + ConfigMenuModeExpert);
local_menu->AppendSubMenu(mode_menu, _(L("Mode")), _(L("Slic3r View Mode")));
local_menu->AppendSubMenu(mode_menu, _(L("Mode")), wxString::Format(_(L("%s View Mode")), SLIC3R_APP_NAME));
local_menu->AppendSeparator();
local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application &Language")));
local_menu->AppendSeparator();
@ -669,6 +680,12 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
// Take a configuration snapshot.
if (check_unsaved_changes()) {
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)
app_config->set("on_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);
if (select_language(names, identifiers)) {
save_language();
// show_info(mainframe->m_tabpanel, _(L("Application will be restarted")), _(L("Attention!")));
_3DScene::remove_all_canvases();// remove all canvas before recreate GUI
recreate_GUI();
}

View file

@ -98,6 +98,7 @@ public:
void init_label_colours();
void update_label_colours_from_appconfig();
void init_fonts();
void update_fonts();
void set_label_clr_modified(const wxColour& clr);
void set_label_clr_sys(const wxColour& clr);
@ -139,6 +140,8 @@ public:
bool checked_tab(Tab* tab);
void load_current_presets();
wxString current_language_code() { return m_wxLocale != nullptr ? m_wxLocale->GetCanonicalName() : wxString("en_US"); }
virtual bool OnExceptionInMainLoop();
#ifdef __APPLE__

View file

@ -163,7 +163,7 @@ void ObjectList::create_objects_ctrl()
m_sizer = new wxBoxSizer(wxVERTICAL);
m_sizer->Add(this, 1, wxGROW);
m_objects_model = new PrusaObjectDataViewModel;
m_objects_model = new ObjectDataViewModel;
AssociateModel(m_objects_model);
m_objects_model->SetAssociatedControl(this);
#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
@ -173,7 +173,7 @@ void ObjectList::create_objects_ctrl()
// column 0(Icon+Text) of the view control:
// 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));
// column 1 of the view control:
@ -203,7 +203,7 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt)
if (col->GetTitle() == " " && GetSelectedItemsCount()<2)
GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings")));
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);
auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats;
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()
{
m_bmp_modifiermesh = create_scaled_bitmap(nullptr, "add_modifier");
m_bmp_solidmesh = create_scaled_bitmap(nullptr, "add_part");
m_bmp_support_enforcer = create_scaled_bitmap(nullptr, "support_enforcer");
m_bmp_support_blocker = create_scaled_bitmap(nullptr, "support_blocker");
m_bmp_modifiermesh = ScalableBitmap(nullptr, "add_modifier"); // Add part
m_bmp_solidmesh = ScalableBitmap(nullptr, "add_part"); // Add modifier
m_bmp_support_enforcer = ScalableBitmap(nullptr, "support_enforcer");// Add support enforcer
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.push_back(&m_bmp_solidmesh); // Add part
m_bmp_vector.push_back(&m_bmp_modifiermesh); // Add modifier
m_bmp_vector.push_back(&m_bmp_support_enforcer); // Add support enforcer
m_bmp_vector.push_back(&m_bmp_support_blocker); // Add support blocker
m_bmp_vector.push_back(&m_bmp_solidmesh.bmp());
m_bmp_vector.push_back(&m_bmp_modifiermesh.bmp());
m_bmp_vector.push_back(&m_bmp_support_enforcer.bmp());
m_bmp_vector.push_back(&m_bmp_support_blocker.bmp());
// Set volumes default bitmaps for the model
m_objects_model->SetVolumeBitmaps(m_bmp_vector);
// 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
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
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);
}
m_parts_changed = true;
parts_changed(obj_idx);
changed_object(obj_idx);
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));
}
m_parts_changed = true;
wxGetApp().plater()->changed_objects(object_idxs);
m_parts_changed = false;
select_items(items);
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
@ -534,7 +575,7 @@ void ObjectList::OnContextMenu(wxDataViewEvent&)
if (title == " ")
show_context_menu();
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())
fix_through_netfabb();
@ -703,8 +744,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
select_item(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id,
m_objects_model->GetParent(item)));
m_parts_changed = true;
parts_changed(m_dragged_data.obj_idx());
changed_object(m_dragged_data.obj_idx());
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)
{
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_)
{
PrusaMenu* menu = dynamic_cast<PrusaMenu*>(menu_);
MenuWithSeparators* menu = dynamic_cast<MenuWithSeparators*>(menu_);
const wxString menu_name = _(L("Add settings"));
// Delete old items from settings popupmenu
@ -1053,7 +1093,7 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
if (printer_technology() == ptFFF ||
menu->GetMenuItems().size() > 0 && !menu->GetMenuItems().back()->IsSeparator())
menu->m_separator_frst = menu->AppendSeparator();
menu->SetFirstSeparator();
// Add frequently settings
create_freq_settings_popupmenu(menu);
@ -1061,11 +1101,11 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
if (mode == comAdvanced)
return nullptr;
menu->m_separator_scnd = menu->AppendSeparator();
menu->SetSecondSeparator();
// Add full settings list
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));
@ -1290,7 +1330,7 @@ void ObjectList::load_subobject(ModelVolumeType type)
wxArrayString part_names;
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) {
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);
m_parts_changed = false;
wxArrayString input_files;
wxGetApp().import_model(parent, input_files);
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
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
m_parts_changed = true;
}
}
}
@ -1486,8 +1523,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
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
m_parts_changed = true;
parts_changed(obj_idx);
changed_object(obj_idx);
const auto object_item = m_objects_model->GetTopParent(GetSelection());
select_item(m_objects_model->AddVolumeChild(object_item, name, type));
@ -1551,8 +1587,7 @@ void ObjectList::del_instances_from_object(const int obj_idx)
(*m_objects)[obj_idx]->invalidate_bounding_box(); // ? #ys_FIXME
m_parts_changed = true;
parts_changed(obj_idx);
changed_object(obj_idx);
}
bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type)
@ -1597,8 +1632,7 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
else
return false;
m_parts_changed = true;
parts_changed(obj_idx);
changed_object(obj_idx);
return true;
}
@ -1648,8 +1682,7 @@ void ObjectList::split()
if (parent == item)
Expand(parent);
m_parts_changed = true;
parts_changed(obj_idx);
changed_object(obj_idx);
}
bool ObjectList::get_volume_by_item(const wxDataViewItem& item, ModelVolume*& volume)
@ -1706,17 +1739,10 @@ bool ObjectList::can_split_instances()
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(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;
wxGetApp().plater()->changed_object(obj_idx < 0 ? get_selected_obj_idx() : obj_idx);
}
void ObjectList::part_selection_changed()
@ -1819,7 +1845,7 @@ void ObjectList::add_object_to_list(size_t obj_idx)
stats.facets_added + stats.facets_reversed + stats.backwards_edges;
if (errors > 0) {
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);
}
@ -2439,8 +2465,7 @@ void ObjectList::change_part_type()
volume->set_type(new_type);
m_objects_model->SetVolumeType(item, new_type);
m_parts_changed = true;
parts_changed(get_selected_obj_idx());
changed_object(get_selected_obj_idx());
// Update settings showing, if we have it
//(we show additional settings for Part and Modifier and hide it for Support Blocker/Enforcer)
@ -2620,7 +2645,7 @@ void ObjectList::rename_item()
wxVariant valueOld;
m_objects_model->GetValue(valueOld, item, 0);
PrusaDataViewBitmapText bmpText;
DataViewBitmapText bmpText;
bmpText << valueOld;
// But replace the text with the value entered by user.
@ -2668,11 +2693,29 @@ void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) co
if (errors == 0) {
// delete Error_icon if all errors are fixed
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);
}
}
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)
{
if (event.GetColumn() == 0)
@ -2686,7 +2729,7 @@ void ObjectList::OnEditingDone(wxDataViewEvent &event)
if (event.GetColumn() != 0)
return;
const auto renderer = dynamic_cast<PrusaBitmapTextRenderer*>(GetColumn(0)->GetRenderer());
const auto renderer = dynamic_cast<BitmapTextRenderer*>(GetColumn(0)->GetRenderer());
if (renderer->WasCanceled())
show_error(this, _(L("The supplied name is not valid;")) + "\n" +

View file

@ -13,8 +13,8 @@
class wxBoxSizer;
class wxMenuItem;
class PrusaObjectDataViewModel;
class PrusaMenu;
class ObjectDataViewModel;
class MenuWithSeparators;
namespace Slic3r {
class ConfigOptionsGroup;
@ -108,18 +108,18 @@ class ObjectList : public wxDataViewCtrl
wxBoxSizer *m_sizer {nullptr};
wxWindow *m_parent {nullptr};
wxBitmap m_bmp_modifiermesh;
wxBitmap m_bmp_solidmesh;
wxBitmap m_bmp_support_enforcer;
wxBitmap m_bmp_support_blocker;
wxBitmap m_bmp_manifold_warning;
wxBitmap m_bmp_cog;
wxBitmap m_bmp_split;
ScalableBitmap m_bmp_modifiermesh;
ScalableBitmap m_bmp_solidmesh;
ScalableBitmap m_bmp_support_enforcer;
ScalableBitmap m_bmp_support_blocker;
ScalableBitmap m_bmp_manifold_warning;
ScalableBitmap m_bmp_cog;
ScalableBitmap m_bmp_split;
PrusaMenu m_menu_object;
PrusaMenu m_menu_part;
PrusaMenu m_menu_sla_object;
PrusaMenu m_menu_instance;
MenuWithSeparators m_menu_object;
MenuWithSeparators m_menu_part;
MenuWithSeparators m_menu_sla_object;
MenuWithSeparators m_menu_instance;
wxMenuItem* m_menu_item_split { nullptr };
wxMenuItem* m_menu_item_split_part { nullptr };
wxMenuItem* m_menu_item_settings { nullptr };
@ -139,9 +139,6 @@ class ObjectList : public wxDataViewCtrl
// update_settings_items - updating canvas selection is undesirable,
// 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;
wxDataViewItem m_last_selected_item {nullptr};
@ -157,7 +154,7 @@ public:
std::map<std::string, wxBitmap> CATEGORY_ICON;
PrusaObjectDataViewModel *m_objects_model{ nullptr };
ObjectDataViewModel *m_objects_model{ nullptr };
DynamicPrintConfig *m_config {nullptr};
std::vector<ModelObject*> *m_objects{ nullptr };
@ -176,6 +173,7 @@ public:
void update_extruder_values_for_items(const int max_extruder);
void init_icons();
void rescale_icons();
void set_tooltip_for_item(const wxPoint& pt);
@ -225,11 +223,8 @@ public:
wxBoxSizer* get_sizer() {return m_sizer;}
int get_selected_obj_idx() 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();
// Add object to the list
@ -291,6 +286,8 @@ public:
void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes);
void paste_objects_into_list(const std::vector<size_t>& object_idxs);
void msw_rescale();
private:
void OnChar(wxKeyEvent& event);
void OnContextMenu(wxDataViewEvent &event);

View file

@ -67,7 +67,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
#endif // __APPLE__
{
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->m_on_change = std::bind(&ObjectManipulation::on_change, this, std::placeholders::_1, std::placeholders::_2);
@ -89,11 +89,11 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
def.label = L("Name");
def.gui_type = "legend";
def.tooltip = L("Object name");
def.width = 21 * wxGetApp().em_unit();
def.width = 21;
def.default_value = new ConfigOptionString{ " " };
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
auto line = Line{ "", "" };
@ -126,7 +126,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
// Add "uniform scaling" button in front of "Scale" option
if (option_name == "Scale") {
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){
event.Skip();
wxTheApp->CallAfter([btn, this]() { set_uniform_scaling(btn->IsLocked()); });
@ -164,15 +164,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("Size"), "mm"));
/* Unused parameter at this time
def.label = L("Place on bed");
def.type = coBool;
def.tooltip = L("Automatic placing of models on printing bed in Y axis");
def.gui_type = "";
def.sidetext = "";
def.default_value = new ConfigOptionBool{ false };
m_og->append_single_option_line(Option(def, "place_on_bed"));
*/
// call back for a rescale of button "Set uniform scale"
m_og->rescale_near_label_widget = [this](wxWindow* win) {
auto *ctrl = dynamic_cast<LockButton*>(win);
if (ctrl == nullptr)
return;
ctrl->msw_rescale();
};
}
void ObjectManipulation::Show(const bool show)

View file

@ -7,7 +7,7 @@
#include "GLCanvas3D.hpp"
class wxStaticText;
class PrusaLockButton;
class LockButton;
namespace Slic3r {
namespace GUI {
@ -82,7 +82,7 @@ class ObjectManipulation : public OG_Settings
bool m_uniform_scale {true};
// Does the object manipulation panel work in World or Local coordinates?
bool m_world_coordinates = true;
PrusaLockButton* m_lock_bnt{ nullptr };
LockButton* m_lock_bnt{ nullptr };
wxBitmapComboBox* m_word_local_combo = nullptr;
#ifndef __APPLE__

View file

@ -59,6 +59,8 @@ ObjectSettings::ObjectSettings(wxWindow* parent) :
m_settings_list_sizer = new wxBoxSizer(wxVERTICAL);
m_og->sizer->Add(m_settings_list_sizer, 1, wxEXPAND | wxLEFT, 5);
m_bmp_delete = ScalableBitmap(parent, "cross");
}
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 btn = new wxBitmapButton(parent, wxID_ANY, create_scaled_bitmap(m_parent, "cross"/*"colorchange_delete_on.png"*/),
wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
#ifdef __WXMSW__
btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif // __WXMSW__
auto btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete);
btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) {
config->erase(opt_key);
wxGetApp().obj_list()->part_settings_changed();
wxGetApp().obj_list()->changed_object();
wxTheApp->CallAfter([this]() {
wxWindowUpdateLocker noUpdates(m_parent);
update_settings_list();
@ -123,22 +122,31 @@ void ObjectSettings::update_settings_list()
continue;
auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), cat.first, config, false, extra_column);
optgroup->label_width = 15 * wxGetApp().em_unit();
optgroup->sidetext_width = 5.5 * wxGetApp().em_unit();
optgroup->label_width = 15;
optgroup->sidetext_width = 5.5;
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)
{
if (opt == "extruder")
continue;
Option option = optgroup->get_option(opt);
option.opt.width = 12 * wxGetApp().em_unit();
option.opt.width = 12;
optgroup->append_single_option_line(option);
}
optgroup->reload_config();
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);
categories.push_back(cat.first);
@ -163,5 +171,13 @@ void ObjectSettings::UpdateAndShow(const bool 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 Slic3r

View file

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

View file

@ -396,6 +396,18 @@ void Preview::refresh_print()
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()
{
this->Bind(wxEVT_SIZE, &Preview::on_size, this);
@ -507,7 +519,7 @@ void Preview::on_checkbox_shells(wxCommandEvent& evt)
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);
// sizer, m_canvas_widget

View file

@ -13,7 +13,7 @@ class wxStaticText;
class wxChoice;
class wxComboCtrl;
class wxCheckBox;
class PrusaDoubleSlider;
class DoubleSlider;
namespace Slic3r {
@ -99,7 +99,7 @@ class Preview : public wxPanel
bool m_loaded;
bool m_enabled;
PrusaDoubleSlider* m_slider {nullptr};
DoubleSlider* m_slider {nullptr};
public:
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 refresh_print();
void msw_rescale();
private:
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/dcclient.h>
#include <wx/debug.h>
#include <wx/settings.h>
class wxCheckBox;
class wxTopLevelWindow;
@ -58,35 +59,119 @@ public:
: P(parent, id, title, pos, size, style, name)
{
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();
this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) {
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() {}
float scale_factor() const { return m_scale_factor; }
int em_unit() const { return m_em_unit; }
int font_size() const { return m_font_size; }
float scale_factor() const { return m_scale_factor; }
float prev_scale_factor() const { return m_prev_scale_factor; }
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:
virtual void on_dpi_changed(const wxRect &suggested_rect) = 0;
private:
int m_scale_factor;
float m_scale_factor;
int m_em_unit;
int m_font_size;
wxFont m_normal_font;
float m_prev_scale_factor;
bool m_can_rescale{ true };
void recalc_font()
{
wxClientDC dc(this);
const auto metrics = dc.GetFontMetrics();
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;

View file

@ -10,26 +10,28 @@ namespace Slic3r {
namespace GUI {
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);
// logo
const wxBitmap logo_bmp = create_scaled_bitmap(this, "Slic3r_32px.png", 32);
m_logo_bmp = ScalableBitmap(this, "Slic3r_32px.png", 32);
// 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__
head_font.SetPointSize(14);
#else
head_font.SetPointSize(12);
head_font.SetPointSize(bold_font.GetPointSize() + 2);
#endif // __WXOSX__
const wxFont& font = wxGetApp().small_font();
const wxFont& bold_font = wxGetApp().bold_font();
fill_shortcuts();
auto panel = new wxPanel(this);
@ -43,22 +45,25 @@ KBShortcutsDialog::KBShortcutsDialog()
wxBoxSizer* r_sizer = new wxBoxSizer(wxVERTICAL);
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)
{
// auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer;
auto sizer = sc.second.second == 0 ? l_sizer : r_sizer;
auto sizer = sc.second.second == szLeft ? l_sizer : r_sizer;
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
// logo
auto *logo = new wxStaticBitmap(panel, wxID_ANY, logo_bmp);
hsizer->Add(logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 15);
m_head_bitmaps.push_back(new wxStaticBitmap(panel, wxID_ANY, m_logo_bmp.bmp()));
hsizer->Add(m_head_bitmaps.back(), 0, wxEXPAND | wxLEFT | wxRIGHT, 15);
// 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);
hsizer->Add(head, 0, wxALIGN_CENTER_VERTICAL);
// Shortcuts list
auto grid_sizer = new wxFlexGridSizer(2, 5, 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(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;
@ -148,7 +153,7 @@ void KBShortcutsDialog::fill_shortcuts()
plater_shortcuts.push_back(Shortcut("O", L("Zoom out")));
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;
@ -168,7 +173,7 @@ void KBShortcutsDialog::fill_shortcuts()
preview_shortcuts.push_back(Shortcut("U", L("Upper 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;
@ -181,7 +186,26 @@ 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("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();
msw_buttons_rescale(this, em, { wxID_OK });
const wxSize& size = wxSize(85 * em, 75 * em);
SetMinSize(size);
Fit();
Refresh();
}
void KBShortcutsDialog::onCloseDialog(wxEvent &)

View file

@ -5,24 +5,38 @@
#include <map>
#include <vector>
#include "GUI_Utils.hpp"
#include "wxExtensions.hpp"
namespace Slic3r {
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::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};
ShortcutsVec m_full_shortcuts;
ShortcutsVec m_full_shortcuts;
ScalableBitmap m_logo_bmp;
std::vector<wxStaticBitmap*> m_head_bitmaps;
public:
KBShortcutsDialog();
void fill_shortcuts();
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private:
void onCloseDialog(wxEvent &);
};

View file

@ -258,7 +258,44 @@ bool MainFrame::can_delete_all() const
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();
// Workarounds for correct Window rendering after rescale
/* Even if Window is maximized during moving,
* first of all we should imitate Window resizing. So:
* 1. cancel maximization, if it was set
* 2. imitate resizing
* 3. set maximization, if it was set
*/
const bool is_maximized = this->IsMaximized();
if (is_maximized)
this->Maximize(false);
/* 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);
this->Maximize(is_maximized);
}
void MainFrame::init_menubar()
@ -337,7 +374,7 @@ void MainFrame::init_menubar()
append_menu_item(fileMenu, wxID_ANY, _(L("&Repair STL file")) + dots, _(L("Automatically repair an STL file")),
[this](wxCommandEvent&) { repair_stl(); }, "wrench");
fileMenu->AppendSeparator();
append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), _(L("Quit Slic3r")),
append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), wxString::Format(_(L("Quit %s")), SLIC3R_APP_NAME),
[this](wxCommandEvent&) { Close(false); });
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater != nullptr); }, item_open->GetId());
@ -474,9 +511,11 @@ void MainFrame::init_menubar()
//# wxTheApp->check_version(1);
//# });
//# $versioncheck->Enable(wxTheApp->have_version_check);
append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Website")), _(L("Open the Slic3r website in your browser")),
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_(L("%s &Website")), SLIC3R_APP_NAME),
wxString::Format(_(L("Open the %s website in your browser")), SLIC3R_APP_NAME),
[this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://slic3r.org/"); });
append_menu_item(helpMenu, wxID_ANY, _(L("Slic3r &Manual")), _(L("Open the Slic3r manual in your browser")),
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_(L("%s &Manual")), SLIC3R_APP_NAME),
wxString::Format(_(L("Open the %s manual in your browser")), SLIC3R_APP_NAME),
[this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://manual.slic3r.org/"); });
helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, _(L("System &Info")), _(L("Show system information")),

View file

@ -4,6 +4,7 @@
#include "libslic3r/PrintConfig.hpp"
#include <wx/frame.h>
#include <wx/settings.h>
#include <wx/string.h>
#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)
: 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))
, btn_sizer(new wxBoxSizer(wxHORIZONTAL))
{
boldfont.SetWeight(wxFONTWEIGHT_BOLD);
this->SetFont(wxGetApp().normal_font());
auto *topsizer = new wxBoxSizer(wxHORIZONTAL);
auto *rightsizer = new wxBoxSizer(wxVERTICAL);
@ -68,7 +70,8 @@ MsgDialog::~MsgDialog() {}
// ErrorDialog
ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg)
: MsgDialog(parent, _(L("Slic3r error")), _(L("Slic3r has encountered an error")),
: MsgDialog(parent, wxString::Format(_(L("%s error")), SLIC3R_APP_NAME),
wxString::Format(_(L("%s has encountered an error")), SLIC3R_APP_NAME),
wxID_NONE)
, msg(msg)
{

View file

@ -166,37 +166,45 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
#endif /* __WXGTK__ */
// if we have an extra column, build it
if (extra_column)
grid_sizer->Add(extra_column(this->ctrl_parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3);
if (extra_column)
{
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
wxStaticText* label=nullptr;
if (label_width != 0) {
if (! line.near_label_widget || ! line.label.IsEmpty()) {
// Only create the label if it is going to be displayed.
long label_style = staticbox ? 0 : wxALIGN_RIGHT;
#ifdef __WXGTK__
#ifdef __WXGTK__
// workaround for correct text align of the StaticBox on Linux
// flags wxALIGN_RIGHT and wxALIGN_CENTRE don't work when Ellipsize flags are _not_ given.
// Text is properly aligned only when Ellipsize is checked.
label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END;
#endif /* __WXGTK__ */
#endif /* __WXGTK__ */
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->SetFont(label_font);
label->Wrap(label_width); // avoid a Linux/GTK bug
label->SetFont(wxGetApp().normal_font());
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);
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 {
// 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(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT, 7);
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5);
m_near_label_widget_ptrs.push_back(line.near_label_widget(this->ctrl_parent()));
if (line.label.IsEmpty())
grid_sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7);
else {
// 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 (label != nullptr && line.label_tooltip != "")
label->SetToolTip(line.label_tooltip);
@ -237,14 +245,13 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
wxSizer* sizer_tmp = sizer;
// add label if any
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
wxString str_label = (option.label == "Top" || option.label == "Bottom") ?
_CTX(option.label, "Layers") :
_(option.label);
label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize);
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);
}
@ -269,9 +276,9 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
// add sidetext if any
if (option.sidetext != "") {
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->SetFont(sidetext_font);
sidetext->SetFont(wxGetApp().normal_font());
sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
field->set_side_text_ptr(sidetext);
}
@ -303,7 +310,10 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
}
Line OptionsGroup::create_single_option_line(const Option& option) const {
Line retval{ _(option.opt.label), _(option.opt.tooltip) };
// Line retval{ _(option.opt.label), _(option.opt.tooltip) };
wxString tooltip = _(option.opt.tooltip);
edit_tooltip(tooltip);
Line retval{ _(option.opt.label), tooltip };
Option tmp(option);
tmp.opt.label = std::string("");
retval.append_option(tmp);
@ -479,6 +489,59 @@ bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) {
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) {
const int label_height = int(1.5f*label->GetFont().GetPixelSize().y + 0.5f);
label->SetMinSize(wxSize(label_width*em, /*-1*/label_height));
}
}
else if (label_item->IsSizer()) // case when we have 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) {
const int label_height = int(1.5f*label->GetFont().GetPixelSize().y + 0.5f);
label->SetMinSize(wxSize(label_width*em, /*-1*/label_height));
}
}
}
}
m_grid_sizer->Layout();
}
}
boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize) {
if (deserialize) {

View file

@ -72,7 +72,7 @@ private:
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_opt_map = std::map< std::string, std::pair<std::string, int> >;
@ -82,7 +82,7 @@ class OptionsGroup {
public:
const bool staticbox {true};
const wxString title {wxString("")};
size_t label_width = 20 * wxGetApp().em_unit();// {200};
size_t label_width = 20 ;// {200};
wxSizer* sizer {nullptr};
column_t extra_column {nullptr};
t_change m_on_change { nullptr };
@ -94,6 +94,9 @@ public:
std::function<DynamicPrintConfig()> m_get_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 label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
int sidetext_width{ -1 };
@ -193,6 +196,8 @@ protected:
std::map<t_config_option_key, Option> m_options;
wxWindow* m_parent {nullptr};
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.
/// using types that need to know what it is beyond the public interface
@ -261,6 +266,7 @@ public:
void Hide();
void Show(const bool show);
bool update_visibility(ConfigOptionMode mode);
void msw_rescale();
boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize);
// return option value from config
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;
void show_sizer(bool show);
void msw_rescale();
};
ObjectInfo::ObjectInfo(wxWindow *parent) :
@ -118,10 +119,10 @@ ObjectInfo::ObjectInfo(wxWindow *parent) :
{
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->AddGrowableCol(1, 1);
grid_sizer->AddGrowableCol(3, 1);
// grid_sizer->AddGrowableCol(1, 1);
// grid_sizer->AddGrowableCol(3, 1);
auto init_info_label = [parent, grid_sizer](wxStaticText **info_label, wxString 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);
}
void ObjectInfo::msw_rescale()
{
manifold_warning_icon->SetBitmap(create_scaled_bitmap(nullptr, "exclamation"));
}
enum SlisedInfoIdx
{
siFilament_m,
@ -229,7 +235,8 @@ void SlicedInfo::SetTextAndShow(SlisedInfoIdx idx, const wxString& text, const w
PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), 0, nullptr, wxCB_READONLY),
preset_type(preset_type),
last_selected(wxNOT_FOUND)
last_selected(wxNOT_FOUND),
m_em_unit(wxGetApp().em_unit())
{
Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) {
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);
#ifdef __WINDOWS__
edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
edit_btn->SetBitmap(create_scaled_bitmap(this, "cog"));
edit_btn = new ScalableButton(parent, wxID_ANY, "cog");
edit_btn->SetToolTip(_(L("Click to edit preset")));
edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent)
@ -331,6 +334,12 @@ void PresetComboBox::check_selection()
this->last_selected = GetSelection();
}
void PresetComboBox::msw_rescale()
{
m_em_unit = wxGetApp().em_unit();
edit_btn->msw_rescale();
}
// Frequently changed parameters
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.opt.label = L("Infill");
option.opt.width = 6 * wxGetApp().em_unit();
option.opt.width = 6;
option.opt.sidetext = " ";
line.append_option(option);
@ -566,7 +575,7 @@ struct Sidebar::priv
wxScrolledWindow *scrolled;
wxPanel* presets_panel; // Used for MSW better layouts
PrusaModeSizer *mode_sizer;
ModeSizer *mode_sizer;
wxFlexGridSizer *sizer_presets;
PresetComboBox *combo_print;
std::vector<PresetComboBox*> combos_filament;
@ -614,9 +623,9 @@ void Sidebar::priv::show_preset_comboboxes()
// Sidebar / public
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);
@ -625,7 +634,7 @@ Sidebar::Sidebar(Plater *parent)
p->scrolled->SetSizer(scrolled_sizer);
// 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
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_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_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);
@ -703,10 +707,6 @@ Sidebar::Sidebar(Plater *parent)
p->object_settings->Hide();
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
p->object_info = new ObjectInfo(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);
// 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());
p->btn_reslice = new wxButton(this, wxID_ANY, _(L("Slice now")));
p->btn_reslice->SetFont(wxGetApp().bold_font());
auto init_btn = [this](wxButton **btn, wxString label) {
*btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition,
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);
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)
{
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
@ -820,23 +849,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
case Preset::TYPE_PRINTER:
{
// wxWindowUpdateLocker noUpdates_scrolled(p->scrolled);
// 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]);
}
update_all_preset_comboboxes();
p->show_preset_comboboxes();
break;
}
@ -861,6 +874,37 @@ void Sidebar::update_reslice_btn_tooltip() const
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()
{
return p->object_manipulation;
@ -1132,11 +1176,11 @@ struct Plater::priv
MainFrame *main_frame;
// Object popup menu
PrusaMenu object_menu;
MenuWithSeparators object_menu;
// Part popup menu
PrusaMenu part_menu;
MenuWithSeparators part_menu;
// SLA-Object popup menu
PrusaMenu sla_object_menu;
MenuWithSeparators sla_object_menu;
// Removed/Prepended Items according to the view mode
std::vector<wxMenuItem*> items_increase;
@ -3710,22 +3754,16 @@ void Plater::changed_object(int obj_idx)
{
if (obj_idx < 0)
return;
auto list = wxGetApp().obj_list();
wxASSERT(list != nullptr);
if (list == nullptr)
return;
if (list->is_parts_changed()) {
// recenter and re - align to Z = 0
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);
// recenter and re - align to Z = 0
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);
// update print
this->p->schedule_background_process();
@ -3736,26 +3774,19 @@ void Plater::changed_objects(const std::vector<size_t>& object_idxs)
if (object_idxs.empty())
return;
auto list = wxGetApp().obj_list();
wxASSERT(list != nullptr);
if (list == nullptr)
return;
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);
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);
// update print
this->p->schedule_background_process();
@ -3798,6 +3829,18 @@ bool Plater::can_paste_from_clipboard() const
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_all() const { return p->can_delete_all(); }
bool Plater::can_increase_instances() const { return p->can_increase_instances(); }

View file

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

View file

@ -7,7 +7,9 @@ namespace Slic3r {
namespace GUI {
PreferencesDialog::PreferencesDialog(wxWindow* parent) :
wxDialog(parent, wxID_ANY, _(L("Preferences")), wxDefaultPosition, wxDefaultSize) {
DPIDialog(parent, wxID_ANY, _(L("Preferences")), wxDefaultPosition,
wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
{
build();
}
@ -15,7 +17,7 @@ void PreferencesDialog::build()
{
auto app_config = get_app_config();
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_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
};
@ -110,6 +112,8 @@ void PreferencesDialog::build()
auto sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(m_optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
SetFont(wxGetApp().normal_font());
auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); });
@ -123,7 +127,7 @@ void PreferencesDialog::accept()
{
if (m_values.find("no_defaults") != m_values.end() ||
m_values.find("use_legacy_opengl") != m_values.end()) {
warning_catcher(this, _(L("You need to restart Slic3r to make the changes effective.")));
warning_catcher(this, wxString::Format(_(L("You need to restart %s to make the changes effective.")), SLIC3R_APP_NAME));
}
auto app_config = get_app_config();
@ -138,5 +142,21 @@ void PreferencesDialog::accept()
wxGetApp().update_ui_from_settings();
}
void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect)
{
m_optgroup->msw_rescale();
const int em = em_unit();
msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL });
const wxSize& size = wxSize(47 * em, 28 * em);
SetMinSize(size);
Fit();
Refresh();
}
} // GUI
} // Slic3r

View file

@ -2,6 +2,7 @@
#define slic3r_Preferences_hpp_
#include "GUI.hpp"
#include "GUI_Utils.hpp"
#include <wx/dialog.h>
#include <map>
@ -11,7 +12,7 @@ namespace GUI {
class ConfigOptionsGroup;
class PreferencesDialog : public wxDialog
class PreferencesDialog : public DPIDialog
{
std::map<std::string, std::string> m_values;
std::shared_ptr<ConfigOptionsGroup> m_optgroup;
@ -21,6 +22,9 @@ public:
void build();
void accept();
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
};
} // 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.
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;
wxString selected = "";
if (!this->m_presets.front().is_visible)
@ -934,13 +944,13 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
std::vector<wxBitmap> bmps;
if (wide_icons)
// 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.
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);
// Paint a lock at the system presets.
bmps.emplace_back(m_bitmap_cache->mkclear(6, 16));
bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 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(icon_width, icon_height));
bmp = m_bitmap_cache->insert(bitmap_key, bmps);
}
@ -981,12 +991,12 @@ void PresetCollection::update_platter_ui(GUI::PresetComboBox *ui)
std::vector<wxBitmap> bmps;
if (wide_icons)
// 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.
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);
// 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);
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->SetToolTip(ui->GetString(selected_preset_item));
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)
return 0;
@ -1007,6 +1021,14 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati
ui->Clear();
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;
wxString selected = "";
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;
bmps.emplace_back((tmp_bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *tmp_bmp);
// 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);
}
@ -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();
}
void PresetCollection::clear_bitmap_cache()
{
m_bitmap_cache->clear();
}
wxString PresetCollection::separator(const std::string &label)
{
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.
// 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.
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.
// Only the compatible presets are shown.
// 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.
std::string path_from_name(const std::string &new_name) const;
void clear_bitmap_cache();
#ifdef __linux__
static const char* separator_head() { 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)
{
// 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->sla_prints.load_bitmap_default(window, "cog");
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 = "";
if (!this->filaments().front().is_visible)
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) {
const Preset &preset = this->filaments.preset(i);
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;
if (wide_icons)
// 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.
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) {
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.
bmps.emplace_back(m_bitmapCache->mkclear(2, 16));
bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(16, 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(normal_icon_width, icon_height));
// (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16));
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->check_selection();
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)

View file

@ -19,6 +19,7 @@
#include "MsgDialog.hpp"
#include "I18N.hpp"
#include "../Utils/PrintHost.hpp"
#include "wxExtensions.hpp"
namespace fs = boost::filesystem;
@ -131,13 +132,11 @@ wxEvent *PrintHostQueueDialog::Event::Clone() const
}
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_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this)
, on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this)
{
enum { HEIGHT = 60, WIDTH = 30, SPACING = 5 };
const auto em = GetTextExtent("m").x;
SetSize(wxSize(HEIGHT * em, WIDTH * em));
@ -202,6 +201,18 @@ void PrintHostQueueDialog::append_job(const PrintHostJob &job)
job_list->AppendItem(fields, static_cast<wxUIntPtr>(ST_NEW));
}
void PrintHostQueueDialog::on_dpi_changed(const wxRect &suggested_rect)
{
const int& em = em_unit();
msw_buttons_rescale(this, em, { wxID_DELETE, wxID_CANCEL, btn_error->GetId() });
SetMinSize(wxSize(HEIGHT * em, WIDTH * em));
Fit();
Refresh();
}
PrintHostQueueDialog::JobState PrintHostQueueDialog::get_state(int idx)
{
wxCHECK_MSG(idx >= 0 && idx < job_list->GetItemCount(), ST_ERROR, "Out of bounds access to job list");

View file

@ -41,7 +41,7 @@ private:
};
class PrintHostQueueDialog : public wxDialog
class PrintHostQueueDialog : public DPIDialog
{
public:
class Event : public wxEvent
@ -62,6 +62,10 @@ public:
PrintHostQueueDialog(wxWindow *parent);
void append_job(const PrintHostJob &job);
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private:
enum Column {
COL_ID,
@ -81,6 +85,8 @@ private:
ST_COMPLETED,
};
enum { HEIGHT = 60, WIDTH = 30, SPACING = 5 };
wxButton *btn_cancel;
wxButton *btn_error;
wxDataViewListCtrl *job_list;

View file

@ -141,6 +141,9 @@ void Chart::mouse_double_clicked(wxMouseEvent& event) {
void Chart::recalculate_line() {
m_line_to_draw.clear();
m_total_volume = 0.f;
std::vector<wxPoint> points;
for (auto& but : m_buttons) {
points.push_back(wxPoint(math_to_screen(but.get_pos())));
@ -150,92 +153,88 @@ void Chart::recalculate_line() {
break;
}
}
std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; });
m_line_to_draw.clear();
m_total_volume = 0.f;
// Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods
const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point
// false - second ---- || -------
const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points
std::vector<float> diag(N+1);
std::vector<float> mu(N+1);
std::vector<float> lambda(N+1);
std::vector<float> h(N+1);
std::vector<float> rhs(N+1);
// let's fill in inner equations
for (int i=1;i<=N;++i) h[i] = points[i].x-points[i-1].x;
std::fill(diag.begin(),diag.end(),2.f);
for (int i=1;i<=N-1;++i) {
mu[i] = h[i]/(h[i]+h[i+1]);
lambda[i] = 1.f - mu[i];
rhs[i] = 6 * ( float(points[i+1].y-points[i].y )/(h[i+1]*(points[i+1].x-points[i-1].x)) -
float(points[i].y -points[i-1].y)/(h[i] *(points[i+1].x-points[i-1].x)) );
}
// now fill in the first and last equations, according to boundary conditions:
if (boundary_first_derivative) {
const float endpoints_derivative = 0;
lambda[0] = 1;
mu[N] = 1;
rhs[0] = (6.f/h[1]) * (float(points[0].y-points[1].y)/(points[0].x-points[1].x) - endpoints_derivative);
rhs[N] = (6.f/h[N]) * (endpoints_derivative - float(points[N-1].y-points[N].y)/(points[N-1].x-points[N].x));
}
else {
lambda[0] = 0;
mu[N] = 0;
rhs[0] = 0;
rhs[N] = 0;
}
// The calculation wouldn't work in case the ramming is to be turned off completely.
if (points.size()>1) {
std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; });
// Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods
const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point
// false - second ---- || -------
const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points
std::vector<float> diag(N+1);
std::vector<float> mu(N+1);
std::vector<float> lambda(N+1);
std::vector<float> h(N+1);
std::vector<float> rhs(N+1);
// the trilinear system is ready to be solved:
for (int i=1;i<=N;++i) {
float multiple = mu[i]/diag[i-1]; // let's subtract proper multiple of above equation
diag[i]-= multiple * lambda[i-1];
rhs[i] -= multiple * rhs[i-1];
}
// now the back substitution (vector mu contains invalid values from now on):
rhs[N] = rhs[N]/diag[N];
for (int i=N-1;i>=0;--i)
rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i];
unsigned int i=1;
float y=0.f;
for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) {
if (splines) {
if (i<points.size()-1 && points[i].x < x ) {
++i;
// let's fill in inner equations
for (int i=1;i<=N;++i) h[i] = points[i].x-points[i-1].x;
std::fill(diag.begin(),diag.end(),2.f);
for (int i=1;i<=N-1;++i) {
mu[i] = h[i]/(h[i]+h[i+1]);
lambda[i] = 1.f - mu[i];
rhs[i] = 6 * ( float(points[i+1].y-points[i].y )/(h[i+1]*(points[i+1].x-points[i-1].x)) -
float(points[i].y -points[i-1].y)/(h[i] *(points[i+1].x-points[i-1].x)) );
}
// now fill in the first and last equations, according to boundary conditions:
if (boundary_first_derivative) {
const float endpoints_derivative = 0;
lambda[0] = 1;
mu[N] = 1;
rhs[0] = (6.f/h[1]) * (float(points[0].y-points[1].y)/(points[0].x-points[1].x) - endpoints_derivative);
rhs[N] = (6.f/h[N]) * (endpoints_derivative - float(points[N-1].y-points[N].y)/(points[N-1].x-points[N].x));
}
else {
lambda[0] = 0;
mu[N] = 0;
rhs[0] = 0;
rhs[N] = 0;
}
// the trilinear system is ready to be solved:
for (int i=1;i<=N;++i) {
float multiple = mu[i]/diag[i-1]; // let's subtract proper multiple of above equation
diag[i]-= multiple * lambda[i-1];
rhs[i] -= multiple * rhs[i-1];
}
// now the back substitution (vector mu contains invalid values from now on):
rhs[N] = rhs[N]/diag[N];
for (int i=N-1;i>=0;--i)
rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i];
unsigned int i=1;
float y=0.f;
for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) {
if (splines) {
if (i<points.size()-1 && points[i].x < x ) {
++i;
}
if (points[0].x > x)
y = points[0].y;
else
if (points[N].x < x)
y = points[N].y;
else
y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) +
(points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] +
(points[i].y -rhs[i] *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i];
m_line_to_draw.push_back(y);
}
if (points[0].x > x)
y = points[0].y;
else
if (points[N].x < x)
y = points[N].y;
else
y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) +
(points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] +
(points[i].y -rhs[i] *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i];
m_line_to_draw.push_back(y);
else {
float x_math = screen_to_math(wxPoint(x,0)).m_x;
if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math)
++i;
m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y);
}
m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1);
m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1);
m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight());
}
else {
float x_math = screen_to_math(wxPoint(x,0)).m_x;
if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math)
++i;
m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y);
}
m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1);
m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1);
m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight());
}
wxPostEvent(this->GetParent(), wxCommandEvent(EVT_WIPE_TOWER_CHART_CHANGED));
Refresh();
}

View file

@ -41,10 +41,12 @@ std::string get_main_info(bool format_as_html)
}
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);
SetBackgroundColour(bgr_clr);
SetFont(wxGetApp().normal_font());
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
hsizer->SetMinSize(wxSize(50 * wxGetApp().em_unit(), -1));
@ -52,8 +54,9 @@ SysInfoDialog::SysInfoDialog()
main_sizer->Add(hsizer, 1, wxEXPAND | wxALL, 10);
// logo
auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192));
hsizer->Add(logo, 0, wxALIGN_CENTER_VERTICAL);
m_logo_bmp = ScalableBitmap(this, "Slic3r_192px.png", 192);
m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bmp.bmp());
hsizer->Add(m_logo, 0, wxALIGN_CENTER_VERTICAL);
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
hsizer->Add(vsizer, 1, wxEXPAND|wxLEFT, 20);
@ -61,8 +64,7 @@ SysInfoDialog::SysInfoDialog()
// title
{
wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize);
wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
title_font.SetWeight(wxFONTWEIGHT_BOLD);
wxFont title_font = wxGetApp().bold_font();
title_font.SetFamily(wxFONTFAMILY_ROMAN);
title_font.SetPointSize(22);
title->SetFont(title_font);
@ -70,7 +72,7 @@ SysInfoDialog::SysInfoDialog()
}
// 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);
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());
@ -78,10 +80,10 @@ SysInfoDialog::SysInfoDialog()
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 };
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);
html->SetBorders(2);
m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
m_html->SetBorders(2);
const auto text = wxString::Format(
"<html>"
"<body bgcolor= %s link= %s>"
@ -91,16 +93,16 @@ SysInfoDialog::SysInfoDialog()
"</body>"
"</html>", bgr_clr_str, text_clr_str, text_clr_str,
get_main_info(true));
html->SetPage(text);
vsizer->Add(html, 1, wxEXPAND | wxBOTTOM, wxGetApp().em_unit());
m_html->SetPage(text);
vsizer->Add(m_html, 1, wxEXPAND | wxBOTTOM, wxGetApp().em_unit());
}
// 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()));
opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
opengl_info_html->SetBorders(10);
m_opengl_info_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
m_opengl_info_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
m_opengl_info_html->SetBorders(10);
const auto text = wxString::Format(
"<html>"
"<body bgcolor= %s link= %s>"
@ -110,14 +112,15 @@ SysInfoDialog::SysInfoDialog()
"</body>"
"</html>", bgr_clr_str, text_clr_str, text_clr_str,
_3DScene::get_gl_info(true, true));
opengl_info_html->SetPage(text);
main_sizer->Add(opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15);
m_opengl_info_html->SetPage(text);
main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15);
}
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK);
auto btn_copy_to_clipboard = new wxButton(this, wxID_ANY, "Copy to Clipboard", wxDefaultPosition, wxDefaultSize);
buttons->Insert(0, btn_copy_to_clipboard, 0, wxLEFT, 5);
btn_copy_to_clipboard->Bind(wxEVT_BUTTON, &SysInfoDialog::onCopyToClipboard, this);
m_btn_copy_to_clipboard = new wxButton(this, wxID_ANY, "Copy to Clipboard", wxDefaultPosition, wxDefaultSize);
buttons->Insert(0, m_btn_copy_to_clipboard, 0, wxLEFT, 5);
m_btn_copy_to_clipboard->Bind(wxEVT_BUTTON, &SysInfoDialog::onCopyToClipboard, this);
this->SetEscapeId(wxID_OK);
this->Bind(wxEVT_BUTTON, &SysInfoDialog::onCloseDialog, this, wxID_OK);
@ -130,6 +133,34 @@ SysInfoDialog::SysInfoDialog()
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();
msw_buttons_rescale(this, em, { wxID_OK, m_btn_copy_to_clipboard->GetId() });
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);
Fit();
Refresh();
}
void SysInfoDialog::onCopyToClipboard(wxEvent &)
{
wxTheClipboard->Open();

View file

@ -4,14 +4,26 @@
#include <wx/wx.h>
#include <wx/html/htmlwin.h>
#include "GUI_Utils.hpp"
#include "wxExtensions.hpp"
namespace Slic3r {
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;
wxButton* m_btn_copy_to_clipboard;
public:
SysInfoDialog();
protected:
void on_dpi_changed(const wxRect &suggested_rect) override;
private:
void onCopyToClipboard(wxEvent &);

View file

@ -110,37 +110,28 @@ void Tab::create_preset_tab()
#endif //__WXOSX__
// 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);
//buttons
wxBitmap bmpMenu;
bmpMenu = create_scaled_bitmap(this, "save");
m_btn_save_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
if (wxMSW) m_btn_save_preset->SetBackgroundColour(color);
bmpMenu = create_scaled_bitmap(this, "cross"/*"delete.png"*/);
m_btn_delete_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
if (wxMSW) m_btn_delete_preset->SetBackgroundColour(color);
m_scaled_buttons.reserve(6);
m_scaled_buttons.reserve(2);
add_scaled_button(panel, &m_btn_save_preset, "save");
add_scaled_button(panel, &m_btn_delete_preset, "cross");
m_show_incompatible_presets = false;
m_bmp_show_incompatible_presets = create_scaled_bitmap(this, "flag_red");
m_bmp_hide_incompatible_presets = create_scaled_bitmap(this, "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_bitmap(this, m_bmp_show_incompatible_presets, "flag_red");
add_scaled_bitmap(this, m_bmp_hide_incompatible_presets, "flag_green");
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_delete_preset->SetToolTip(_(L("Delete this preset")));
m_btn_delete_preset->Disable();
m_undo_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
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);
}
add_scaled_button(panel, &m_question_btn, "question");
m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n"
"or click this button.")));
@ -148,22 +139,21 @@ void Tab::create_preset_tab()
// Determine the theme color of OS (dark or light)
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.
m_bmp_value_lock = create_scaled_bitmap(this, luma >= 128 ? "lock_closed" : "lock_closed_white");
m_bmp_value_unlock = create_scaled_bitmap(this, "lock_open");
add_scaled_bitmap(this, m_bmp_value_lock , luma >= 128 ? "lock_closed" : "lock_closed_white");
add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open");
m_bmp_non_system = &m_bmp_white_bullet;
// Bitmaps to be shown on the "Undo user changes" button next to each input field.
m_bmp_value_revert = create_scaled_bitmap(this, "undo");
m_bmp_white_bullet = create_scaled_bitmap(this, luma >= 128 ? "dot" : "dot_white"/*"bullet_white.png"*/);
m_bmp_question = create_scaled_bitmap(this, "question");
add_scaled_bitmap(this, m_bmp_value_revert, "undo");
add_scaled_bitmap(this, m_bmp_white_bullet, luma >= 128 ? "dot" : "dot_white");
fill_icon_descriptions();
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_to_sys_btn->SetBitmap(m_bmp_white_bullet);
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)
{
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();
// 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();
m_hsizer = new wxBoxSizer(wxHORIZONTAL);
@ -259,12 +249,36 @@ void Tab::create_preset_tab()
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.
build();
rebuild_page_tree();
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()
{
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);
if (icon_idx == -1) {
// Add a new icon to the icon list.
// wxIcon img_icon(from_u8(Slic3r::var(icon)), wxBITMAP_TYPE_PNG);
// m_icons->Add(img_icon);
m_icons->Add(create_scaled_bitmap(this, icon));
m_scaled_icons_list.push_back(ScalableBitmap(this, icon));
m_icons->Add(m_scaled_icons_list.back().bmp());
icon_idx = ++m_icon_count;
m_icon_index[icon] = icon_idx;
}
@ -294,7 +307,7 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str
#else
auto panel = this;
#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);
#ifdef __WINDOWS__
// page->SetDoubleBuffered(true);
@ -402,8 +415,8 @@ void Tab::update_changed_ui()
{
bool is_nonsys_value = false;
bool is_modified_value = true;
const wxBitmap *sys_icon = &m_bmp_value_lock;
const wxBitmap *icon = &m_bmp_value_revert;
const ScalableBitmap *sys_icon = &m_bmp_value_lock;
const ScalableBitmap *icon = &m_bmp_value_revert;
const wxColour *color = &m_sys_label_clr;
@ -595,8 +608,8 @@ void Tab::update_changed_tree_ui()
void Tab::update_undo_buttons()
{
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_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_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);
@ -673,7 +686,7 @@ void Tab::update_dirty()
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.
@ -726,6 +739,42 @@ void Tab::update_visibility()
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* field = nullptr;
@ -1121,10 +1170,10 @@ void TabPrint::build()
optgroup->append_single_option_line("complete_objects");
line = { _(L("Extruder clearance (mm)")), "" };
Option option = optgroup->get_option("extruder_clearance_radius");
option.opt.width = 60;
option.opt.width = 6;
line.append_option(option);
option = optgroup->get_option("extruder_clearance_height");
option.opt.width = 60;
option.opt.width = 6;
line.append_option(option);
optgroup->append_line(line);
@ -1138,14 +1187,14 @@ void TabPrint::build()
optgroup = page->new_optgroup(_(L("Post-processing scripts")), 0);
option = optgroup->get_option("post_process");
option.opt.full_width = true;
option.opt.height = 5 * m_em_unit;//50;
option.opt.height = 5;//50;
optgroup->append_single_option_line(option);
page = add_options_page(_(L("Notes")), "note.png");
optgroup = page->new_optgroup(_(L("Notes")), 0);
option = optgroup->get_option("notes");
option.opt.full_width = true;
option.opt.height = 25 * m_em_unit;//250;
option.opt.height = 25;//250;
optgroup->append_single_option_line(option);
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("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("slowdown_below_layer_time");
optgroup->append_single_option_line("min_print_speed");
@ -1508,8 +1557,8 @@ void TabFilament::build()
};
optgroup->append_line(line);
const int gcode_field_height = 15 * m_em_unit; // 150
const int notes_field_height = 25 * m_em_unit; // 250
const int gcode_field_height = 15; // 150
const int notes_field_height = 25; // 250
page = add_options_page(_(L("Custom G-code")), "cog");
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, "");
auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT);
(*StaticText)->SetFont(font);
// auto font = (new wxSystemSettings)->GetFont(wxSYS_DEFAULT_GUI_FONT);
(*StaticText)->SetFont(wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(*StaticText, 1, wxEXPAND|wxALL, 0);
@ -1629,10 +1678,10 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
}
auto printhost_browse = [=](wxWindow* parent) {
auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots,
wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L(" Browse ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
ScalableButton* btn = m_printhost_browse_btn;
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
btn->SetBitmap(create_scaled_bitmap(this, "browse"));
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
@ -1648,10 +1697,9 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
};
auto print_host_test = [this](wxWindow* parent) {
auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")),
wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
btn->SetBitmap(create_scaled_bitmap(this, "test"));
add_scaled_button(parent, &m_print_host_test_btn, "test", _(L("Test")), wxBU_LEFT | wxBU_EXACTFIT);
ScalableButton* btn = m_print_host_test_btn;
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
@ -1722,9 +1770,9 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
line.widget = [this, ca_file_hint] (wxWindow* parent) {
auto txt = new wxStaticText(parent, wxID_ANY, wxString::Format("%s\n\n\t%s",
_(L("HTTPS CA File:\n\
\tOn this system, Slic3r uses HTTPS certificates from the system Certificate Store or Keychain.\n\
\tTo use a custom CA file, please import your CA file into Certificate Store / Keychain.")),
wxString::Format(_(L("HTTPS CA File:\n\
\tOn this system, %s uses HTTPS certificates from the system Certificate Store or Keychain.\n\
\tTo use a custom CA file, please import your CA file into Certificate Store / Keychain.")), SLIC3R_APP_NAME),
ca_file_hint));
txt->SetFont(Slic3r::GUI::wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
@ -1755,6 +1803,8 @@ void TabPrinter::build_fff()
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"));
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();
m_sys_extruders_count = parent_preset == nullptr ? 0 :
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.widget = [this](wxWindow* parent) {
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetFont(wxGetApp().small_font());
btn->SetBitmap(create_scaled_bitmap(this, "printer_white"));
ScalableButton* btn;
add_scaled_button(parent, &btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetFont(wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
@ -1881,7 +1931,7 @@ void TabPrinter::build_fff()
m_use_silent_mode = val;
}
}
build_extruder_pages();
build_unregular_pages();
update_dirty();
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("variable_layer_height");
const int gcode_field_height = 15 * m_em_unit; // 150
const int notes_field_height = 25 * m_em_unit; // 250
const int gcode_field_height = 15; // 150
const int notes_field_height = 25; // 250
page = add_options_page(_(L("Custom G-code")), "cog");
optgroup = page->new_optgroup(_(L("Start G-code")), 0);
option = optgroup->get_option("start_gcode");
@ -1948,7 +1998,7 @@ void TabPrinter::build_fff()
};
optgroup->append_line(line);
build_extruder_pages();
build_unregular_pages();
#if 0
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.widget = [this](wxWindow* parent) {
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetFont(wxGetApp().small_font());
btn->SetBitmap(create_scaled_bitmap(this, "printer_white"));
ScalableButton* btn;
add_scaled_button(parent, &btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetFont(wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
@ -2023,7 +2074,7 @@ void TabPrinter::build_sla()
optgroup = page->new_optgroup(_(L("Print Host upload")));
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");
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)
{
m_extruders_count = extruders_count;
m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count);
m_preset_bundle->update_multi_material_filament_presets();
build_extruder_pages();
reload_config();
on_value_change("extruders_count", extruders_count);
wxGetApp().sidebar().update_objects_list_extruder_column(extruders_count);
bool is_count_changed = false;
if (m_extruders_count != extruders_count) {
m_extruders_count = extruders_count;
m_preset_bundle->printers.get_edited_preset().set_num_extruders(extruders_count);
m_preset_bundle->update_multi_material_filament_presets();
is_count_changed = true;
}
/* 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)
@ -2078,12 +2139,12 @@ PageShp TabPrinter::build_kinematics_page()
// Legend for OptionsGroups
auto optgroup = page->new_optgroup("");
optgroup->set_show_modified_btns_val(false);
optgroup->label_width = 23 * m_em_unit;// 230;
optgroup->label_width = 23;// 230;
auto line = Line{ "", "" };
ConfigOptionDef def;
def.type = coString;
def.width = 150;
def.width = 15;
def.gui_type = "legend";
def.mode = comAdvanced;
def.tooltip = L("Values in this column are for Full Power mode");
@ -2125,12 +2186,23 @@ PageShp TabPrinter::build_kinematics_page()
return page;
}
void TabPrinter::build_extruder_pages()
/* Previous name 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
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
size_t existed_page = 0;
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;
}
// Build missed extruder pages
for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) {
//# build page
char buf[512];
sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1);
auto page = add_options_page(from_u8(buf), "funnel", true);
const wxString& page_name = wxString::Format(_(L("Extruder %d")), int(extruder_idx + 1));
auto page = add_options_page(page_name, "funnel", true);
m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page);
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.begin() + n_before_extruders + m_extruders_count_old);
Thaw();
m_extruders_count_old = m_extruders_count;
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
@ -2492,7 +2568,6 @@ void Tab::rebuild_page_tree()
m_treectrl->SelectItem(item);
}
}
// Thaw();
}
void Tab::update_page_tree_visibility()
@ -2728,7 +2803,8 @@ bool Tab::may_switch_to_SLA_preset()
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.
// 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()
{
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_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." :
@ -2909,10 +2985,8 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
{
deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All")));
deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font());
deps.btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
deps.btn->SetBitmap(create_scaled_bitmap(this, "printer_white"));
add_scaled_button(parent, &deps.btn, "printer_white", _(L(" Set ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL);
@ -3069,6 +3143,12 @@ void Page::update_visibility(ConfigOptionMode mode)
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* 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;
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;
const std::vector<Option>& options = line.get_options();
if (options.size() == 0 || options[0].opt.gui_type == "legend")
bmp_name = "";// "error.png";
else {
auto mode = options[0].opt.mode; //we assume that we have one option per line
bmp_name = mode == comExpert ? "mode_expert_.png" :
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));
int mode_id = int(options[0].opt.mode);
const wxBitmap& bitmap = options.size() == 0 || options[0].opt.gui_type == "legend" ? wxNullBitmap :
m_mode_bitmap_cache[mode_id].bmp();
auto bmp = new wxStaticBitmap(parent, wxID_ANY, bitmap);
bmp->SetClientData((void*)&m_mode_bitmap_cache[mode_id]);
bmp->SetBackgroundStyle(wxBG_STYLE_PAINT);
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;
};
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);
m_optgroups.push_back(optgroup);
@ -3222,7 +3308,7 @@ void TabSLAMaterial::build()
optgroup->append_single_option_line("initial_exposure_time");
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> axes{ "X", "Y", "Z" };
std::vector<std::string> axes{ "XY", "Z" };
@ -3232,7 +3318,7 @@ void TabSLAMaterial::build()
for (auto& axis : axes) {
auto opt = optgroup->get_option(opt_key, id);
opt.opt.label = axis;
opt.opt.width = 60;
opt.opt.width = 6;
line.append_option(opt);
++id;
}
@ -3244,7 +3330,7 @@ void TabSLAMaterial::build()
optgroup->label_width = 0;
Option option = optgroup->get_option("material_notes");
option.opt.full_width = true;
option.opt.height = 25 * m_em_unit;//250;
option.opt.height = 25;//250;
optgroup->append_single_option_line(option);
page = add_options_page(_(L("Dependencies")), "wrench.png");

View file

@ -30,14 +30,14 @@
#include "BedShapeDialog.hpp"
#include "Event.hpp"
class PrusaModeSizer;
#include "wxExtensions.hpp"
namespace Slic3r {
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 }
// package Slic3r::GUI::Tab::Page;
@ -50,10 +50,11 @@ class Page : public wxScrolledWindow
wxBoxSizer* m_vsizer;
bool m_show = true;
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_title(title),
m_iconID(iconID)
m_iconID(iconID),
m_mode_bitmap_cache(mode_bmp_cache)
{
Create(m_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_vsizer = new wxBoxSizer(wxVERTICAL);
@ -67,6 +68,7 @@ public:
// Delayed layout after resizing the main window.
bool layout_valid = false;
const std::vector<ScalableBitmap>& m_mode_bitmap_cache;
public:
std::vector <ConfigOptionsGroupShp> m_optgroups;
@ -79,6 +81,7 @@ public:
void set_config(DynamicPrintConfig* config_in) { m_config = config_in; }
void reload_config();
void update_visibility(ConfigOptionMode mode);
void msw_rescale();
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);
ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1);
@ -119,20 +122,20 @@ protected:
std::string m_name;
const wxString m_title;
wxBitmapComboBox* m_presets_choice;
wxBitmapButton* m_btn_save_preset;
wxBitmapButton* m_btn_delete_preset;
wxBitmapButton* m_btn_hide_incompatible_presets;
ScalableButton* m_btn_save_preset;
ScalableButton* m_btn_delete_preset;
ScalableButton* m_btn_hide_incompatible_presets;
wxBoxSizer* m_hsizer;
wxBoxSizer* m_left_sizer;
wxTreeCtrl* m_treectrl;
wxImageList* m_icons;
PrusaModeSizer* m_mode_sizer;
ModeSizer* m_mode_sizer;
struct PresetDependencies {
Preset::Type type = Preset::TYPE_INVALID;
wxCheckBox *checkbox = nullptr;
wxButton *btn = nullptr;
ScalableButton *btn = nullptr;
std::string key_list; // "compatible_printers"
std::string key_condition;
std::string dialog_title;
@ -141,25 +144,27 @@ protected:
PresetDependencies m_compatible_printers;
PresetDependencies m_compatible_prints;
wxButton* m_undo_btn;
wxButton* m_undo_to_sys_btn;
wxButton* m_question_btn;
wxImageList* m_preset_icons;
ScalableButton* m_undo_btn;
ScalableButton* m_undo_to_sys_btn;
ScalableButton* m_question_btn;
// Cached bitmaps.
// A "flag" icon to be displayned next to the preset name in the Tab's combo box.
wxBitmap m_bmp_show_incompatible_presets;
wxBitmap m_bmp_hide_incompatible_presets;
ScalableBitmap m_bmp_show_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.
wxBitmap m_bmp_value_lock;
wxBitmap m_bmp_value_unlock;
wxBitmap m_bmp_white_bullet;
ScalableBitmap m_bmp_value_lock;
ScalableBitmap m_bmp_value_unlock;
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.
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.
wxBitmap m_bmp_value_revert;
// wxBitmap m_bmp_value_unmodified;
wxBitmap m_bmp_question;
ScalableBitmap m_bmp_value_revert;
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"
wxColour m_sys_label_clr;
@ -236,7 +241,11 @@ public:
virtual bool supports_printer_technology(const PrinterTechnology tech) = 0;
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 update_page_tree_visibility();
// Select a new preset, possibly delete the current one.
@ -274,6 +283,7 @@ public:
virtual void reload_config();
void update_mode();
void update_visibility();
void msw_rescale();
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);
wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText);
@ -345,8 +355,8 @@ class TabPrinter : public Tab
void build_printhost(ConfigOptionsGroup *optgroup);
public:
wxButton* m_serial_test_btn = nullptr;
wxButton* m_print_host_test_btn = nullptr;
wxButton* m_printhost_browse_btn = nullptr;
ScalableButton* m_print_host_test_btn = nullptr;
ScalableButton* m_printhost_browse_btn = nullptr;
size_t m_extruders_count;
size_t m_extruders_count_old = 0;
@ -368,7 +378,7 @@ public:
void update_serial_ports();
void extruders_count_changed(size_t extruders_count);
PageShp build_kinematics_page();
void build_extruder_pages();
void build_unregular_pages();
void on_preset_loaded() override;
void init_options_list() override;
bool supports_printer_technology(const PrinterTechnology /* tech */) override { return true; }

View file

@ -109,7 +109,8 @@ MsgUpdateConfig::~MsgUpdateConfig() {}
// MsgDataIncompatible
MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, wxString> &incompats) :
MsgDialog(nullptr, _(L("Slic3r incompatibility")), _(L("Slic3r configuration is incompatible")), wxID_NONE)
MsgDialog(nullptr, wxString::Format(_(L("%s incompatibility")), SLIC3R_APP_NAME),
wxString::Format(_(L("%s configuration is incompatible")), SLIC3R_APP_NAME), wxID_NONE)
{
logo->SetBitmap(create_scaled_bitmap(this, "Slic3r_192px_grayscale.png", 192));
@ -117,9 +118,9 @@ MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, w
"This version of %s is not compatible with currently installed configuration bundles.\n"
"This probably happened as a result of running an older %s after using a newer one.\n\n"
"You may either exit Slic3r and try again with a newer version, or you may re-run the initial configuration. "
"Doing so will create a backup snapshot of the existing configuration before installing files compatible with this Slic3r.\n"
)), SLIC3R_APP_NAME, SLIC3R_APP_NAME));
"You may either exit %s and try again with a newer version, or you may re-run the initial configuration. "
"Doing so will create a backup snapshot of the existing configuration before installing files compatible with this %s.\n"
)), SLIC3R_APP_NAME, SLIC3R_APP_NAME, SLIC3R_APP_NAME, SLIC3R_APP_NAME));
text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
content_sizer->Add(text);
@ -144,7 +145,7 @@ MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, w
content_sizer->Add(versions);
content_sizer->AddSpacer(2*VERT_SPACING);
auto *btn_exit = new wxButton(this, wxID_EXIT, _(L("Exit Slic3r")));
auto *btn_exit = new wxButton(this, wxID_EXIT, wxString::Format(_(L("Exit %s")), SLIC3R_APP_NAME));
btn_sizer->Add(btn_exit);
btn_sizer->AddSpacer(HORIZ_SPACING);
auto *btn_reconf = new wxButton(this, wxID_REPLACE, _(L("Re-configure")));
@ -187,7 +188,7 @@ MsgDataLegacy::MsgDataLegacy() :
auto *text2 = new wxStaticText(this, wxID_ANY, _(L("For more information please visit our wiki page:")));
static const wxString url("https://github.com/prusa3d/Slic3r/wiki/Slic3r-PE-1.40-configuration-update");
// The wiki page name is intentionally not localized:
auto *link = new wxHyperlinkCtrl(this, wxID_ANY, "Slic3r PE 1.40 configuration update", CONFIG_UPDATE_WIKI_URL);
auto *link = new wxHyperlinkCtrl(this, wxID_ANY, wxString::Format("%s 1.40 configuration update", SLIC3R_APP_NAME), CONFIG_UPDATE_WIKI_URL);
content_sizer->Add(text2);
content_sizer->Add(link);
content_sizer->AddSpacer(VERT_SPACING);

File diff suppressed because it is too large Load diff

View file

@ -31,7 +31,12 @@ 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,
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);
class wxDialog;
void edit_tooltip(wxString& tooltip);
void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector<int>& btn_ids);
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
{
@ -94,91 +99,20 @@ public:
};
// *** PrusaCollapsiblePane ***
// ----------------------------------------------------------------------------
class PrusaCollapsiblePane : public wxCollapsiblePane
// DataViewBitmapText: helper class used by PrusaBitmapTextRenderer
// ----------------------------------------------------------------------------
class DataViewBitmapText : public wxObject
{
public:
PrusaCollapsiblePane() {}
PrusaCollapsiblePane(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);
}
~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)
DataViewBitmapText( const wxString &text = wxEmptyString,
const wxBitmap& bmp = wxNullBitmap) :
m_text(text),
m_bmp(bmp)
{ }
PrusaDataViewBitmapText(const PrusaDataViewBitmapText &other)
DataViewBitmapText(const DataViewBitmapText &other)
: wxObject(),
m_text(other.m_text),
m_bmp(other.m_bmp)
@ -186,18 +120,18 @@ public:
void SetText(const wxString &text) { m_text = 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; }
bool IsSameAs(const PrusaDataViewBitmapText& other) const {
bool IsSameAs(const DataViewBitmapText& other) const {
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);
}
bool operator!=(const PrusaDataViewBitmapText& other) const {
bool operator!=(const DataViewBitmapText& other) const {
return !IsSameAs(other);
}
@ -205,13 +139,13 @@ private:
wxString m_text;
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 {
@ -223,56 +157,73 @@ enum ItemType {
itSettings = 16
};
class PrusaObjectDataViewModelNode;
WX_DEFINE_ARRAY_PTR(PrusaObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray);
class ObjectDataViewModelNode;
WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray);
class PrusaObjectDataViewModelNode
class ObjectDataViewModelNode
{
PrusaObjectDataViewModelNode* m_parent;
ObjectDataViewModelNode* m_parent;
MyObjectTreeModelNodePtrArray m_children;
wxBitmap m_empty_bmp;
size_t m_volumes_cnt = 0;
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:
PrusaObjectDataViewModelNode(const wxString &name,
const wxString& extruder) {
m_parent = NULL;
m_name = name;
m_type = itObject;
ObjectDataViewModelNode(const wxString &name,
const wxString& extruder):
m_parent(NULL),
m_name(name),
m_type(itObject),
m_extruder(extruder)
{
#ifdef __WXGTK__
// 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
// it will be produce "segmentation fault"
m_container = true;
#endif //__WXGTK__
m_extruder = extruder;
set_object_action_icon();
set_action_icon();
}
PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent,
const wxString& sub_obj_name,
const wxBitmap& bmp,
const wxString& extruder,
const int idx = -1 ) {
m_parent = parent;
m_name = sub_obj_name;
m_bmp = bmp;
m_type = itVolume;
m_idx = idx;
m_extruder = extruder;
ObjectDataViewModelNode(ObjectDataViewModelNode* parent,
const wxString& sub_obj_name,
const wxBitmap& bmp,
const wxString& extruder,
const int idx = -1 ) :
m_parent (parent),
m_name (sub_obj_name),
m_type (itVolume),
m_idx (idx),
m_extruder (extruder)
{
m_bmp = bmp;
#ifdef __WXGTK__
// 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
// it will be produce "segmentation fault"
m_container = true;
#endif //__WXGTK__
set_part_action_icon();
set_action_icon();
}
PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, const ItemType type) :
m_parent(parent),
m_type(type),
m_extruder(wxEmptyString)
ObjectDataViewModelNode(ObjectDataViewModelNode* parent,
const ItemType type) :
m_parent(parent),
m_type(type),
m_extruder(wxEmptyString)
{
if (type == itSettings) {
m_name = "Settings to modified";
@ -286,35 +237,28 @@ public:
else if (type == itInstance) {
m_idx = parent->GetChildCount();
m_name = wxString::Format("Instance_%d", m_idx+1);
set_part_action_icon();
set_action_icon();
}
}
~PrusaObjectDataViewModelNode()
~ObjectDataViewModelNode()
{
// free all our children nodes
size_t count = m_children.GetCount();
for (size_t i = 0; i < count; i++)
{
PrusaObjectDataViewModelNode *child = m_children[i];
ObjectDataViewModelNode *child = m_children[i];
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
{
return m_container;
}
PrusaObjectDataViewModelNode* GetParent()
ObjectDataViewModelNode* GetParent()
{
return m_parent;
}
@ -322,17 +266,17 @@ public:
{
return m_children;
}
PrusaObjectDataViewModelNode* GetNthChild(unsigned int n)
ObjectDataViewModelNode* GetNthChild(unsigned int n)
{
return m_children.Item(n);
}
void Insert(PrusaObjectDataViewModelNode* child, unsigned int n)
void Insert(ObjectDataViewModelNode* child, unsigned int n)
{
if (!m_container)
m_container = true;
m_children.Insert(child, n);
}
void Append(PrusaObjectDataViewModelNode* child)
void Append(ObjectDataViewModelNode* child)
{
if (!m_container)
m_container = true;
@ -362,7 +306,7 @@ public:
switch (col)
{
case 0:{
PrusaDataViewBitmapText data;
DataViewBitmapText data;
data << variant;
m_bmp = data.GetBitmap();
m_name = data.GetText();
@ -400,7 +344,7 @@ public:
}
// 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 --
m_name = from_node.m_name;
@ -416,8 +360,8 @@ public:
scnd_id < 0 || scnd_id >= GetChildCount())
return false;
PrusaObjectDataViewModelNode new_scnd = *GetNthChild(frst_id);
PrusaObjectDataViewModelNode new_frst = *GetNthChild(scnd_id);
ObjectDataViewModelNode new_scnd = *GetNthChild(frst_id);
ObjectDataViewModelNode new_frst = *GetNthChild(scnd_id);
new_scnd.m_idx = m_children.Item(scnd_id)->m_idx;
new_frst.m_idx = m_children.Item(frst_id)->m_idx;
@ -428,37 +372,40 @@ public:
}
// Set action icons for node
void set_object_action_icon();
void set_part_action_icon();
bool update_settings_digest(const std::vector<std::string>& categories);
void set_action_icon();
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:
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:
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;
wxDataViewCtrl* m_ctrl{ nullptr };
public:
PrusaObjectDataViewModel();
~PrusaObjectDataViewModel();
ObjectDataViewModel();
~ObjectDataViewModel();
wxDataViewItem Add(const wxString &name, const int extruder);
wxDataViewItem AddVolumeChild(const wxDataViewItem &parent_item,
const wxString &name,
const Slic3r::ModelVolumeType volume_type,
const int extruder = 0,
const bool create_frst_child = true);
wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item,
const wxString &name,
const Slic3r::ModelVolumeType volume_type,
const int extruder = 0,
const bool create_frst_child = true);
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num);
wxDataViewItem Delete(const wxDataViewItem &item);
@ -470,76 +417,82 @@ public:
wxDataViewItem GetItemById(int obj_idx);
wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx);
wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx);
int GetIdByItem(const wxDataViewItem& item) const;
int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const;
int GetObjectIdByItem(const wxDataViewItem& item) const;
int GetVolumeIdByItem(const wxDataViewItem& item) const;
int GetInstanceIdByItem(const wxDataViewItem& item) const;
int GetIdByItem(const wxDataViewItem& item) const;
int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const;
int GetObjectIdByItem(const wxDataViewItem& item) const;
int GetVolumeIdByItem(const wxDataViewItem& item) const;
int GetInstanceIdByItem(const wxDataViewItem& item) const;
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(); }
// helper method for wxLog
wxString GetName(const wxDataViewItem &item) const;
wxBitmap& GetBitmap(const wxDataViewItem &item) const;
wxString GetName(const wxDataViewItem &item) const;
wxBitmap& GetBitmap(const wxDataViewItem &item) const;
// helper methods to change the model
virtual unsigned int GetColumnCount() const override { return 3;}
virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); }
virtual unsigned int GetColumnCount() const override { return 3;}
virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); }
virtual void GetValue(wxVariant &variant,
const wxDataViewItem &item, unsigned int col) const override;
virtual bool SetValue(const wxVariant &variant,
const wxDataViewItem &item, unsigned int col) override;
bool SetValue(const wxVariant &variant, const int item_idx, unsigned int col);
virtual void GetValue( wxVariant &variant,
const wxDataViewItem &item,
unsigned int col) const override;
virtual bool SetValue( const wxVariant &variant,
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
// Remaining items will moved up/down accordingly
wxDataViewItem ReorganizeChildren(int cur_volume_id,
int new_volume_id,
const wxDataViewItem &parent);
wxDataViewItem ReorganizeChildren( const int cur_volume_id,
const int new_volume_id,
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
wxDataViewItem GetTopParent(const wxDataViewItem &item) const;
virtual bool IsContainer(const wxDataViewItem &item) const override;
virtual unsigned int GetChildren(const wxDataViewItem &parent,
wxDataViewItemArray &array) const override;
wxDataViewItem GetTopParent(const wxDataViewItem &item) const;
virtual bool IsContainer(const wxDataViewItem &item) const override;
virtual unsigned int GetChildren(const wxDataViewItem &parent,
wxDataViewItemArray &array) const override;
void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const;
// Is the container just a header or 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 ;
wxDataViewItem GetItemByType(const wxDataViewItem &parent_item, ItemType type) const;
wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const;
wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const;
ItemType GetItemType(const wxDataViewItem &item) const ;
wxDataViewItem GetItemByType( const wxDataViewItem &parent_item,
ItemType type) const;
wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const;
wxDataViewItem GetInstanceRootItem(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 SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type);
void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; }
// Rescale bitmaps for existing Items
void Rescale();
};
// ----------------------------------------------------------------------------
// PrusaBitmapTextRenderer
// BitmapTextRenderer
// ----------------------------------------------------------------------------
#if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING
class PrusaBitmapTextRenderer : public wxDataViewRenderer
class BitmapTextRenderer : public wxDataViewRenderer
#else
class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer
class BitmapTextRenderer : public wxDataViewCustomRenderer
#endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING
{
public:
PrusaBitmapTextRenderer(wxDataViewCellMode mode =
BitmapTextRenderer(wxDataViewCellMode mode =
#ifdef __WXOSX__
wxDATAVIEW_CELL_INERT
#else
@ -550,7 +503,7 @@ public:
#if ENABLE_NONCUSTOM_DATA_VIEW_RENDERING
);
#else
) : wxDataViewCustomRenderer(wxT("PrusaDataViewBitmapText"), mode, align) {}
) : wxDataViewCustomRenderer(wxT("DataViewBitmapText"), mode, align) {}
#endif //ENABLE_NONCUSTOM_DATA_VIEW_RENDERING
bool SetValue(const wxVariant &value);
@ -578,7 +531,7 @@ public:
bool WasCanceled() const { return m_was_unusable_symbol; }
private:
PrusaDataViewBitmapText m_value;
DataViewBitmapText m_value;
bool m_was_unusable_symbol {false};
};
@ -676,7 +629,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:
@ -693,10 +676,10 @@ enum TicksAction{
taDel
};
class PrusaDoubleSlider : public wxControl
class DoubleSlider : public wxControl
{
public:
PrusaDoubleSlider(
DoubleSlider(
wxWindow *parent,
wxWindowID id,
int lowerValue,
@ -708,7 +691,9 @@ public:
long style = wxSL_VERTICAL,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxEmptyString);
~PrusaDoubleSlider() {}
~DoubleSlider() {}
void msw_rescale();
int GetMinValue() const { return m_min_value; }
int GetMaxValue() const { return m_max_value; }
@ -717,6 +702,7 @@ public:
int GetLowerValue() const { return m_lower_value; }
int GetHigherValue() const { return m_higher_value; }
int GetActiveValue() const;
wxSize get_min_size() const ;
double GetLowerValueD() { return get_double_value(ssLower); }
double GetHigherValueD() { return get_double_value(ssHigher); }
wxSize DoGetBestSize() const override;
@ -801,16 +787,16 @@ private:
int m_max_value;
int m_lower_value;
int m_higher_value;
wxBitmap m_bmp_thumb_higher;
wxBitmap m_bmp_thumb_lower;
wxBitmap m_bmp_add_tick_on;
wxBitmap m_bmp_add_tick_off;
wxBitmap m_bmp_del_tick_on;
wxBitmap m_bmp_del_tick_off;
wxBitmap m_bmp_one_layer_lock_on;
wxBitmap m_bmp_one_layer_lock_off;
wxBitmap m_bmp_one_layer_unlock_on;
wxBitmap m_bmp_one_layer_unlock_off;
ScalableBitmap m_bmp_thumb_higher;
ScalableBitmap m_bmp_thumb_lower;
ScalableBitmap m_bmp_add_tick_on;
ScalableBitmap m_bmp_add_tick_off;
ScalableBitmap m_bmp_del_tick_on;
ScalableBitmap m_bmp_del_tick_off;
ScalableBitmap m_bmp_one_layer_lock_on;
ScalableBitmap m_bmp_one_layer_lock_off;
ScalableBitmap m_bmp_one_layer_unlock_on;
ScalableBitmap m_bmp_one_layer_unlock_off;
SelectedSlider m_selection;
bool m_is_left_down = false;
bool m_is_right_down = false;
@ -841,26 +827,26 @@ private:
wxPen GREY_PEN;
wxPen LIGHT_GREY_PEN;
std::vector<wxPen*> line_pens;
std::vector<wxPen*> segm_pens;
std::vector<wxPen*> m_line_pens;
std::vector<wxPen*> m_segm_pens;
std::set<int> m_ticks;
std::vector<std::pair<int,double>> m_values;
};
// ----------------------------------------------------------------------------
// PrusaLockButton
// LockButton
// ----------------------------------------------------------------------------
class PrusaLockButton : public wxButton
class LockButton : public wxButton
{
public:
PrusaLockButton(
LockButton(
wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize);
~PrusaLockButton() {}
~LockButton() {}
void OnButton(wxCommandEvent& event);
void OnEnterBtn(wxMouseEvent& event) { enter_button(true); event.Skip(); }
@ -869,34 +855,72 @@ public:
bool IsLocked() const { return m_is_pushed; }
void SetLock(bool lock);
void msw_rescale();
protected:
void enter_button(const bool enter);
private:
bool m_is_pushed = false;
wxBitmap m_bmp_lock_on;
wxBitmap m_bmp_lock_off;
wxBitmap m_bmp_unlock_on;
wxBitmap m_bmp_unlock_off;
ScalableBitmap m_bmp_lock_on;
ScalableBitmap m_bmp_lock_off;
ScalableBitmap m_bmp_unlock_on;
ScalableBitmap m_bmp_unlock_off;
};
// ----------------------------------------------------------------------------
// PrusaModeButton
// ScalableButton
// ----------------------------------------------------------------------------
class PrusaModeButton : public wxButton
class ScalableButton : public wxButton
{
public:
PrusaModeButton(
wxWindow *parent,
wxWindowID id,
const wxString& mode = wxEmptyString,
const wxBitmap& bmp_on = wxNullBitmap,
const wxSize& size = wxDefaultSize,
const wxPoint& pos = wxDefaultPosition);
~PrusaModeButton() {}
ScalableButton(){}
ScalableButton(
wxWindow * parent,
wxWindowID id,
const std::string& icon_name = "",
const wxString& label = wxEmptyString,
const wxSize& size = wxDefaultSize,
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 OnEnterBtn(wxMouseEvent& event) { focus_button(true); event.Skip(); }
@ -910,8 +934,6 @@ protected:
private:
bool m_is_selected = false;
wxBitmap m_bmp_on;
wxBitmap m_bmp_off;
wxString m_tt_selected;
wxString m_tt_focused;
};
@ -919,47 +941,49 @@ private:
// ----------------------------------------------------------------------------
// PrusaModeSizer
// ModeSizer
// ----------------------------------------------------------------------------
class PrusaModeSizer : public wxFlexGridSizer
class ModeSizer : public wxFlexGridSizer
{
public:
PrusaModeSizer( wxWindow *parent, int hgap = 10);
~PrusaModeSizer() {}
ModeSizer( wxWindow *parent, int hgap = 10);
~ModeSizer() {}
void SetMode(const /*ConfigOptionMode*/int mode);
void msw_rescale();
private:
std::vector<PrusaModeButton*> mode_btns;
std::vector<ModeButton*> m_mode_btns;
};
// ----------------------------------------------------------------------------
// PrusaMenu
// MenuWithSeparators
// ----------------------------------------------------------------------------
class PrusaMenu : public wxMenu
class MenuWithSeparators : public wxMenu
{
public:
PrusaMenu(const wxString& title, long style = 0)
MenuWithSeparators(const wxString& title, long style = 0)
: wxMenu(title, style) {}
PrusaMenu(long style = 0)
MenuWithSeparators(long style = 0)
: wxMenu(style) {}
~PrusaMenu() {}
~MenuWithSeparators() {}
void DestroySeparators();
void SetFirstSeparator();
void SetSecondSeparator();
private:
wxMenuItem* m_separator_frst { nullptr }; // use like separator before settings item
wxMenuItem* m_separator_scnd { nullptr }; // use like separator between settings items
};
// ******************************* EXPERIMENTS **********************************************
// ******************************************************************************************
#endif // slic3r_GUI_wxExtensions_hpp_