diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index 9825f0cf90..af3b655301 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -42,7 +42,7 @@ AboutDialog::AboutDialog() main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20); // logo - auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("Slic3r_192px.png", 192)); + auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); hsizer->Add(logo, 1, wxALIGN_CENTER_VERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 7ad36f09bb..bb4145107f 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -25,16 +25,25 @@ void BitmapCache::clear() delete bitmap.second; } -static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image) +static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image, float scale = 1.0f) { #ifdef BROKEN_ALPHA wxMemoryOutputStream stream; image.SaveFile(stream, wxBITMAP_TYPE_PNG); wxStreamBuffer *buf = stream.GetOutputStreamBuffer(); return wxBitmap::NewFromPNGData(buf->GetBufferStart(), buf->GetBufferSize()); +#else +#ifdef __APPLE__ + // This is a c-tor native to Mac OS. We need to let the Mac OS wxBitmap implementation + // know that the image may already be scaled appropriately for Retina, + // and thereby that it's not supposed to upscale it. + // Contrary to intuition, the `scale` argument isn't "please scale this to such and such" + // but rather "the wxImage is sized for backing scale such and such". + return wxBitmap(std::move(image), -1, scale); #else return wxBitmap(std::move(image)); #endif +#endif } wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height) @@ -163,7 +172,7 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *beg #endif } -wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned int width, unsigned int height, const unsigned char *raw_data) +wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, float scale /* = 1.0f */) { wxImage image(width, height); image.InitAlpha(); @@ -176,7 +185,7 @@ wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned i *rgb ++ = *raw_data ++; *alpha ++ = *raw_data ++; } - return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image))); + return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image), scale)); } wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int width, unsigned int height) @@ -184,6 +193,7 @@ wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int wid std::string bitmap_key = bitmap_name + ( height !=0 ? "-h" + std::to_string(height) : "-w" + std::to_string(width)); + auto it = m_map.find(bitmap_key); if (it != m_map.end()) return it->second; @@ -204,11 +214,15 @@ wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int wid return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image))); } -wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int target_width, unsigned int target_height) +wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_width, unsigned target_height, float scale /* = 1.0f */) { - std::string bitmap_key = bitmap_name + (target_height != 0 ? - "-h" + std::to_string(target_height) : - "-w" + std::to_string(target_width)); + std::string bitmap_key = bitmap_name + ( target_height !=0 ? + "-h" + std::to_string(target_height) : + "-w" + std::to_string(target_width)) + + (scale != 1.0f ? "-s" + std::to_string(scale) : ""); + + target_height != 0 ? target_height *= scale : target_width *= scale; + auto it = m_map.find(bitmap_key); if (it != m_map.end()) return it->second; @@ -217,12 +231,12 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int tar if (image == nullptr) return nullptr; - float scale = target_height != 0 ? + float svg_scale = target_height != 0 ? (float)target_height / image->height : target_width != 0 ? (float)target_width / image->width : 1; - int width = (int)(scale * image->width + 0.5f); - int height = (int)(scale * image->height + 0.5f); + int width = (int)(svg_scale * image->width + 0.5f); + int height = (int)(svg_scale * image->height + 0.5f); int n_pixels = width * height; if (n_pixels <= 0) { ::nsvgDelete(image); @@ -236,11 +250,11 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int tar } std::vector data(n_pixels * 4, 0); - ::nsvgRasterize(rast, image, 0, 0, scale, data.data(), width, height, width * 4); + ::nsvgRasterize(rast, image, 0, 0, svg_scale, data.data(), width, height, width * 4); ::nsvgDeleteRasterizer(rast); ::nsvgDelete(image); - return this->insert_raw_rgba(bitmap_key, width, height, data.data()); + return this->insert_raw_rgba(bitmap_key, width, height, data.data(), scale); } wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency) diff --git a/src/slic3r/GUI/BitmapCache.hpp b/src/slic3r/GUI/BitmapCache.hpp index 8915783a34..f032d80827 100644 --- a/src/slic3r/GUI/BitmapCache.hpp +++ b/src/slic3r/GUI/BitmapCache.hpp @@ -29,12 +29,12 @@ public: wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3); wxBitmap* insert(const std::string &name, const std::vector &bmps) { return this->insert(name, &bmps.front(), &bmps.front() + bmps.size()); } wxBitmap* insert(const std::string &name, const wxBitmap *begin, const wxBitmap *end); - wxBitmap* insert_raw_rgba(const std::string &bitmap_key, unsigned int width, unsigned int height, const unsigned char *raw_data); + wxBitmap* insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, float scale = 1.0f); // Load png from resources/icons. bitmap_key is given without the .png suffix. Bitmap will be rescaled to provided height/width if nonzero. wxBitmap* load_png(const std::string &bitmap_key, unsigned int width = 0, unsigned int height = 0); // Load svg from resources/icons. bitmap_key is given without the .svg suffix. SVG will be rasterized to provided height/width. - wxBitmap* load_svg(const std::string &bitmap_key, unsigned int width = 0, unsigned int height = 0); + wxBitmap* load_svg(const std::string &bitmap_key, unsigned int width = 0, unsigned int height = 0, float scale = 1.0f); static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency); static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2d84af8e9d..6c02dd29bb 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -62,18 +62,18 @@ ObjectList::ObjectList(wxWindow* parent) : // Fill CATEGORY_ICON { // ptFFF - CATEGORY_ICON[L("Layers and Perimeters")] = create_scaled_bitmap("layers"); - CATEGORY_ICON[L("Infill")] = create_scaled_bitmap("infill"); - CATEGORY_ICON[L("Support material")] = create_scaled_bitmap("support"); - CATEGORY_ICON[L("Speed")] = create_scaled_bitmap("time"); - CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap("funnel"); - CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap("funnel"); -// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap("skirt+brim"); -// CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap("time"); - CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap("wrench"); + CATEGORY_ICON[L("Layers and Perimeters")] = create_scaled_bitmap(this, "layers"); + CATEGORY_ICON[L("Infill")] = create_scaled_bitmap(this, "infill"); + CATEGORY_ICON[L("Support material")] = create_scaled_bitmap(this, "support"); + CATEGORY_ICON[L("Speed")] = create_scaled_bitmap(this, "time"); + CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap(this, "funnel"); + CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap(this, "funnel"); +// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap(this, "skirt+brim"); +// CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap(this, "time"); + CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap(this, "wrench"); // ptSLA - CATEGORY_ICON[L("Supports")] = create_scaled_bitmap("sla_supports"); - CATEGORY_ICON[L("Pad")] = create_scaled_bitmap("brick.png"); + CATEGORY_ICON[L("Supports")] = create_scaled_bitmap(this, "sla_supports"); + CATEGORY_ICON[L("Pad")] = create_scaled_bitmap(this, "brick.png"); } // create control @@ -392,10 +392,10 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const void ObjectList::init_icons() { - m_bmp_modifiermesh = create_scaled_bitmap("lambda.png"); - m_bmp_solidmesh = create_scaled_bitmap("object.png"); - m_bmp_support_enforcer = create_scaled_bitmap("support_enforcer_.png"); - m_bmp_support_blocker = create_scaled_bitmap("support_blocker_.png"); + m_bmp_modifiermesh = create_scaled_bitmap(this, "lambda.png"); + m_bmp_solidmesh = create_scaled_bitmap(this, "object.png"); + m_bmp_support_enforcer = create_scaled_bitmap(this, "support_enforcer_.png"); + m_bmp_support_blocker = create_scaled_bitmap(this, "support_blocker_.png"); m_bmp_vector.reserve(4); // bitmaps for different types of parts @@ -406,13 +406,13 @@ void ObjectList::init_icons() m_objects_model->SetVolumeBitmaps(m_bmp_vector); // init icon for manifold warning - m_bmp_manifold_warning = create_scaled_bitmap("exclamation_mark_.png"); + m_bmp_manifold_warning = create_scaled_bitmap(this, "exclamation_mark_.png"); // init bitmap for "Split to sub-objects" context menu - m_bmp_split = create_scaled_bitmap("split_parts"); + m_bmp_split = create_scaled_bitmap(this, "split_parts"); // init bitmap for "Add Settings" context menu - m_bmp_cog = create_scaled_bitmap("cog"); + m_bmp_cog = create_scaled_bitmap(this, "cog"); } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 7e7d8a1d5a..df54f16d48 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -92,7 +92,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : else if (option_name == "Size") { line.near_label_widget = [this](wxWindow* parent) { return new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap, wxDefaultPosition, - create_scaled_bitmap("one_layer_lock_on.png").GetSize()); + create_scaled_bitmap(m_parent, "one_layer_lock_on.png").GetSize()); }; } diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index b1f33eea11..f1e326caf8 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -77,7 +77,7 @@ 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("colorchange_delete_on.png"), + auto btn = new wxBitmapButton(parent, wxID_ANY, create_scaled_bitmap(m_parent, "colorchange_delete_on.png"), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); #ifdef __WXMSW__ btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 5f74407962..c7fbe82316 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -17,7 +17,7 @@ KBShortcutsDialog::KBShortcutsDialog() auto main_sizer = new wxBoxSizer(wxVERTICAL); // logo - const wxBitmap logo_bmp = create_scaled_bitmap("Slic3r_32px.png", 32); + const wxBitmap logo_bmp = create_scaled_bitmap(this, "Slic3r_32px.png", 32); // fonts wxFont head_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index beb0c97cd6..771599b8e8 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -23,15 +23,11 @@ namespace Slic3r { namespace GUI { -MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id) : - MsgDialog(parent, title, headline, create_scaled_bitmap("Slic3r_192px.png", 192), button_id) -{} - -MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxBitmap bitmap, wxWindowID button_id) : -wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), - boldfont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)), - content_sizer(new wxBoxSizer(wxVERTICAL)), - btn_sizer(new wxBoxSizer(wxHORIZONTAL)) +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)) + , content_sizer(new wxBoxSizer(wxVERTICAL)) + , btn_sizer(new wxBoxSizer(wxHORIZONTAL)) { boldfont.SetWeight(wxFONTWEIGHT_BOLD); @@ -54,7 +50,11 @@ wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DI rightsizer->Add(btn_sizer, 0, wxALIGN_RIGHT); - auto *logo = new wxStaticBitmap(this, wxID_ANY, std::move(bitmap)); + if (! bitmap.IsOk()) { + bitmap = create_scaled_bitmap(this, "Slic3r_192px.png", 192); + } + + logo = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap); topsizer->Add(logo, 0, wxALL, BORDER); topsizer->Add(rightsizer, 1, wxALL | wxEXPAND, BORDER); @@ -69,7 +69,6 @@ MsgDialog::~MsgDialog() {} ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg) : MsgDialog(parent, _(L("Slic3r error")), _(L("Slic3r has encountered an error")), - create_scaled_bitmap("Slic3r_192px_grayscale.png"), wxID_NONE) , msg(msg) { @@ -97,6 +96,8 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg) btn_ok->SetFocus(); btn_sizer->Add(btn_ok, 0, wxRIGHT, HORIZ_SPACING); + logo->SetBitmap(create_scaled_bitmap(this, "Slic3r_192px_grayscale.png", 192)); + SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT*wxGetApp().em_unit())); Fit(); } diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index 09bb89e4f7..ad4bbcc971 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -12,6 +12,7 @@ class wxBoxSizer; class wxCheckBox; +class wxStaticBitmap; namespace Slic3r { @@ -40,12 +41,12 @@ protected: }; // button_id is an id of a button that can be added by default, use wxID_NONE to disable - MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id = wxID_OK); - MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxBitmap bitmap, wxWindowID button_id = wxID_OK); + MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id = wxID_OK, wxBitmap bitmap = wxNullBitmap); wxFont boldfont; wxBoxSizer *content_sizer; wxBoxSizer *btn_sizer; + wxStaticBitmap *logo; }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 85ca43c9a0..2f91df1873 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -286,7 +286,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * #ifdef __WINDOWS__ edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif - edit_btn->SetBitmap(create_scaled_bitmap("cog")); + edit_btn->SetBitmap(create_scaled_bitmap(this, "cog")); edit_btn->SetToolTip(_(L("Click to edit preset"))); edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index e383181f46..5e4d921052 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -802,13 +802,13 @@ bool PresetCollection::delete_current_preset() bool PresetCollection::load_bitmap_default(const std::string &file_name) { // return m_bitmap_main_frame->LoadFile(wxString::FromUTF8(Slic3r::var(file_name).c_str()), wxBITMAP_TYPE_PNG); - return load_scaled_bitmap(&m_bitmap_main_frame, file_name); + return load_scaled_bitmap(nullptr, &m_bitmap_main_frame, file_name); // FIXME: pass window ptr for proper scaling } bool PresetCollection::load_bitmap_add(const std::string &file_name) { // return m_bitmap_add->LoadFile(wxString::FromUTF8(Slic3r::var(file_name).c_str()), wxBITMAP_TYPE_PNG); - return load_scaled_bitmap(&m_bitmap_add, file_name); + return load_scaled_bitmap(nullptr, &m_bitmap_add, file_name); // FIXME: pass window ptr for proper scaling } const Preset* PresetCollection::get_selected_preset_parent() const diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index 19f9040bf4..7525112b96 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -411,10 +411,11 @@ bool PresetBundle::load_compatible_bitmaps() // bool loaded_lock_open = m_bitmapLockOpen->LoadFile( // wxString::FromUTF8(Slic3r::var(path_bitmap_lock_open).c_str()), wxBITMAP_TYPE_PNG); - bool loaded_compatible = load_scaled_bitmap(&m_bitmapCompatible, path_bitmap_compatible); - bool loaded_incompatible = load_scaled_bitmap(&m_bitmapIncompatible,path_bitmap_incompatible); - bool loaded_lock = load_scaled_bitmap(&m_bitmapLock, path_bitmap_lock); - bool loaded_lock_open = load_scaled_bitmap(&m_bitmapLockOpen, path_bitmap_lock_open); + // FIXME: pass window ptr for proper scaling + bool loaded_compatible = load_scaled_bitmap(nullptr, &m_bitmapCompatible, path_bitmap_compatible); + bool loaded_incompatible = load_scaled_bitmap(nullptr, &m_bitmapIncompatible,path_bitmap_incompatible); + bool loaded_lock = load_scaled_bitmap(nullptr, &m_bitmapLock, path_bitmap_lock); + bool loaded_lock_open = load_scaled_bitmap(nullptr, &m_bitmapLockOpen, path_bitmap_lock_open); if (loaded_compatible) { prints .set_bitmap_compatible(m_bitmapCompatible); diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index 95bd7e61ad..052656974e 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -52,7 +52,7 @@ SysInfoDialog::SysInfoDialog() main_sizer->Add(hsizer, 1, wxEXPAND | wxALL, 10); // logo - auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("Slic3r_192px.png", 192)); + auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap(this, "Slic3r_192px.png", 192)); hsizer->Add(logo, 0, wxALIGN_CENTER_VERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index c221611646..e5b83587e7 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -116,16 +116,16 @@ void Tab::create_preset_tab() //buttons wxBitmap bmpMenu; - bmpMenu = create_scaled_bitmap("disk.png"); + bmpMenu = create_scaled_bitmap(this, "disk.png"); 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("delete.png"); + bmpMenu = create_scaled_bitmap(this, "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_show_incompatible_presets = false; - m_bmp_show_incompatible_presets = create_scaled_bitmap("flag-red-icon.png"); - m_bmp_hide_incompatible_presets = create_scaled_bitmap("flag-green-icon.png"); + m_bmp_show_incompatible_presets = create_scaled_bitmap(this, "flag-red-icon.png"); + m_bmp_hide_incompatible_presets = create_scaled_bitmap(this, "flag-green-icon.png"); 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); @@ -148,13 +148,13 @@ 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("sys_lock.png"); - m_bmp_value_unlock = create_scaled_bitmap(luma >= 128 ? "sys_unlock.png" : "sys_unlock_grey.png"); + m_bmp_value_lock = create_scaled_bitmap(this, "sys_lock.png"); + m_bmp_value_unlock = create_scaled_bitmap(this, luma >= 128 ? "sys_unlock.png" : "sys_unlock_grey.png"); 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(luma >= 128 ? "action_undo.png" : "action_undo_grey.png"); - m_bmp_white_bullet = create_scaled_bitmap("bullet_white.png"); - m_bmp_question = create_scaled_bitmap("question_mark_01.png"); + m_bmp_value_revert = create_scaled_bitmap(this, luma >= 128 ? "action_undo.png" : "action_undo_grey.png"); + m_bmp_white_bullet = create_scaled_bitmap(this, "bullet_white.png"); + m_bmp_question = create_scaled_bitmap(this, "question_mark_01.png"); fill_icon_descriptions(); set_tooltips_text(); @@ -283,7 +283,7 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str // 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(icon)); + m_icons->Add(create_scaled_bitmap(this, icon)); icon_idx = ++m_icon_count; m_icon_index[icon] = icon_idx; } @@ -1632,7 +1632,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - btn->SetBitmap(create_scaled_bitmap("zoom.png")); + btn->SetBitmap(create_scaled_bitmap(this, "zoom.png")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1651,7 +1651,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) 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("wrench.png")); + btn->SetBitmap(create_scaled_bitmap(this, "wrench.png")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1688,7 +1688,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); - btn->SetBitmap(create_scaled_bitmap("zoom.png")); + btn->SetBitmap(create_scaled_bitmap(this, "zoom.png")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1766,7 +1766,7 @@ void TabPrinter::build_fff() 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("printer")); + btn->SetBitmap(create_scaled_bitmap(this, "printer")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1967,7 +1967,7 @@ void TabPrinter::build_sla() 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("printer")); + btn->SetBitmap(create_scaled_bitmap(this, "printer")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -2911,7 +2911,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep 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("printer")); + deps.btn->SetBitmap(create_scaled_bitmap(this, "printer")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL); @@ -3102,7 +3102,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la 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(bmp_name)); + auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(parent, bmp_name)); bmp->SetBackgroundStyle(wxBG_STYLE_PAINT); return bmp; }; diff --git a/src/slic3r/GUI/UpdateDialogs.cpp b/src/slic3r/GUI/UpdateDialogs.cpp index c4b78eb1a8..dccdf3ecd6 100644 --- a/src/slic3r/GUI/UpdateDialogs.cpp +++ b/src/slic3r/GUI/UpdateDialogs.cpp @@ -15,6 +15,7 @@ #include "GUI_App.hpp" #include "I18N.hpp" #include "ConfigWizard.hpp" +#include "wxExtensions.hpp" namespace Slic3r { namespace GUI { @@ -108,8 +109,10 @@ MsgUpdateConfig::~MsgUpdateConfig() {} // MsgDataIncompatible MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map &incompats) : - MsgDialog(nullptr, _(L("Slic3r incompatibility")), _(L("Slic3r configuration is incompatible")), wxBitmap(from_u8(Slic3r::var("Slic3r_192px_grayscale.png")), wxBITMAP_TYPE_PNG), wxID_NONE) + MsgDialog(nullptr, _(L("Slic3r incompatibility")), _(L("Slic3r configuration is incompatible")), wxID_NONE) { + logo->SetBitmap(create_scaled_bitmap(this, "Slic3r_192px_grayscale.png", 192)); + auto *text = new wxStaticText(this, wxID_ANY, _(L( "This version of Slic3r PE is not compatible with currently installed configuration bundles.\n" "This probably happened as a result of running an older Slic3r PE after using a newer one.\n\n" diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index a27b84058d..9f4a18a49a 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1,5 +1,7 @@ #include "wxExtensions.hpp" +#include + #include "libslic3r/Utils.hpp" #include "libslic3r/Model.hpp" @@ -44,7 +46,7 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, const std::string& icon, wxEvtHandler* event_handler) { - const wxBitmap& bmp = !icon.empty() ? create_scaled_bitmap(icon) : wxNullBitmap; + const wxBitmap& bmp = !icon.empty() ? create_scaled_bitmap(nullptr, icon) : wxNullBitmap; // FIXME: pass window ptr return append_menu_item(menu, id, string, description, cb, bmp, event_handler); } @@ -55,7 +57,7 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* item = new wxMenuItem(menu, id, string, description); if (!icon.empty()) - item->SetBitmap(create_scaled_bitmap(icon)); + item->SetBitmap(create_scaled_bitmap(nullptr, icon)); // FIXME: pass window ptr item->SetSubMenu(sub_menu); menu->Append(item); @@ -420,27 +422,40 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) // If an icon has horizontal orientation (width > height) call this function with is_horizontal = true -bool load_scaled_bitmap(wxBitmap** bmp, const std::string& bmp_name_in, const int px_cnt/* = 16*/, const bool is_horizontal /*= false*/) +bool load_scaled_bitmap(wxWindow *win, wxBitmap** bmp, const std::string& bmp_name_in, const int px_cnt/* = 16*/, const bool is_horizontal /*= false*/) { static Slic3r::GUI::BitmapCache cache; + const float scale_factor = win != nullptr ? win->GetContentScaleFactor() : 1.0f; + unsigned int height, width = height = 0; unsigned int& scale_base = is_horizontal ? width : height; + scale_base = (unsigned int)(Slic3r::GUI::wxGetApp().em_unit() * px_cnt * 0.1f + 0.5f); std::string bmp_name = bmp_name_in; boost::replace_last(bmp_name, ".png", ""); - *bmp = cache.load_svg(bmp_name, width, height); - if (*bmp == nullptr) + + // Try loading an SVG first, then PNG if SVG is not found: + *bmp = cache.load_svg(bmp_name, width, height, scale_factor); + if (*bmp == nullptr) { *bmp = cache.load_png(bmp_name, width, height); + } + + if (*bmp == nullptr) { + // Neither SVG nor PNG has been found, raise error + throw std::runtime_error("Could not load bitmap: " + bmp_name); + } + + // XXX: useless return *bmp != nullptr; } // If an icon has horizontal orientation (width > height) call this function with is_horizontal = true -wxBitmap create_scaled_bitmap(const std::string& bmp_name_in, const int px_cnt/* = 16*/, const bool is_horizontal /* = false*/) +wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, const int px_cnt/* = 16*/, const bool is_horizontal /* = false*/) { wxBitmap *bmp {nullptr}; - load_scaled_bitmap(&bmp, bmp_name_in, px_cnt, is_horizontal); + load_scaled_bitmap(win, &bmp, bmp_name_in, px_cnt, is_horizontal); return *bmp; } @@ -450,10 +465,10 @@ wxBitmap create_scaled_bitmap(const std::string& bmp_name_in, const int px_cnt/* // ---------------------------------------------------------------------------- void PrusaObjectDataViewModelNode::set_object_action_icon() { - m_action_icon = create_scaled_bitmap("add_object.png"); + m_action_icon = create_scaled_bitmap(nullptr, "add_object.png"); // FIXME: pass window ptr } void PrusaObjectDataViewModelNode::set_part_action_icon() { - m_action_icon = create_scaled_bitmap(m_type == itVolume ? "cog" : "brick_go.png"); + m_action_icon = create_scaled_bitmap(nullptr, m_type == itVolume ? "cog.png" : "brick_go.png"); // FIXME: pass window ptr } Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; @@ -1495,20 +1510,20 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, if (!is_osx) SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX - m_bmp_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap("right_half_circle.png") : create_scaled_bitmap("up_half_circle.png", 16, true)); - m_bmp_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap("left_half_circle.png" ) : create_scaled_bitmap("down_half_circle.png",16, true)); + m_bmp_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap(this, "right_half_circle.png") : create_scaled_bitmap(this, "up_half_circle.png", 16, true)); + m_bmp_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap(this, "left_half_circle.png" ) : create_scaled_bitmap(this, "down_half_circle.png", 16, true)); m_thumb_size = m_bmp_thumb_lower.GetSize(); - m_bmp_add_tick_on = create_scaled_bitmap("colorchange_add_on.png"); - m_bmp_add_tick_off = create_scaled_bitmap("colorchange_add_off.png"); - m_bmp_del_tick_on = create_scaled_bitmap("colorchange_delete_on.png"); - m_bmp_del_tick_off = create_scaled_bitmap("colorchange_delete_off.png"); + m_bmp_add_tick_on = create_scaled_bitmap(this, "colorchange_add_on.png"); + m_bmp_add_tick_off = create_scaled_bitmap(this, "colorchange_add_off.png"); + m_bmp_del_tick_on = create_scaled_bitmap(this, "colorchange_delete_on.png"); + m_bmp_del_tick_off = create_scaled_bitmap(this, "colorchange_delete_off.png"); m_tick_icon_dim = m_bmp_add_tick_on.GetSize().x; - m_bmp_one_layer_lock_on = create_scaled_bitmap("one_layer_lock_on.png"); - m_bmp_one_layer_lock_off = create_scaled_bitmap("one_layer_lock_off.png"); - m_bmp_one_layer_unlock_on = create_scaled_bitmap("one_layer_unlock_on.png"); - m_bmp_one_layer_unlock_off = create_scaled_bitmap("one_layer_unlock_off.png"); + m_bmp_one_layer_lock_on = create_scaled_bitmap(this, "one_layer_lock_on.png"); + m_bmp_one_layer_lock_off = create_scaled_bitmap(this, "one_layer_lock_off.png"); + m_bmp_one_layer_unlock_on = create_scaled_bitmap(this, "one_layer_unlock_on.png"); + m_bmp_one_layer_unlock_off = create_scaled_bitmap(this, "one_layer_unlock_off.png"); m_lock_icon_dim = m_bmp_one_layer_lock_on.GetSize().x; m_selection = ssUndef; @@ -2332,10 +2347,10 @@ PrusaLockButton::PrusaLockButton( wxWindow *parent, const wxSize& size /*= wxDefaultSize*/): wxButton(parent, id, wxEmptyString, pos, size, wxBU_EXACTFIT | wxNO_BORDER) { - m_bmp_lock_on = create_scaled_bitmap("one_layer_lock_on.png"); - m_bmp_lock_off = create_scaled_bitmap("one_layer_lock_off.png"); - m_bmp_unlock_on = create_scaled_bitmap("one_layer_unlock_on.png"); - m_bmp_unlock_off = create_scaled_bitmap("one_layer_unlock_off.png"); + m_bmp_lock_on = create_scaled_bitmap(this, "one_layer_lock_on.png"); + m_bmp_lock_off = create_scaled_bitmap(this, "one_layer_lock_off.png"); + m_bmp_unlock_on = create_scaled_bitmap(this, "one_layer_unlock_on.png"); + m_bmp_unlock_off = create_scaled_bitmap(this, "one_layer_unlock_off.png"); #ifdef __WXMSW__ @@ -2393,7 +2408,7 @@ PrusaModeButton::PrusaModeButton( wxWindow *parent, #ifdef __WXMSW__ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif // __WXMSW__ - m_bmp_off = create_scaled_bitmap("mode_off_sq.png"); + m_bmp_off = create_scaled_bitmap(this, "mode_off_sq.png"); m_tt_focused = wxString::Format(_(L("Switch to the %s mode")), mode); m_tt_selected = wxString::Format(_(L("Current mode is %s")), mode); @@ -2443,9 +2458,9 @@ PrusaModeSizer::PrusaModeSizer(wxWindow *parent, int hgap/* = 10*/) : SetFlexibleDirection(wxHORIZONTAL); std::vector> buttons = { - {_(L("Simple")), create_scaled_bitmap("mode_simple_sq.png")}, - {_(L("Advanced")), create_scaled_bitmap("mode_middle_sq.png")}, - {_(L("Expert")), create_scaled_bitmap("mode_expert_sq.png")} + {_(L("Simple")), create_scaled_bitmap(parent, "mode_simple_sq.png")}, + {_(L("Advanced")), create_scaled_bitmap(parent, "mode_middle_sq.png")}, + {_(L("Expert")), create_scaled_bitmap(parent, "mode_expert_sq.png")} }; mode_btns.reserve(3); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 1a50a8adb7..b1055bd809 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -31,8 +31,8 @@ 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 cb, wxEvtHandler* event_handler); -bool load_scaled_bitmap(wxBitmap** bmp, const std::string& bmp_name, const int px_cnt=16, const bool is_horizontal = false); -wxBitmap create_scaled_bitmap(const std::string& bmp_name, const int px_cnt=16, const bool is_horizontal = false); +bool load_scaled_bitmap(wxWindow *win, wxBitmap** bmp, const std::string& bmp_name, const int px_cnt=16, const bool is_horizontal = false); +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 {