Code refactoring:
- PresetCombpBoxes are extracted to the separate file. - All preset icons are moved to the PresetComboBox from Preset and PresetBundle - First "steps" to add physical printers to the printers list on the sidebar.
This commit is contained in:
parent
f23a275fbb
commit
43e6e4f18c
15 changed files with 1304 additions and 1041 deletions
|
@ -80,6 +80,8 @@ set(SLIC3R_GUI_SOURCES
|
|||
GUI/MainFrame.cpp
|
||||
GUI/MainFrame.hpp
|
||||
GUI/Plater.cpp
|
||||
GUI/PresetComboBoxes.hpp
|
||||
GUI/PresetComboBoxes.cpp
|
||||
GUI/Plater.hpp
|
||||
GUI/GUI_ObjectList.cpp
|
||||
GUI/GUI_ObjectList.hpp
|
||||
|
|
|
@ -88,9 +88,6 @@ ObjectList::ObjectList(wxWindow* parent) :
|
|||
{
|
||||
// Fill CATEGORY_ICON
|
||||
{
|
||||
// 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("layers");
|
||||
CATEGORY_ICON[L("Infill")] = create_scaled_bitmap("infill");
|
||||
|
|
|
@ -74,11 +74,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
|||
SLIC3R_VERSION +
|
||||
_(L(" - Remember to check for updates at http://github.com/prusa3d/PrusaSlicer/releases")));
|
||||
|
||||
/* Load default preset bitmaps before a tabpanel initialization,
|
||||
* but after filling of an em_unit value
|
||||
*/
|
||||
wxGetApp().preset_bundle->load_default_preset_bitmaps();
|
||||
|
||||
// initialize tabpanel and menubar
|
||||
init_tabpanel();
|
||||
init_menubar();
|
||||
|
@ -540,11 +535,6 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect)
|
|||
wxGetApp().update_fonts();
|
||||
this->SetFont(this->normal_font());
|
||||
|
||||
/* Load default preset bitmaps before a tabpanel initialization,
|
||||
* but after filling of an em_unit value
|
||||
*/
|
||||
wxGetApp().preset_bundle->load_default_preset_bitmaps();
|
||||
|
||||
// update Plater
|
||||
wxGetApp().plater()->msw_rescale();
|
||||
|
||||
|
@ -586,8 +576,6 @@ void MainFrame::on_sys_color_changed()
|
|||
// update label colors in respect to the system mode
|
||||
wxGetApp().init_label_colours();
|
||||
|
||||
wxGetApp().preset_bundle->load_default_preset_bitmaps();
|
||||
|
||||
// update Plater
|
||||
wxGetApp().plater()->sys_color_changed();
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <wx/dnd.h>
|
||||
#include <wx/progdlg.h>
|
||||
#include <wx/wupdlock.h>
|
||||
#include <wx/colordlg.h>
|
||||
#include <wx/numdlg.h>
|
||||
#include <wx/debug.h>
|
||||
#include <wx/busyinfo.h>
|
||||
|
@ -77,6 +76,7 @@
|
|||
#include "../Utils/UndoRedo.hpp"
|
||||
#include "RemovableDriveManager.hpp"
|
||||
#include "InstanceCheck.hpp"
|
||||
#include "PresetComboBoxes.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "Gizmos/GLGizmosManager.hpp"
|
||||
|
@ -253,153 +253,6 @@ void SlicedInfo::SetTextAndShow(SlicedInfoIdx idx, const wxString& text, const w
|
|||
info_vec[idx].second->Show(show);
|
||||
}
|
||||
|
||||
PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
|
||||
PresetBitmapComboBox(parent, wxSize(15 * wxGetApp().em_unit(), -1)),
|
||||
preset_type(preset_type),
|
||||
last_selected(wxNOT_FOUND),
|
||||
m_em_unit(wxGetApp().em_unit())
|
||||
{
|
||||
SetFont(wxGetApp().normal_font());
|
||||
#ifdef _WIN32
|
||||
// Workaround for ignoring CBN_EDITCHANGE events, which are processed after the content of the combo box changes, so that
|
||||
// the index of the item inside CBN_EDITCHANGE may no more be valid.
|
||||
EnableTextChangedEvents(false);
|
||||
#endif /* _WIN32 */
|
||||
Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) {
|
||||
auto selected_item = evt.GetSelection();
|
||||
|
||||
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
|
||||
if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) {
|
||||
this->SetSelection(this->last_selected);
|
||||
evt.StopPropagation();
|
||||
if (marker >= LABEL_ITEM_WIZARD_PRINTERS) {
|
||||
ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME;
|
||||
switch (marker) {
|
||||
case LABEL_ITEM_WIZARD_PRINTERS: sp = ConfigWizard::SP_PRINTERS; break;
|
||||
case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break;
|
||||
case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break;
|
||||
}
|
||||
wxTheApp->CallAfter([sp]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, sp); });
|
||||
}
|
||||
} else if ( this->last_selected != selected_item ||
|
||||
wxGetApp().get_tab(this->preset_type)->get_presets()->current_is_dirty() ) {
|
||||
this->last_selected = selected_item;
|
||||
evt.SetInt(this->preset_type);
|
||||
evt.Skip();
|
||||
} else {
|
||||
evt.StopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
if (preset_type == Slic3r::Preset::TYPE_FILAMENT)
|
||||
{
|
||||
Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &event) {
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
const Preset* selected_preset = preset_bundle->filaments.find_preset(preset_bundle->filament_presets[extruder_idx]);
|
||||
// Wide icons are shown if the currently selected preset is not compatible with the current printer,
|
||||
// and red flag is drown in front of the selected preset.
|
||||
bool wide_icons = selected_preset != nullptr && !selected_preset->is_compatible;
|
||||
float scale = m_em_unit*0.1f;
|
||||
|
||||
int shifl_Left = wide_icons ? int(scale * 16 + 0.5) : 0;
|
||||
#if defined(wxBITMAPCOMBOBOX_OWNERDRAWN_BASED)
|
||||
shifl_Left += int(scale * 4 + 0.5f); // IMAGE_SPACING_RIGHT = 4 for wxBitmapComboBox -> Space left of image
|
||||
#endif
|
||||
int icon_right_pos = shifl_Left + int(scale * (24+4) + 0.5);
|
||||
int mouse_pos = event.GetLogicalPosition(wxClientDC(this)).x;
|
||||
if (mouse_pos < shifl_Left || mouse_pos > icon_right_pos ) {
|
||||
// Let the combo box process the mouse click.
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Swallow the mouse click and open the color picker.
|
||||
|
||||
// get current color
|
||||
DynamicPrintConfig* cfg = wxGetApp().get_tab(Preset::TYPE_PRINTER)->get_config();
|
||||
auto colors = static_cast<ConfigOptionStrings*>(cfg->option("extruder_colour")->clone());
|
||||
wxColour clr(colors->values[extruder_idx]);
|
||||
if (!clr.IsOk())
|
||||
clr = wxColour(0,0,0); // Don't set alfa to transparence
|
||||
|
||||
auto data = new wxColourData();
|
||||
data->SetChooseFull(1);
|
||||
data->SetColour(clr);
|
||||
|
||||
wxColourDialog dialog(this, data);
|
||||
dialog.CenterOnParent();
|
||||
if (dialog.ShowModal() == wxID_OK)
|
||||
{
|
||||
colors->values[extruder_idx] = dialog.GetColourData().GetColour().GetAsString(wxC2S_HTML_SYNTAX).ToStdString();
|
||||
|
||||
DynamicPrintConfig cfg_new = *cfg;
|
||||
cfg_new.set_key_value("extruder_colour", colors);
|
||||
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg_new);
|
||||
preset_bundle->update_plater_filament_ui(extruder_idx, this);
|
||||
wxGetApp().plater()->on_config_change(cfg_new);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Tab* tab = wxGetApp().get_tab(preset_type);
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
int page_id = wxGetApp().tab_panel()->FindPage(tab);
|
||||
if (page_id == wxNOT_FOUND)
|
||||
return;
|
||||
|
||||
wxGetApp().tab_panel()->SetSelection(page_id);
|
||||
|
||||
// Switch to Settings NotePad
|
||||
wxGetApp().mainframe->select_tab();
|
||||
|
||||
/* In a case of a multi-material printing, for editing another Filament Preset
|
||||
* it's needed to select this preset for the "Filament settings" Tab
|
||||
*/
|
||||
if (preset_type == Preset::TYPE_FILAMENT && wxGetApp().extruders_edited_cnt() > 1)
|
||||
{
|
||||
const std::string& selected_preset = GetString(GetSelection()).ToUTF8().data();
|
||||
|
||||
// Call select_preset() only if there is new preset and not just modified
|
||||
if ( !boost::algorithm::ends_with(selected_preset, Preset::suffix_modified()) )
|
||||
{
|
||||
const std::string& preset_name = wxGetApp().preset_bundle->filaments.get_preset_name_by_alias(selected_preset);
|
||||
tab->select_preset(/*selected_preset*/preset_name);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
PresetComboBox::~PresetComboBox()
|
||||
{
|
||||
if (edit_btn)
|
||||
edit_btn->Destroy();
|
||||
}
|
||||
|
||||
|
||||
void PresetComboBox::set_label_marker(int item, LabelItemType label_item_type)
|
||||
{
|
||||
this->SetClientData(item, (void*)label_item_type);
|
||||
}
|
||||
|
||||
void PresetComboBox::check_selection(int selection)
|
||||
{
|
||||
this->last_selected = selection;
|
||||
}
|
||||
|
||||
void PresetComboBox::msw_rescale()
|
||||
{
|
||||
m_em_unit = wxGetApp().em_unit();
|
||||
edit_btn->msw_rescale();
|
||||
}
|
||||
|
||||
// Frequently changed parameters
|
||||
|
||||
class FreqChangedParams : public OG_Settings
|
||||
|
@ -697,12 +550,12 @@ struct Sidebar::priv
|
|||
|
||||
ModeSizer *mode_sizer;
|
||||
wxFlexGridSizer *sizer_presets;
|
||||
PresetComboBox *combo_print;
|
||||
std::vector<PresetComboBox*> combos_filament;
|
||||
PlaterPresetComboBox *combo_print;
|
||||
std::vector<PlaterPresetComboBox*> combos_filament;
|
||||
wxBoxSizer *sizer_filaments;
|
||||
PresetComboBox *combo_sla_print;
|
||||
PresetComboBox *combo_sla_material;
|
||||
PresetComboBox *combo_printer;
|
||||
PlaterPresetComboBox *combo_sla_print;
|
||||
PlaterPresetComboBox *combo_sla_material;
|
||||
PlaterPresetComboBox *combo_printer;
|
||||
|
||||
wxBoxSizer *sizer_params;
|
||||
FreqChangedParams *frequently_changed_parameters{ nullptr };
|
||||
|
@ -801,10 +654,10 @@ Sidebar::Sidebar(Plater *parent)
|
|||
|
||||
p->sizer_filaments = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto init_combo = [this](PresetComboBox **combo, wxString label, Preset::Type preset_type, bool filament) {
|
||||
auto init_combo = [this](PlaterPresetComboBox **combo, wxString label, Preset::Type preset_type, bool filament) {
|
||||
auto *text = new wxStaticText(p->presets_panel, wxID_ANY, label + " :");
|
||||
text->SetFont(wxGetApp().small_font());
|
||||
*combo = new PresetComboBox(p->presets_panel, preset_type);
|
||||
*combo = new PlaterPresetComboBox(p->presets_panel, preset_type);
|
||||
|
||||
auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
combo_and_btn_sizer->Add(*combo, 1, wxEXPAND);
|
||||
|
@ -941,8 +794,8 @@ Sidebar::Sidebar(Plater *parent)
|
|||
|
||||
Sidebar::~Sidebar() {}
|
||||
|
||||
void Sidebar::init_filament_combo(PresetComboBox **combo, const int extr_idx) {
|
||||
*combo = new PresetComboBox(p->presets_panel, Slic3r::Preset::TYPE_FILAMENT);
|
||||
void Sidebar::init_filament_combo(PlaterPresetComboBox **combo, const int extr_idx) {
|
||||
*combo = new PlaterPresetComboBox(p->presets_panel, Slic3r::Preset::TYPE_FILAMENT);
|
||||
// # copy icons from first choice
|
||||
// $choice->SetItemBitmap($_, $choices->[0]->GetItemBitmap($_)) for 0..$#presets;
|
||||
|
||||
|
@ -977,18 +830,18 @@ void Sidebar::update_all_preset_comboboxes()
|
|||
|
||||
// Update the print choosers to only contain the compatible presets, update the dirty flags.
|
||||
if (print_tech == ptFFF)
|
||||
preset_bundle.prints.update_plater_ui(p->combo_print);
|
||||
p->combo_print->update();
|
||||
else {
|
||||
preset_bundle.sla_prints.update_plater_ui(p->combo_sla_print);
|
||||
preset_bundle.sla_materials.update_plater_ui(p->combo_sla_material);
|
||||
p->combo_sla_print->update();
|
||||
p->combo_sla_material->update();
|
||||
}
|
||||
// Update the printer choosers, update the dirty flags.
|
||||
preset_bundle.printers.update_plater_ui(p->combo_printer);
|
||||
p->combo_printer->update();
|
||||
// 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_plater_filament_ui(i, p->combos_filament[i]);
|
||||
for (PlaterPresetComboBox* cb : p->combos_filament)
|
||||
cb->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1010,23 +863,22 @@ void Sidebar::update_presets(Preset::Type preset_type)
|
|||
preset_bundle.set_filament_preset(0, name);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < filament_cnt; i++) {
|
||||
preset_bundle.update_plater_filament_ui(i, p->combos_filament[i]);
|
||||
}
|
||||
for (size_t i = 0; i < filament_cnt; i++)
|
||||
p->combos_filament[i]->update();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Preset::TYPE_PRINT:
|
||||
preset_bundle.prints.update_plater_ui(p->combo_print);
|
||||
p->combo_print->update();
|
||||
break;
|
||||
|
||||
case Preset::TYPE_SLA_PRINT:
|
||||
preset_bundle.sla_prints.update_plater_ui(p->combo_sla_print);
|
||||
p->combo_sla_print->update();
|
||||
break;
|
||||
|
||||
case Preset::TYPE_SLA_MATERIAL:
|
||||
preset_bundle.sla_materials.update_plater_ui(p->combo_sla_material);
|
||||
p->combo_sla_material->update();
|
||||
break;
|
||||
|
||||
case Preset::TYPE_PRINTER:
|
||||
|
@ -1062,18 +914,14 @@ void Sidebar::msw_rescale()
|
|||
|
||||
p->mode_sizer->msw_rescale();
|
||||
|
||||
// Rescale preset comboboxes in respect to the current em_unit ...
|
||||
for (PresetComboBox* combo : std::vector<PresetComboBox*> { p->combo_print,
|
||||
for (PlaterPresetComboBox* combo : std::vector<PlaterPresetComboBox*> { p->combo_print,
|
||||
p->combo_sla_print,
|
||||
p->combo_sla_material,
|
||||
p->combo_printer } )
|
||||
combo->msw_rescale();
|
||||
for (PresetComboBox* combo : p->combos_filament)
|
||||
for (PlaterPresetComboBox* 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->msw_rescale();
|
||||
p->object_list->msw_rescale();
|
||||
p->object_manipulation->msw_rescale();
|
||||
|
@ -1096,12 +944,12 @@ void Sidebar::sys_color_changed()
|
|||
{
|
||||
// Update preset comboboxes in respect to the system color ...
|
||||
// combo->msw_rescale() updates icon on button, so use it
|
||||
for (PresetComboBox* combo : std::vector<PresetComboBox*>{ p->combo_print,
|
||||
for (PlaterPresetComboBox* combo : std::vector<PlaterPresetComboBox*>{ p->combo_print,
|
||||
p->combo_sla_print,
|
||||
p->combo_sla_material,
|
||||
p->combo_printer })
|
||||
combo->msw_rescale();
|
||||
for (PresetComboBox* combo : p->combos_filament)
|
||||
for (PlaterPresetComboBox* combo : p->combos_filament)
|
||||
combo->msw_rescale();
|
||||
|
||||
// ... then refill them and set min size to correct layout of the sidebar
|
||||
|
@ -1458,7 +1306,7 @@ void Sidebar::update_ui_from_settings()
|
|||
update_sliced_info_sizer();
|
||||
}
|
||||
|
||||
std::vector<PresetComboBox*>& Sidebar::combos_filament()
|
||||
std::vector<PlaterPresetComboBox*>& Sidebar::combos_filament()
|
||||
{
|
||||
return p->combos_filament;
|
||||
}
|
||||
|
@ -3339,7 +3187,7 @@ void Plater::priv::set_current_panel(wxPanel* panel)
|
|||
void Plater::priv::on_select_preset(wxCommandEvent &evt)
|
||||
{
|
||||
auto preset_type = static_cast<Preset::Type>(evt.GetInt());
|
||||
auto *combo = static_cast<PresetComboBox*>(evt.GetEventObject());
|
||||
auto *combo = static_cast<PlaterPresetComboBox*>(evt.GetEventObject());
|
||||
|
||||
// see https://github.com/prusa3d/PrusaSlicer/issues/3889
|
||||
// Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender"),
|
||||
|
@ -3368,7 +3216,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
|
|||
// TODO: ?
|
||||
if (preset_type == Preset::TYPE_FILAMENT && sidebar->is_multifilament()) {
|
||||
// Only update the plater UI for the 2nd and other filaments.
|
||||
wxGetApp().preset_bundle->update_plater_filament_ui(idx, combo);
|
||||
combo->update();
|
||||
}
|
||||
else {
|
||||
wxWindowUpdateLocker noUpdates(sidebar->presets_panel());
|
||||
|
@ -5154,12 +5002,12 @@ void Plater::on_extruders_change(size_t num_extruders)
|
|||
size_t i = choices.size();
|
||||
while ( i < num_extruders )
|
||||
{
|
||||
PresetComboBox* choice/*{ nullptr }*/;
|
||||
PlaterPresetComboBox* choice/*{ nullptr }*/;
|
||||
sidebar().init_filament_combo(&choice, i);
|
||||
choices.push_back(choice);
|
||||
|
||||
// initialize selection
|
||||
wxGetApp().preset_bundle->update_plater_filament_ui(i, choice);
|
||||
choice->update();
|
||||
++i;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,14 +6,12 @@
|
|||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <wx/bmpcbox.h>
|
||||
|
||||
#include "Preset.hpp"
|
||||
#include "Selection.hpp"
|
||||
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "Jobs/Job.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "Search.hpp"
|
||||
|
||||
class wxButton;
|
||||
|
@ -50,46 +48,13 @@ class Mouse3DController;
|
|||
struct Camera;
|
||||
class Bed3D;
|
||||
class GLToolbar;
|
||||
class PlaterPresetComboBox;
|
||||
|
||||
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
|
||||
|
||||
class Plater;
|
||||
enum class ActionButtonType : int;
|
||||
|
||||
class PresetComboBox : public PresetBitmapComboBox
|
||||
{
|
||||
public:
|
||||
PresetComboBox(wxWindow *parent, Preset::Type preset_type);
|
||||
~PresetComboBox();
|
||||
|
||||
ScalableButton* edit_btn { nullptr };
|
||||
|
||||
enum LabelItemType {
|
||||
LABEL_ITEM_MARKER = 0xffffff01,
|
||||
LABEL_ITEM_WIZARD_PRINTERS,
|
||||
LABEL_ITEM_WIZARD_FILAMENTS,
|
||||
LABEL_ITEM_WIZARD_MATERIALS,
|
||||
|
||||
LABEL_ITEM_MAX,
|
||||
};
|
||||
|
||||
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(int 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
|
||||
{
|
||||
ConfigOptionMode m_mode;
|
||||
|
@ -101,7 +66,7 @@ public:
|
|||
Sidebar &operator=(const Sidebar &) = delete;
|
||||
~Sidebar();
|
||||
|
||||
void init_filament_combo(PresetComboBox **combo, const int extr_idx);
|
||||
void init_filament_combo(PlaterPresetComboBox **combo, const int extr_idx);
|
||||
void remove_unused_filament_combos(const size_t current_extruder_count);
|
||||
void update_all_preset_comboboxes();
|
||||
void update_presets(Slic3r::Preset::Type preset_type);
|
||||
|
@ -139,7 +104,7 @@ public:
|
|||
void update_searcher();
|
||||
void update_ui_from_settings();
|
||||
|
||||
std::vector<PresetComboBox*>& combos_filament();
|
||||
std::vector<PlaterPresetComboBox*>& combos_filament();
|
||||
Search::OptionsSearcher& get_searcher();
|
||||
std::string& get_search_line();
|
||||
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
#include "Preset.hpp"
|
||||
#include "AppConfig.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
@ -30,15 +28,9 @@
|
|||
#include <boost/locale.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <wx/image.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/bmpcbox.h>
|
||||
#include <wx/wupdlock.h>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/PlaceholderParser.hpp"
|
||||
#include "Plater.hpp"
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
|
@ -590,10 +582,7 @@ const std::vector<std::string>& Preset::sla_printer_options()
|
|||
PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name) :
|
||||
m_type(type),
|
||||
m_edited_preset(type, "", false),
|
||||
m_idx_selected(0),
|
||||
m_bitmap_main_frame(new wxBitmap),
|
||||
m_bitmap_add(new wxBitmap),
|
||||
m_bitmap_cache(new GUI::BitmapCache)
|
||||
m_idx_selected(0)
|
||||
{
|
||||
// Insert just the default preset.
|
||||
this->add_default_preset(keys, defaults, default_name);
|
||||
|
@ -602,12 +591,6 @@ PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::str
|
|||
|
||||
PresetCollection::~PresetCollection()
|
||||
{
|
||||
delete m_bitmap_main_frame;
|
||||
m_bitmap_main_frame = nullptr;
|
||||
delete m_bitmap_add;
|
||||
m_bitmap_add = nullptr;
|
||||
delete m_bitmap_cache;
|
||||
m_bitmap_cache = nullptr;
|
||||
}
|
||||
|
||||
void PresetCollection::reset(bool delete_files)
|
||||
|
@ -951,16 +934,6 @@ bool PresetCollection::delete_preset(const std::string& name)
|
|||
return true;
|
||||
}
|
||||
|
||||
void PresetCollection::load_bitmap_default(const std::string &file_name)
|
||||
{
|
||||
*m_bitmap_main_frame = create_scaled_bitmap(file_name);
|
||||
}
|
||||
|
||||
void PresetCollection::load_bitmap_add(const std::string &file_name)
|
||||
{
|
||||
*m_bitmap_add = create_scaled_bitmap(file_name);
|
||||
}
|
||||
|
||||
const Preset* PresetCollection::get_selected_preset_parent() const
|
||||
{
|
||||
if (this->get_selected_idx() == size_t(-1))
|
||||
|
@ -1119,279 +1092,15 @@ size_t PresetCollection::update_compatible_internal(const PresetWithVendorProfil
|
|||
// Delete the current preset, activate the first visible preset.
|
||||
//void PresetCollection::delete_current_preset();
|
||||
|
||||
// Update the wxChoice UI component from this list of presets.
|
||||
// Hide the
|
||||
void PresetCollection::update_plater_ui(GUI::PresetComboBox *ui)
|
||||
{
|
||||
if (ui == nullptr)
|
||||
return;
|
||||
|
||||
// Otherwise fill in the list from scratch.
|
||||
ui->Freeze();
|
||||
ui->Clear();
|
||||
size_t selected_preset_item = INT_MAX; // some value meaning that no one item is selected
|
||||
|
||||
const Preset &selected_preset = this->get_selected_preset();
|
||||
// Show wide icons if the currently selected preset is not compatible with the current printer,
|
||||
// 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 = "";
|
||||
wxString tooltip = "";
|
||||
if (!this->m_presets.front().is_visible)
|
||||
ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap));
|
||||
for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++ i) {
|
||||
const Preset &preset = this->m_presets[i];
|
||||
if (! preset.is_visible || (! preset.is_compatible && i != m_idx_selected))
|
||||
continue;
|
||||
|
||||
std::string bitmap_key = "";
|
||||
// !!! Temporary solution, till refactoring: create and use "sla_printer" icon instead of m_bitmap_main_frame
|
||||
wxBitmap main_bmp = m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap;
|
||||
if (m_type == Preset::TYPE_PRINTER && preset.printer_technology()==ptSLA ) {
|
||||
bitmap_key = "sla_printer";
|
||||
main_bmp = create_scaled_bitmap("sla_printer");
|
||||
}
|
||||
|
||||
// If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
|
||||
// to the filament color image.
|
||||
if (wide_icons)
|
||||
bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt";
|
||||
bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst";
|
||||
wxBitmap *bmp = m_bitmap_cache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
if (wide_icons)
|
||||
// Paint a red flag for incompatible presets.
|
||||
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(thin_space_icon_width, icon_height));
|
||||
bmps.emplace_back(main_bmp);
|
||||
// Paint a lock at the system presets.
|
||||
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);
|
||||
}
|
||||
|
||||
const std::string name = preset.alias.empty() ? preset.name : preset.alias;
|
||||
if (preset.is_default || preset.is_system) {
|
||||
ui->Append(wxString::FromUTF8((/*preset.*/name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
|
||||
(bmp == 0) ? main_bmp : *bmp);
|
||||
if (i == m_idx_selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX) {
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
tooltip = wxString::FromUTF8(preset.name.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nonsys_presets.emplace(wxString::FromUTF8((/*preset.*/name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/);
|
||||
if (i == m_idx_selected) {
|
||||
selected = wxString::FromUTF8((/*preset.*/name + (preset.is_dirty ? g_suffix_modified : "")).c_str());
|
||||
tooltip = wxString::FromUTF8(preset.name.c_str());
|
||||
}
|
||||
}
|
||||
if (i + 1 == m_num_default_presets)
|
||||
ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap));
|
||||
}
|
||||
if (!nonsys_presets.empty())
|
||||
{
|
||||
ui->set_label_marker(ui->Append(PresetCollection::separator(L("User presets")), wxNullBitmap));
|
||||
for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
|
||||
ui->Append(it->first, *it->second);
|
||||
if (it->first == selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX)
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
}
|
||||
}
|
||||
if (m_type == Preset::TYPE_PRINTER || m_type == Preset::TYPE_SLA_MATERIAL) {
|
||||
std::string bitmap_key = "";
|
||||
// If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
|
||||
// to the filament color image.
|
||||
if (wide_icons)
|
||||
bitmap_key += "wide,";
|
||||
bitmap_key += "edit_preset_list";
|
||||
wxBitmap *bmp = m_bitmap_cache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
if (wide_icons)
|
||||
// Paint a red flag for incompatible presets.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(icon_width, icon_height));
|
||||
// Paint the color bars.
|
||||
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(wide_space_icon_width, icon_height));
|
||||
// bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap);
|
||||
bmps.emplace_back(create_scaled_bitmap("edit_uni"));
|
||||
bmp = m_bitmap_cache->insert(bitmap_key, bmps);
|
||||
}
|
||||
if (m_type == Preset::TYPE_SLA_MATERIAL)
|
||||
ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add/Remove materials")), *bmp), GUI::PresetComboBox::LABEL_ITEM_WIZARD_MATERIALS);
|
||||
else
|
||||
ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add/Remove printers")), *bmp), GUI::PresetComboBox::LABEL_ITEM_WIZARD_PRINTERS);
|
||||
}
|
||||
|
||||
/* But, if selected_preset_item is still equal to INT_MAX, it means that
|
||||
* there is no presets added to the list.
|
||||
* So, select last combobox item ("Add/Remove preset")
|
||||
*/
|
||||
if (selected_preset_item == INT_MAX)
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
|
||||
ui->SetSelection(selected_preset_item);
|
||||
ui->SetToolTip(tooltip.IsEmpty() ? ui->GetString(selected_preset_item) : tooltip);
|
||||
ui->check_selection(selected_preset_item);
|
||||
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, const int em/* = 10*/)
|
||||
{
|
||||
if (ui == nullptr)
|
||||
return 0;
|
||||
ui->Freeze();
|
||||
ui->Clear();
|
||||
size_t selected_preset_item = INT_MAX; // some value meaning that no one item is selected
|
||||
|
||||
/* 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)
|
||||
ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap);
|
||||
for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++i) {
|
||||
const Preset &preset = this->m_presets[i];
|
||||
if (! preset.is_visible || (! show_incompatible && ! preset.is_compatible && i != m_idx_selected))
|
||||
continue;
|
||||
std::string bitmap_key = "tab";
|
||||
|
||||
// !!! Temporary solution, till refactoring: create and use "sla_printer" icon instead of m_bitmap_main_frame
|
||||
wxBitmap main_bmp = m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap;
|
||||
if (m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA) {
|
||||
bitmap_key = "sla_printer";
|
||||
main_bmp = create_scaled_bitmap("sla_printer");
|
||||
}
|
||||
|
||||
bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt";
|
||||
bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst";
|
||||
wxBitmap *bmp = m_bitmap_cache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
const wxBitmap* tmp_bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible;
|
||||
bmps.emplace_back((tmp_bmp == 0) ? main_bmp : *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(icon_width, icon_height));
|
||||
bmp = m_bitmap_cache->insert(bitmap_key, bmps);
|
||||
}
|
||||
|
||||
if (preset.is_default || preset.is_system) {
|
||||
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
|
||||
(bmp == 0) ? main_bmp : *bmp);
|
||||
if (i == m_idx_selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX)
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/);
|
||||
if (i == m_idx_selected)
|
||||
selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str());
|
||||
}
|
||||
if (i + 1 == m_num_default_presets)
|
||||
ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap);
|
||||
}
|
||||
if (!nonsys_presets.empty())
|
||||
{
|
||||
ui->Append(PresetCollection::separator(L("User presets")), wxNullBitmap);
|
||||
for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
|
||||
ui->Append(it->first, *it->second);
|
||||
if (it->first == selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX)
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
}
|
||||
}
|
||||
if (m_type == Preset::TYPE_PRINTER) {
|
||||
wxBitmap *bmp = m_bitmap_cache->find("edit_printer_list");
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
bmps.emplace_back(*m_bitmap_main_frame);
|
||||
// bmps.emplace_back(m_bitmap_add ? *m_bitmap_add : wxNullBitmap);
|
||||
bmps.emplace_back(create_scaled_bitmap("edit_uni"));
|
||||
bmp = m_bitmap_cache->insert("add_printer_tab", bmps);
|
||||
}
|
||||
ui->Append(PresetCollection::separator("Add a new printer"), *bmp);
|
||||
}
|
||||
|
||||
/* But, if selected_preset_item is still equal to INT_MAX, it means that
|
||||
* there is no presets added to the list.
|
||||
* So, select last combobox item ("Add/Remove preset")
|
||||
*/
|
||||
if (selected_preset_item == INT_MAX)
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
|
||||
ui->SetSelection(selected_preset_item);
|
||||
ui->SetToolTip(ui->GetString(selected_preset_item));
|
||||
ui->Thaw();
|
||||
return selected_preset_item;
|
||||
}
|
||||
|
||||
// Update a dirty floag of the current preset, update the labels of the UI component accordingly.
|
||||
// Update a dirty flag of the current preset
|
||||
// Return true if the dirty flag changed.
|
||||
bool PresetCollection::update_dirty_ui(wxBitmapComboBox *ui)
|
||||
bool PresetCollection::update_dirty()
|
||||
{
|
||||
wxWindowUpdateLocker noUpdates(ui);
|
||||
// 1) Update the dirty flag of the current preset.
|
||||
bool was_dirty = this->get_selected_preset().is_dirty;
|
||||
bool is_dirty = current_is_dirty();
|
||||
this->get_selected_preset().is_dirty = is_dirty;
|
||||
this->get_edited_preset().is_dirty = is_dirty;
|
||||
// 2) Update the labels.
|
||||
for (unsigned int ui_id = 0; ui_id < ui->GetCount(); ++ ui_id) {
|
||||
std::string old_label = ui->GetString(ui_id).utf8_str().data();
|
||||
std::string preset_name = Preset::remove_suffix_modified(old_label);
|
||||
const Preset *preset = this->find_preset(preset_name, false);
|
||||
// The old_label could be the "----- system presets ------" or the "------- user presets --------" separator.
|
||||
// assert(preset != nullptr);
|
||||
if (preset != nullptr) {
|
||||
std::string new_label = preset->is_dirty ? preset->name + g_suffix_modified : preset->name;
|
||||
if (old_label != new_label)
|
||||
ui->SetString(ui_id, wxString::FromUTF8(new_label.c_str()));
|
||||
}
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
// wxWidgets on OSX do not upload the text of the combo box line automatically.
|
||||
// Force it to update by re-selecting.
|
||||
ui->SetSelection(ui->GetSelection());
|
||||
#endif /* __APPLE __ */
|
||||
|
||||
return was_dirty != is_dirty;
|
||||
}
|
||||
|
||||
|
@ -1605,16 +1314,6 @@ 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());
|
||||
}
|
||||
|
||||
const Preset& PrinterPresetCollection::default_preset_for(const DynamicPrintConfig &config) const
|
||||
{
|
||||
const ConfigOptionEnumGeneric *opt_printer_technology = config.opt<ConfigOptionEnumGeneric>("printer_technology");
|
||||
|
@ -1631,7 +1330,108 @@ const Preset* PrinterPresetCollection::find_by_model_id(const std::string &model
|
|||
|
||||
return it != cend() ? &*it : nullptr;
|
||||
}
|
||||
/*
|
||||
PhysicalPrinter& PhysicalPrinterCollection::load_external_printer(
|
||||
// Path to the profile source file (a G-code, an AMF or 3MF file, a config file)
|
||||
const std::string& path,
|
||||
// Name of the profile, derived from the source file name.
|
||||
const std::string& name,
|
||||
// Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored.
|
||||
const std::string& original_name,
|
||||
// Config to initialize the preset from.
|
||||
const DynamicPrintConfig& config,
|
||||
// Select the preset after loading?
|
||||
bool select)
|
||||
{
|
||||
// Load the preset over a default preset, so that the missing fields are filled in from the default preset.
|
||||
DynamicPrintConfig cfg(this->default_printer().config);
|
||||
cfg.apply_only(config, cfg.keys(), true);
|
||||
// Is there a preset already loaded with the name stored inside the config?
|
||||
std::deque<PhysicalPrinter>::iterator it = this->find_printer_internal(original_name);
|
||||
bool found = it != m_printers.end() && it->name == original_name;
|
||||
if (!found) {
|
||||
// Try to match the original_name against the "renamed_from" profile names of loaded system profiles.
|
||||
/ *
|
||||
it = this->find_preset_renamed(original_name);
|
||||
found = it != m_presets.end();
|
||||
* /
|
||||
}
|
||||
if (found) {
|
||||
if (profile_print_params_same(it->config, cfg)) {
|
||||
// The preset exists and it matches the values stored inside config.
|
||||
if (select)
|
||||
this->select_printer(it - m_printers.begin());
|
||||
return *it;
|
||||
}
|
||||
if (profile_host_params_same_or_anonymized(it->config, cfg) == ProfileHostParams::Anonymized) {
|
||||
// The project being loaded is anonymized. Replace the empty host keys of the loaded profile with the data from the original profile.
|
||||
// See "Octoprint Settings when Opening a .3MF file" GH issue #3244
|
||||
auto opt_update = [it, &cfg](const std::string& opt_key) {
|
||||
auto opt = it->config.option<ConfigOptionString>(opt_key);
|
||||
if (opt != nullptr)
|
||||
cfg.set_key_value(opt_key, opt->clone());
|
||||
};
|
||||
opt_update("print_host");
|
||||
opt_update("printhost_apikey");
|
||||
opt_update("printhost_cafile");
|
||||
}
|
||||
}
|
||||
// The external preset does not match an internal preset, load the external preset.
|
||||
std::string new_name;
|
||||
for (size_t idx = 0;; ++idx) {
|
||||
std::string suffix;
|
||||
if (original_name.empty()) {
|
||||
if (idx > 0)
|
||||
suffix = " (" + std::to_string(idx) + ")";
|
||||
}
|
||||
else {
|
||||
if (idx == 0)
|
||||
suffix = " (" + original_name + ")";
|
||||
else
|
||||
suffix = " (" + original_name + "-" + std::to_string(idx) + ")";
|
||||
}
|
||||
new_name = name + suffix;
|
||||
it = this->find_printer_internal(new_name);
|
||||
if (it == m_printers.end() || it->name != new_name)
|
||||
// Unique profile name. Insert a new profile.
|
||||
break;
|
||||
if (profile_print_params_same(it->config, cfg)) {
|
||||
// The preset exists and it matches the values stored inside config.
|
||||
if (select)
|
||||
this->select_printer(it - m_printers.begin());
|
||||
return *it;
|
||||
}
|
||||
// Form another profile name.
|
||||
}
|
||||
// Insert a new profile.
|
||||
PhysicalPrinter& printer = this->load_printer(path, new_name, std::move(cfg), select);
|
||||
|
||||
return printer;
|
||||
}
|
||||
|
||||
void PhysicalPrinterCollection::save_printer(const std::string& new_name)
|
||||
{
|
||||
// 1) Find the printer with a new_name or create a new one,
|
||||
// initialize it with the edited config.
|
||||
auto it = this->find_printer_internal(new_name);
|
||||
if (it != m_printers.end() && it->name == new_name) {
|
||||
// Preset with the same name found.
|
||||
PhysicalPrinter& printer = *it;
|
||||
// Overwriting an existing preset.
|
||||
printer.config = std::move(m_edited_printer.config);
|
||||
}
|
||||
else {
|
||||
// Creating a new printer.
|
||||
PhysicalPrinter& printer = *m_printers.insert(it, m_edited_printer);
|
||||
std::string old_name = printer.name;
|
||||
printer.name = new_name;
|
||||
}
|
||||
// 2) Activate the saved preset.
|
||||
this->select_printer_by_name(new_name, true);
|
||||
// 3) Store the active preset to disk.
|
||||
this->get_selected_preset().save();
|
||||
}
|
||||
*/
|
||||
namespace PresetUtils {
|
||||
const VendorProfile::PrinterModel* system_printer_model(const Preset &preset)
|
||||
{
|
||||
|
|
|
@ -24,11 +24,6 @@ namespace Slic3r {
|
|||
class AppConfig;
|
||||
class PresetBundle;
|
||||
|
||||
namespace GUI {
|
||||
class BitmapCache;
|
||||
class PresetComboBox;
|
||||
}
|
||||
|
||||
enum ConfigFileType
|
||||
{
|
||||
CONFIG_FILE_TYPE_UNKNOWN,
|
||||
|
@ -322,18 +317,6 @@ public:
|
|||
// returns true if the preset was deleted successfully.
|
||||
bool delete_preset(const std::string& name);
|
||||
|
||||
// Load default bitmap to be placed at the wxBitmapComboBox of a MainFrame.
|
||||
void load_bitmap_default(const std::string &file_name);
|
||||
|
||||
// Load "add new printer" bitmap to be placed at the wxBitmapComboBox of a MainFrame.
|
||||
void load_bitmap_add(const std::string &file_name);
|
||||
|
||||
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items.
|
||||
void set_bitmap_compatible (const wxBitmap *bmp) { m_bitmap_compatible = bmp; }
|
||||
void set_bitmap_incompatible(const wxBitmap *bmp) { m_bitmap_incompatible = bmp; }
|
||||
void set_bitmap_lock (const wxBitmap *bmp) { m_bitmap_lock = bmp; }
|
||||
void set_bitmap_lock_open (const wxBitmap *bmp) { m_bitmap_lock_open = bmp; }
|
||||
|
||||
// Enable / disable the "- default -" preset.
|
||||
void set_default_suppressed(bool default_suppressed);
|
||||
bool is_default_suppressed() const { return m_default_suppressed; }
|
||||
|
@ -446,18 +429,9 @@ public:
|
|||
// Return a sorted list of system preset names.
|
||||
std::vector<std::string> system_preset_names() const;
|
||||
|
||||
// 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, 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.
|
||||
void update_plater_ui(GUI::PresetComboBox *ui);
|
||||
|
||||
// Update a dirty floag of the current preset, update the labels of the UI component accordingly.
|
||||
// Update a dirty flag of the current preset
|
||||
// Return true if the dirty flag changed.
|
||||
bool update_dirty_ui(wxBitmapComboBox *ui);
|
||||
bool update_dirty();
|
||||
|
||||
// Select a profile by its name. Return true if the selection changed.
|
||||
// Without force, the selection is only updated if the index changes.
|
||||
|
@ -467,16 +441,7 @@ 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 " -------"; }
|
||||
#else /* __linux__ */
|
||||
static const char* separator_head() { return "————— "; }
|
||||
static const char* separator_tail() { return " —————"; }
|
||||
#endif /* __linux__ */
|
||||
static wxString separator(const std::string &label);
|
||||
size_t num_default_presets() { return m_num_default_presets; }
|
||||
|
||||
protected:
|
||||
// Select a preset, if it exists. If it does not exist, select an invalid (-1) index.
|
||||
|
@ -547,23 +512,10 @@ private:
|
|||
// Is the "- default -" preset suppressed?
|
||||
bool m_default_suppressed = true;
|
||||
size_t m_num_default_presets = 0;
|
||||
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items of a Plater.
|
||||
// These bitmaps are not owned by PresetCollection, but by a PresetBundle.
|
||||
const wxBitmap *m_bitmap_compatible = nullptr;
|
||||
const wxBitmap *m_bitmap_incompatible = nullptr;
|
||||
const wxBitmap *m_bitmap_lock = nullptr;
|
||||
const wxBitmap *m_bitmap_lock_open = nullptr;
|
||||
// Marks placed at the wxBitmapComboBox of a MainFrame.
|
||||
// These bitmaps are owned by PresetCollection.
|
||||
wxBitmap *m_bitmap_main_frame;
|
||||
// "Add printer profile" icon, owned by PresetCollection.
|
||||
wxBitmap *m_bitmap_add;
|
||||
|
||||
// Path to the directory to store the config files into.
|
||||
std::string m_dir_path;
|
||||
|
||||
// Caching color bitmaps for the filament combo box.
|
||||
GUI::BitmapCache *m_bitmap_cache = nullptr;
|
||||
|
||||
// to access select_preset_by_name_strict()
|
||||
friend class PresetBundle;
|
||||
};
|
||||
|
@ -585,6 +537,178 @@ namespace PresetUtils {
|
|||
const VendorProfile::PrinterModel* system_printer_model(const Preset &preset);
|
||||
} // namespace PresetUtils
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PhysicalPrinter
|
||||
{
|
||||
public:
|
||||
PhysicalPrinter(const std::string& name) : name(name) {}
|
||||
|
||||
// Name of the Physical Printer, usually derived form the file name.
|
||||
std::string name;
|
||||
// File name of the Physical Printer.
|
||||
std::string file;
|
||||
// Name of the related Printer preset
|
||||
std::string preset_name;
|
||||
|
||||
// Has this profile been loaded?
|
||||
bool loaded = false;
|
||||
|
||||
// Configuration data, loaded from a file, or set from the defaults.
|
||||
DynamicPrintConfig config;
|
||||
|
||||
void save() { this->config.save(this->file); }
|
||||
|
||||
// Return a printer technology, return ptFFF if the printer technology is not set.
|
||||
static PrinterTechnology printer_technology(const DynamicPrintConfig& cfg) {
|
||||
auto* opt = cfg.option<ConfigOptionEnum<PrinterTechnology>>("printer_technology");
|
||||
// The following assert may trigger when importing some legacy profile,
|
||||
// but it is safer to keep it here to capture the cases where the "printer_technology" key is queried, where it should not.
|
||||
return (opt == nullptr) ? ptFFF : opt->value;
|
||||
}
|
||||
PrinterTechnology printer_technology() const { return printer_technology(this->config); }
|
||||
|
||||
// Sort lexicographically by a preset name. The preset name shall be unique across a single PresetCollection.
|
||||
bool operator<(const Preset& other) const { return this->name < other.name; }
|
||||
|
||||
protected:
|
||||
friend class PhysicalPrinterCollection;
|
||||
};
|
||||
/*
|
||||
// Collections of presets of the same type (one of the Print, Filament or Printer type).
|
||||
class PhysicalPrinterCollection
|
||||
{
|
||||
public:
|
||||
// Initialize the PresetCollection with the "- default -" preset.
|
||||
PhysicalPrinterCollection(const std::vector<std::string>& keys) : m_idx_selected(0) {}
|
||||
~PhysicalPrinterCollection() {}
|
||||
|
||||
typedef std::deque<PhysicalPrinter>::iterator Iterator;
|
||||
typedef std::deque<PhysicalPrinter>::const_iterator ConstIterator;
|
||||
Iterator begin() { return m_printers.begin(); }
|
||||
ConstIterator begin() const { return m_printers.cbegin(); }
|
||||
ConstIterator cbegin() const { return m_printers.cbegin(); }
|
||||
Iterator end() { return m_printers.end(); }
|
||||
ConstIterator end() const { return m_printers.cend(); }
|
||||
ConstIterator cend() const { return m_printers.cend(); }
|
||||
|
||||
void reset(bool delete_files) {};
|
||||
|
||||
const std::deque<PhysicalPrinter>& operator()() const { return m_printers; }
|
||||
|
||||
// Load ini files of the particular type from the provided directory path.
|
||||
void load_printers(const std::string& dir_path, const std::string& subdir){};
|
||||
|
||||
// Load a preset from an already parsed config file, insert it into the sorted sequence of presets
|
||||
// and select it, losing previous modifications.
|
||||
PhysicalPrinter& load_printer(const std::string& path, const std::string& name, const DynamicPrintConfig& config, bool select = true);
|
||||
PhysicalPrinter& load_printer(const std::string& path, const std::string& name, DynamicPrintConfig&& config, bool select = true);
|
||||
|
||||
PhysicalPrinter& load_external_printer(
|
||||
// Path to the profile source file (a G-code, an AMF or 3MF file, a config file)
|
||||
const std::string& path,
|
||||
// Name of the profile, derived from the source file name.
|
||||
const std::string& name,
|
||||
// Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored.
|
||||
const std::string& original_name,
|
||||
// Config to initialize the preset from.
|
||||
const DynamicPrintConfig& config,
|
||||
// Select the preset after loading?
|
||||
bool select = true);
|
||||
|
||||
// Save the printer under a new name. If the name is different from the old one,
|
||||
// a new printer is stored into the list of printers.
|
||||
// ? New printer is activated.
|
||||
void save_printer(const std::string& new_name);
|
||||
|
||||
// Delete the current preset, activate the first visible preset.
|
||||
// returns true if the preset was deleted successfully.
|
||||
bool delete_current_printer() {return true;}
|
||||
// Delete the current preset, activate the first visible preset.
|
||||
// returns true if the preset was deleted successfully.
|
||||
bool delete_printer(const std::string& name) { return true; }
|
||||
|
||||
// Select a printer. If an invalid index is provided, the first visible printer is selected.
|
||||
PhysicalPrinter& select_printer(size_t idx);
|
||||
// Return the selected preset, without the user modifications applied.
|
||||
PhysicalPrinter& get_selected_preset() { return m_printers[m_idx_selected]; }
|
||||
const PhysicalPrinter& get_selected_preset() const { return m_printers[m_idx_selected]; }
|
||||
size_t get_selected_idx() const { return m_idx_selected; }
|
||||
// Returns the name of the selected preset, or an empty string if no preset is selected.
|
||||
std::string get_selected_preset_name() const { return (m_idx_selected == size_t(-1)) ? std::string() : this->get_selected_preset().name; }
|
||||
PhysicalPrinter& get_edited_preset() { return m_edited_printer; }
|
||||
const PhysicalPrinter& get_edited_preset() const { return m_edited_printer; }
|
||||
|
||||
// Return a preset possibly with modifications.
|
||||
PhysicalPrinter& default_printer(size_t idx = 0) { return m_printers[idx]; }
|
||||
const PhysicalPrinter& default_printer(size_t idx = 0) const { return m_printers[idx]; }
|
||||
|
||||
// used to update preset_choice from Tab
|
||||
const std::deque<PhysicalPrinter>& get_presets() const { return m_printers; }
|
||||
size_t get_idx_selected() { return m_idx_selected; }
|
||||
|
||||
// Return a preset by an index. If the preset is active, a temporary copy is returned.
|
||||
PhysicalPrinter& printer(size_t idx) { return (idx == m_idx_selected) ? m_edited_printer : m_printers[idx]; }
|
||||
const PhysicalPrinter& printer(size_t idx) const { return const_cast<PhysicalPrinterCollection*>(this)->printer(idx); }
|
||||
|
||||
// Return a preset by its name. If the preset is active, a temporary copy is returned.
|
||||
// If a preset is not found by its name, null is returned.
|
||||
PhysicalPrinter* find_printer(const std::string& name, bool first_visible_if_not_found = false);
|
||||
const PhysicalPrinter* find_printer(const std::string& name, bool first_visible_if_not_found = false) const
|
||||
{
|
||||
return const_cast<PhysicalPrinterCollection*>(this)->find_printer(name, first_visible_if_not_found);
|
||||
}
|
||||
|
||||
// Return number of presets including the "- default -" preset.
|
||||
size_t size() const { return m_printers.size(); }
|
||||
|
||||
// Select a profile by its name. Return true if the selection changed.
|
||||
// Without force, the selection is only updated if the index changes.
|
||||
// With force, the changes are reverted if the new index is the same as the old index.
|
||||
bool select_printer_by_name(const std::string& name, bool force) {};
|
||||
|
||||
// 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;
|
||||
|
||||
private:
|
||||
// PhysicalPrinterCollection();
|
||||
PhysicalPrinterCollection(const PhysicalPrinterCollection& other);
|
||||
PhysicalPrinterCollection& operator=(const PhysicalPrinterCollection& other);
|
||||
|
||||
// Find a preset position in the sorted list of presets.
|
||||
// The "-- default -- " preset is always the first, so it needs
|
||||
// to be handled differently.
|
||||
// If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name.
|
||||
std::deque<PhysicalPrinter>::iterator find_printer_internal(const std::string& name)
|
||||
{
|
||||
PhysicalPrinter key(name);
|
||||
auto it = std::lower_bound(m_printers.begin()+0, m_printers.end(), key);
|
||||
return it;
|
||||
}
|
||||
std::deque<PhysicalPrinter>::const_iterator find_printer_internal(const std::string& name) const
|
||||
{
|
||||
return const_cast<PhysicalPrinterCollection*>(this)->find_printer_internal(name);
|
||||
}
|
||||
|
||||
static std::vector<std::string> dirty_options(const Preset* edited, const Preset* reference, const bool is_printer_type = false);
|
||||
|
||||
// List of presets, starting with the "- default -" preset.
|
||||
// Use deque to force the container to allocate an object per each entry,
|
||||
// so that the addresses of the presets don't change during resizing of the container.
|
||||
std::deque<PhysicalPrinter> m_printers;
|
||||
// Initially this printer contains a copy of the selected printer. Later on, this copy may be modified by the user.
|
||||
PhysicalPrinter m_edited_printer;
|
||||
// Selected preset.
|
||||
size_t m_idx_selected;
|
||||
|
||||
// Path to the directory to store the config files into.
|
||||
std::string m_dir_path;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif /* slic3r_Preset_hpp_ */
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
#include <cassert>
|
||||
|
||||
#include "PresetBundle.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
#include "Plater.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <fstream>
|
||||
#include <unordered_set>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
@ -21,16 +19,13 @@
|
|||
#include <boost/locale.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <wx/dcmemory.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/bmpcbox.h>
|
||||
#include <wx/wupdlock.h>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "libslic3r/CustomGCode.hpp"
|
||||
|
||||
|
||||
// Store the print/filament/printer presets into a "presets" subdirectory of the Slic3rPE config dir.
|
||||
|
@ -52,12 +47,7 @@ PresetBundle::PresetBundle() :
|
|||
filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
|
||||
sla_materials(Preset::TYPE_SLA_MATERIAL, Preset::sla_material_options(), static_cast<const SLAMaterialConfig&>(SLAFullPrintConfig::defaults())),
|
||||
sla_prints(Preset::TYPE_SLA_PRINT, Preset::sla_print_options(), static_cast<const SLAPrintObjectConfig&>(SLAFullPrintConfig::defaults())),
|
||||
printers(Preset::TYPE_PRINTER, Preset::printer_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults()), "- default FFF -"),
|
||||
m_bitmapCompatible(new wxBitmap),
|
||||
m_bitmapIncompatible(new wxBitmap),
|
||||
m_bitmapLock(new wxBitmap),
|
||||
m_bitmapLockOpen(new wxBitmap),
|
||||
m_bitmapCache(new GUI::BitmapCache)
|
||||
printers(Preset::TYPE_PRINTER, Preset::printer_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults()), "- default FFF -")
|
||||
{
|
||||
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
|
||||
wxImage::AddHandler(new wxPNGHandler);
|
||||
|
@ -112,16 +102,6 @@ PresetBundle::PresetBundle() :
|
|||
preset.inherits();
|
||||
}
|
||||
|
||||
// Load the default preset bitmaps.
|
||||
// #ys_FIXME_to_delete we'll load them later, using em_unit()
|
||||
// this->prints .load_bitmap_default("cog");
|
||||
// this->sla_prints .load_bitmap_default("package_green.png");
|
||||
// this->filaments .load_bitmap_default("spool.png");
|
||||
// this->sla_materials.load_bitmap_default("package_green.png");
|
||||
// this->printers .load_bitmap_default("printer_empty.png");
|
||||
// this->printers .load_bitmap_add("add.png");
|
||||
// this->load_compatible_bitmaps();
|
||||
|
||||
// Re-activate the default presets, so their "edited" preset copies will be updated with the additional configuration values above.
|
||||
this->prints .select_preset(0);
|
||||
this->sla_prints .select_preset(0);
|
||||
|
@ -134,20 +114,6 @@ PresetBundle::PresetBundle() :
|
|||
|
||||
PresetBundle::~PresetBundle()
|
||||
{
|
||||
assert(m_bitmapCompatible != nullptr);
|
||||
assert(m_bitmapIncompatible != nullptr);
|
||||
assert(m_bitmapLock != nullptr);
|
||||
assert(m_bitmapLockOpen != nullptr);
|
||||
delete m_bitmapCompatible;
|
||||
m_bitmapCompatible = nullptr;
|
||||
delete m_bitmapIncompatible;
|
||||
m_bitmapIncompatible = nullptr;
|
||||
delete m_bitmapLock;
|
||||
m_bitmapLock = nullptr;
|
||||
delete m_bitmapLockOpen;
|
||||
m_bitmapLockOpen = nullptr;
|
||||
delete m_bitmapCache;
|
||||
m_bitmapCache = nullptr;
|
||||
}
|
||||
|
||||
void PresetBundle::reset(bool delete_files)
|
||||
|
@ -486,36 +452,6 @@ void PresetBundle::export_selections(AppConfig &config)
|
|||
config.set("presets", "printer", printers.get_selected_preset_name());
|
||||
}
|
||||
|
||||
void PresetBundle::load_compatible_bitmaps()
|
||||
{
|
||||
*m_bitmapCompatible = create_scaled_bitmap("flag_green");
|
||||
*m_bitmapIncompatible = create_scaled_bitmap("flag_red");
|
||||
*m_bitmapLock = create_scaled_bitmap("lock_closed");
|
||||
*m_bitmapLockOpen = create_scaled_bitmap("lock_open");
|
||||
|
||||
prints .set_bitmap_compatible(m_bitmapCompatible);
|
||||
filaments .set_bitmap_compatible(m_bitmapCompatible);
|
||||
sla_prints .set_bitmap_compatible(m_bitmapCompatible);
|
||||
sla_materials.set_bitmap_compatible(m_bitmapCompatible);
|
||||
|
||||
prints .set_bitmap_incompatible(m_bitmapIncompatible);
|
||||
filaments .set_bitmap_incompatible(m_bitmapIncompatible);
|
||||
sla_prints .set_bitmap_incompatible(m_bitmapIncompatible);
|
||||
sla_materials.set_bitmap_incompatible(m_bitmapIncompatible);
|
||||
|
||||
prints .set_bitmap_lock(m_bitmapLock);
|
||||
filaments .set_bitmap_lock(m_bitmapLock);
|
||||
sla_prints .set_bitmap_lock(m_bitmapLock);
|
||||
sla_materials.set_bitmap_lock(m_bitmapLock);
|
||||
printers .set_bitmap_lock(m_bitmapLock);
|
||||
|
||||
prints .set_bitmap_lock_open(m_bitmapLock);
|
||||
filaments .set_bitmap_lock_open(m_bitmapLock);
|
||||
sla_prints .set_bitmap_lock_open(m_bitmapLock);
|
||||
sla_materials.set_bitmap_lock_open(m_bitmapLock);
|
||||
printers .set_bitmap_lock_open(m_bitmapLock);
|
||||
}
|
||||
|
||||
DynamicPrintConfig PresetBundle::full_config() const
|
||||
{
|
||||
return (this->printers.get_edited_preset().printer_technology() == ptFFF) ?
|
||||
|
@ -886,7 +822,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
|
|||
// 4) Load the project config values (the per extruder wipe matrix etc).
|
||||
this->project_config.apply_only(config, s_project_options);
|
||||
|
||||
update_custom_gcode_per_print_z_from_config(GUI::wxGetApp().plater()->model().custom_gcode_per_print_z, &this->project_config);
|
||||
CustomGCode::update_custom_gcode_per_print_z_from_config(GUI::wxGetApp().plater()->model().custom_gcode_per_print_z, &this->project_config);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1544,207 +1480,11 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst
|
|||
// an optional "(modified)" suffix will be removed from the filament name.
|
||||
void PresetBundle::set_filament_preset(size_t idx, const std::string &name)
|
||||
{
|
||||
if (name.find_first_of(PresetCollection::separator_head()) == 0)
|
||||
return;
|
||||
|
||||
if (idx >= filament_presets.size())
|
||||
if (idx >= filament_presets.size())
|
||||
filament_presets.resize(idx + 1, filaments.default_preset().name);
|
||||
filament_presets[idx] = Preset::remove_suffix_modified(name);
|
||||
}
|
||||
|
||||
void PresetBundle::load_default_preset_bitmaps()
|
||||
{
|
||||
// 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("cog");
|
||||
this->sla_prints.load_bitmap_default("cog");
|
||||
this->filaments.load_bitmap_default("spool.png");
|
||||
this->sla_materials.load_bitmap_default("resin");
|
||||
this->printers.load_bitmap_default("printer");
|
||||
this->printers.load_bitmap_add("add.png");
|
||||
this->load_compatible_bitmaps();
|
||||
}
|
||||
|
||||
void PresetBundle::update_plater_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui)
|
||||
{
|
||||
if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA ||
|
||||
this->filament_presets.size() <= idx_extruder )
|
||||
return;
|
||||
|
||||
unsigned char rgb[3];
|
||||
std::string extruder_color = this->printers.get_edited_preset().config.opt_string("extruder_colour", idx_extruder);
|
||||
if (!m_bitmapCache->parse_color(extruder_color, rgb))
|
||||
// Extruder color is not defined.
|
||||
extruder_color.clear();
|
||||
|
||||
// Fill in the list from scratch.
|
||||
ui->Freeze();
|
||||
ui->Clear();
|
||||
size_t selected_preset_item = INT_MAX; // some value meaning that no one item is selected
|
||||
|
||||
const Preset *selected_preset = this->filaments.find_preset(this->filament_presets[idx_extruder]);
|
||||
// Show wide icons if the currently selected preset is not compatible with the current printer,
|
||||
// and draw a red flag in front of the selected preset.
|
||||
bool wide_icons = selected_preset != nullptr && ! selected_preset->is_compatible && m_bitmapIncompatible != nullptr;
|
||||
assert(selected_preset != nullptr);
|
||||
std::map<wxString, wxBitmap*> nonsys_presets;
|
||||
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;
|
||||
|
||||
// To avoid the errors of number rounding for different combination of monitor configuration,
|
||||
// let use scaled 8px, as a smallest icon unit
|
||||
const int icon_unit = 8 * scale_f + 0.5f;
|
||||
const int normal_icon_width = 2 * icon_unit; //16 * scale_f + 0.5f;
|
||||
const int thin_icon_width = icon_unit; //8 * scale_f + 0.5f;
|
||||
const int wide_icon_width = 3 * icon_unit; //24 * scale_f + 0.5f;
|
||||
|
||||
const int space_icon_width = 2 * scale_f + 0.5f;
|
||||
|
||||
// To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so
|
||||
// set a bitmap height to m_bitmapLock->GetHeight()
|
||||
//
|
||||
// To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size.
|
||||
// But for some display scaling (for example 125% or 175%) normal_icon_width differs from icon width.
|
||||
// So:
|
||||
// for nonsystem presets set a width of empty bitmap to m_bitmapLock->GetWidth()
|
||||
// for compatible presets set a width of empty bitmap to m_bitmapIncompatible->GetWidth()
|
||||
//
|
||||
// Note, under OSX we should use a Scaled Height/Width because of Retina scale
|
||||
#ifdef __APPLE__
|
||||
const int icon_height = m_bitmapLock->GetScaledHeight();
|
||||
const int lock_icon_width = m_bitmapLock->GetScaledWidth();
|
||||
const int flag_icon_width = m_bitmapIncompatible->GetScaledWidth();
|
||||
#else
|
||||
const int icon_height = m_bitmapLock->GetHeight();
|
||||
const int lock_icon_width = m_bitmapLock->GetWidth();
|
||||
const int flag_icon_width = m_bitmapIncompatible->GetWidth();
|
||||
#endif
|
||||
|
||||
wxString tooltip = "";
|
||||
|
||||
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;
|
||||
if (! preset.is_visible || (! preset.is_compatible && ! selected))
|
||||
continue;
|
||||
// Assign an extruder color to the selected item if the extruder color is defined.
|
||||
std::string filament_rgb = preset.config.opt_string("filament_colour", 0);
|
||||
std::string extruder_rgb = (selected && !extruder_color.empty()) ? extruder_color : filament_rgb;
|
||||
bool single_bar = filament_rgb == extruder_rgb;
|
||||
std::string bitmap_key = single_bar ? filament_rgb : filament_rgb + extruder_rgb;
|
||||
// If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
|
||||
// to the filament color image.
|
||||
if (wide_icons)
|
||||
bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt";
|
||||
bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst";
|
||||
if (preset.is_dirty)
|
||||
bitmap_key += ",drty";
|
||||
wxBitmap *bitmap = m_bitmapCache->find(bitmap_key);
|
||||
if (bitmap == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
if (wide_icons)
|
||||
// Paint a red flag for incompatible presets.
|
||||
bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(flag_icon_width, icon_height) : *m_bitmapIncompatible);
|
||||
// Paint the color bars.
|
||||
m_bitmapCache->parse_color(filament_rgb, rgb);
|
||||
bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? wide_icon_width : normal_icon_width, icon_height, rgb));
|
||||
if (! single_bar) {
|
||||
m_bitmapCache->parse_color(extruder_rgb, 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(space_icon_width, icon_height));
|
||||
bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(lock_icon_width, icon_height));
|
||||
// (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16));
|
||||
bitmap = m_bitmapCache->insert(bitmap_key, bmps);
|
||||
}
|
||||
|
||||
const std::string name = preset.alias.empty() ? preset.name : preset.alias;
|
||||
if (preset.is_default || preset.is_system) {
|
||||
ui->Append(wxString::FromUTF8((/*preset.*/name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
|
||||
(bitmap == 0) ? wxNullBitmap : *bitmap);
|
||||
if (selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX ) {
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
tooltip = wxString::FromUTF8(preset.name.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nonsys_presets.emplace(wxString::FromUTF8((/*preset.*/name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
|
||||
(bitmap == 0) ? &wxNullBitmap : bitmap);
|
||||
if (selected) {
|
||||
selected_str = wxString::FromUTF8((/*preset.*/name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
|
||||
tooltip = wxString::FromUTF8(preset.name.c_str());
|
||||
}
|
||||
}
|
||||
if (preset.is_default)
|
||||
ui->set_label_marker(ui->Append(PresetCollection::separator(L("System presets")), wxNullBitmap));
|
||||
}
|
||||
|
||||
if (!nonsys_presets.empty())
|
||||
{
|
||||
ui->set_label_marker(ui->Append(PresetCollection::separator(L("User presets")), wxNullBitmap));
|
||||
for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
|
||||
ui->Append(it->first, *it->second);
|
||||
if (it->first == selected_str ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX) {
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string bitmap_key = "";
|
||||
if (wide_icons)
|
||||
bitmap_key += "wide,";
|
||||
bitmap_key += "edit_preset_list";
|
||||
wxBitmap* bmp = m_bitmapCache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
if (wide_icons)
|
||||
// Paint a red flag for incompatible presets.
|
||||
bmps.emplace_back(m_bitmapCache->mkclear(flag_icon_width, icon_height));
|
||||
// Paint the color bars + a lock at the system presets.
|
||||
bmps.emplace_back(m_bitmapCache->mkclear(wide_icon_width+space_icon_width, icon_height));
|
||||
bmps.emplace_back(create_scaled_bitmap("edit_uni"));
|
||||
bmp = m_bitmapCache->insert(bitmap_key, bmps);
|
||||
}
|
||||
ui->set_label_marker(ui->Append(PresetCollection::separator(L("Add/Remove filaments")), *bmp), GUI::PresetComboBox::LABEL_ITEM_WIZARD_FILAMENTS);
|
||||
|
||||
/* But, if selected_preset_item is still equal to INT_MAX, it means that
|
||||
* there is no presets added to the list.
|
||||
* So, select last combobox item ("Add/Remove filaments")
|
||||
*/
|
||||
if (selected_preset_item == INT_MAX)
|
||||
selected_preset_item = ui->GetCount() - 1;
|
||||
|
||||
ui->SetSelection(selected_preset_item);
|
||||
ui->SetToolTip(tooltip.IsEmpty() ? ui->GetString(selected_preset_item) : tooltip);
|
||||
ui->check_selection(selected_preset_item);
|
||||
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)
|
||||
{
|
||||
prints.set_default_suppressed(default_suppressed);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "Preset.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
|
@ -13,10 +12,6 @@ class wxWindow;
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace GUI {
|
||||
class BitmapCache;
|
||||
};
|
||||
|
||||
// Bundle of Print + Filament + Printer presets.
|
||||
class PresetBundle
|
||||
{
|
||||
|
@ -110,9 +105,6 @@ public:
|
|||
// Export a config bundle file containing all the presets and the names of the active presets.
|
||||
void export_configbundle(const std::string &path, bool export_system_settings = false);
|
||||
|
||||
// Update a filament selection combo box on the plater for an idx_extruder.
|
||||
void update_plater_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui);
|
||||
|
||||
// Enable / disable the "- default -" preset.
|
||||
void set_default_suppressed(bool default_suppressed);
|
||||
|
||||
|
@ -132,8 +124,6 @@ public:
|
|||
void update_compatible(PresetSelectCompatibleType select_other_print_if_incompatible, PresetSelectCompatibleType select_other_filament_if_incompatible);
|
||||
void update_compatible(PresetSelectCompatibleType select_other_if_incompatible) { this->update_compatible(select_other_if_incompatible, select_other_if_incompatible); }
|
||||
|
||||
void load_default_preset_bitmaps();
|
||||
|
||||
// Set the is_visible flag for printer vendors, printer models and printer variants
|
||||
// based on the user configuration.
|
||||
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
|
||||
|
@ -163,21 +153,9 @@ private:
|
|||
// If it is not an external config, then the config will be stored into the user profile directory.
|
||||
void load_config_file_config(const std::string &name_or_path, bool is_external, DynamicPrintConfig &&config);
|
||||
void load_config_file_config_bundle(const std::string &path, const boost::property_tree::ptree &tree);
|
||||
void load_compatible_bitmaps();
|
||||
|
||||
DynamicPrintConfig full_fff_config() const;
|
||||
DynamicPrintConfig full_sla_config() const;
|
||||
|
||||
// Indicator, that the preset is compatible with the selected printer.
|
||||
wxBitmap *m_bitmapCompatible;
|
||||
// Indicator, that the preset is NOT compatible with the selected printer.
|
||||
wxBitmap *m_bitmapIncompatible;
|
||||
// Indicator, that the preset is system and not modified.
|
||||
wxBitmap *m_bitmapLock;
|
||||
// Indicator, that the preset is system and user modified.
|
||||
wxBitmap *m_bitmapLockOpen;
|
||||
// Caching color bitmaps for the filament combo box.
|
||||
GUI::BitmapCache *m_bitmapCache;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
794
src/slic3r/GUI/PresetComboBoxes.cpp
Normal file
794
src/slic3r/GUI/PresetComboBoxes.cpp
Normal file
|
@ -0,0 +1,794 @@
|
|||
#include "PresetComboBoxes.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/colordlg.h>
|
||||
#include <wx/wupdlock.h>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "Plater.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "format.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include "PresetBundle.hpp"
|
||||
#include "PrintHostDialogs.hpp"
|
||||
#include "ConfigWizard.hpp"
|
||||
#include "../Utils/ASCIIFolding.hpp"
|
||||
#include "../Utils/PrintHost.hpp"
|
||||
#include "../Utils/FixModelByWin10.hpp"
|
||||
#include "../Utils/UndoRedo.hpp"
|
||||
#include "RemovableDriveManager.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
|
||||
using Slic3r::GUI::format_wxstr;
|
||||
|
||||
static const std::pair<unsigned int, unsigned int> THUMBNAIL_SIZE_3MF = { 256, 256 };
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
// ---------------------------------
|
||||
// *** PresetComboBox ***
|
||||
// ---------------------------------
|
||||
|
||||
/* For PresetComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina
|
||||
* (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean
|
||||
* "please scale this to such and such" but rather
|
||||
* "the wxImage is already sized for backing scale such and such". )
|
||||
* Unfortunately, the constructor changes the size of wxBitmap too.
|
||||
* Thus We need to use unscaled size value for bitmaps that we use
|
||||
* to avoid scaled size of control items.
|
||||
* For this purpose control drawing methods and
|
||||
* control size calculation methods (virtual) are overridden.
|
||||
**/
|
||||
|
||||
PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size) :
|
||||
wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, size, 0, nullptr, wxCB_READONLY),
|
||||
m_type(preset_type),
|
||||
m_last_selected(wxNOT_FOUND),
|
||||
m_em_unit(wxGetApp().em_unit()),
|
||||
m_preset_bundle(wxGetApp().preset_bundle),
|
||||
m_bitmap_cache(new BitmapCache)
|
||||
{
|
||||
SetFont(wxGetApp().normal_font());
|
||||
#ifdef _WIN32
|
||||
// Workaround for ignoring CBN_EDITCHANGE events, which are processed after the content of the combo box changes, so that
|
||||
// the index of the item inside CBN_EDITCHANGE may no more be valid.
|
||||
EnableTextChangedEvents(false);
|
||||
#endif /* _WIN32 */
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case Preset::TYPE_PRINT: {
|
||||
m_collection = &m_preset_bundle->prints;
|
||||
m_main_bitmap_name = "cog";
|
||||
break;
|
||||
}
|
||||
case Preset::TYPE_FILAMENT: {
|
||||
m_collection = &m_preset_bundle->filaments;
|
||||
m_main_bitmap_name = "spool";
|
||||
break;
|
||||
}
|
||||
case Preset::TYPE_SLA_PRINT: {
|
||||
m_collection = &m_preset_bundle->sla_prints;
|
||||
m_main_bitmap_name = "cog";
|
||||
break;
|
||||
}
|
||||
case Preset::TYPE_SLA_MATERIAL: {
|
||||
m_collection = &m_preset_bundle->sla_materials;
|
||||
m_main_bitmap_name = "resin";
|
||||
break;
|
||||
}
|
||||
case Preset::TYPE_PRINTER: {
|
||||
m_collection = &m_preset_bundle->printers;
|
||||
m_main_bitmap_name = "printer";
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
m_bitmapCompatible = ScalableBitmap(nullptr, "flag_green");
|
||||
m_bitmapIncompatible = ScalableBitmap(nullptr, "flag_red");
|
||||
m_bitmapLock = ScalableBitmap(nullptr, "lock_closed");
|
||||
|
||||
// parameters for an icon's drawing
|
||||
fill_width_height();
|
||||
}
|
||||
|
||||
PresetComboBox::~PresetComboBox()
|
||||
{
|
||||
delete m_bitmap_cache;
|
||||
m_bitmap_cache = nullptr;
|
||||
}
|
||||
|
||||
void PresetComboBox::set_label_marker(int item, LabelItemType label_item_type)
|
||||
{
|
||||
this->SetClientData(item, (void*)label_item_type);
|
||||
}
|
||||
|
||||
void PresetComboBox::msw_rescale()
|
||||
{
|
||||
m_em_unit = wxGetApp().em_unit();
|
||||
|
||||
m_bitmapLock.msw_rescale();
|
||||
m_bitmapIncompatible.msw_rescale();
|
||||
m_bitmapCompatible.msw_rescale();
|
||||
|
||||
// parameters for an icon's drawing
|
||||
fill_width_height();
|
||||
|
||||
// update the control to redraw the icons
|
||||
update();
|
||||
}
|
||||
|
||||
void PresetComboBox::fill_width_height()
|
||||
{
|
||||
// To avoid asserts, each added bitmap to wxBitmapCombobox should be the same size, so
|
||||
// set a bitmap's height to m_bitmapLock->GetHeight() and norm_icon_width to m_bitmapLock->GetWidth()
|
||||
icon_height = m_bitmapLock.GetBmpHeight();
|
||||
norm_icon_width = m_bitmapLock.GetBmpWidth();
|
||||
|
||||
/* 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 = (float)m_em_unit * 0.1f;
|
||||
|
||||
thin_icon_width = lroundf(8 * scale_f); // analogue to 8px;
|
||||
wide_icon_width = norm_icon_width + thin_icon_width;
|
||||
|
||||
space_icon_width = lroundf(2 * scale_f);
|
||||
thin_space_icon_width = 2 * space_icon_width;
|
||||
wide_space_icon_width = 3 * space_icon_width;
|
||||
}
|
||||
|
||||
wxString PresetComboBox::separator(const std::string& label)
|
||||
{
|
||||
return wxString::FromUTF8(separator_head()) + _(label) + wxString::FromUTF8(separator_tail());
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
bool PresetComboBox::OnAddBitmap(const wxBitmap& bitmap)
|
||||
{
|
||||
if (bitmap.IsOk())
|
||||
{
|
||||
// we should use scaled! size values of bitmap
|
||||
int width = (int)bitmap.GetScaledWidth();
|
||||
int height = (int)bitmap.GetScaledHeight();
|
||||
|
||||
if (m_usedImgSize.x < 0)
|
||||
{
|
||||
// If size not yet determined, get it from this image.
|
||||
m_usedImgSize.x = width;
|
||||
m_usedImgSize.y = height;
|
||||
|
||||
// Adjust control size to vertically fit the bitmap
|
||||
wxWindow* ctrl = GetControl();
|
||||
ctrl->InvalidateBestSize();
|
||||
wxSize newSz = ctrl->GetBestSize();
|
||||
wxSize sz = ctrl->GetSize();
|
||||
if (newSz.y > sz.y)
|
||||
ctrl->SetSize(sz.x, newSz.y);
|
||||
else
|
||||
DetermineIndent();
|
||||
}
|
||||
|
||||
wxCHECK_MSG(width == m_usedImgSize.x && height == m_usedImgSize.y,
|
||||
false,
|
||||
"you can only add images of same size");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PresetComboBox::OnDrawItem(wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int item,
|
||||
int flags) const
|
||||
{
|
||||
const wxBitmap& bmp = *(wxBitmap*)m_bitmaps[item];
|
||||
if (bmp.IsOk())
|
||||
{
|
||||
// we should use scaled! size values of bitmap
|
||||
wxCoord w = bmp.GetScaledWidth();
|
||||
wxCoord h = bmp.GetScaledHeight();
|
||||
|
||||
const int imgSpacingLeft = 4;
|
||||
|
||||
// Draw the image centered
|
||||
dc.DrawBitmap(bmp,
|
||||
rect.x + (m_usedImgSize.x - w) / 2 + imgSpacingLeft,
|
||||
rect.y + (rect.height - h) / 2,
|
||||
true);
|
||||
}
|
||||
|
||||
wxString text = GetString(item);
|
||||
if (!text.empty())
|
||||
dc.DrawText(text,
|
||||
rect.x + m_imgAreaWidth + 1,
|
||||
rect.y + (rect.height - dc.GetCharHeight()) / 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
// *** PlaterPresetComboBox ***
|
||||
// ---------------------------------
|
||||
|
||||
PlaterPresetComboBox::PlaterPresetComboBox(wxWindow *parent, Preset::Type preset_type) :
|
||||
PresetComboBox(parent, preset_type, wxSize(15 * wxGetApp().em_unit(), -1))
|
||||
{
|
||||
Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) {
|
||||
auto selected_item = evt.GetSelection();
|
||||
|
||||
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
|
||||
if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) {
|
||||
this->SetSelection(this->m_last_selected);
|
||||
evt.StopPropagation();
|
||||
if (marker == LABEL_ITEM_PHYSICAL_PRINTERS)
|
||||
{
|
||||
PhysicalPrinterDialog dlg;
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
if (marker >= LABEL_ITEM_WIZARD_PRINTERS) {
|
||||
ConfigWizard::StartPage sp = ConfigWizard::SP_WELCOME;
|
||||
switch (marker) {
|
||||
case LABEL_ITEM_WIZARD_PRINTERS: sp = ConfigWizard::SP_PRINTERS; break;
|
||||
case LABEL_ITEM_WIZARD_FILAMENTS: sp = ConfigWizard::SP_FILAMENTS; break;
|
||||
case LABEL_ITEM_WIZARD_MATERIALS: sp = ConfigWizard::SP_MATERIALS; break;
|
||||
default: break;
|
||||
}
|
||||
wxTheApp->CallAfter([sp]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, sp); });
|
||||
}
|
||||
} else if ( this->m_last_selected != selected_item || m_collection->current_is_dirty() ) {
|
||||
this->m_last_selected = selected_item;
|
||||
evt.SetInt(this->m_type);
|
||||
evt.Skip();
|
||||
} else {
|
||||
evt.StopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
if (m_type == Preset::TYPE_FILAMENT)
|
||||
{
|
||||
Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &event) {
|
||||
const Preset* selected_preset = m_collection->find_preset(m_preset_bundle->filament_presets[m_extruder_idx]);
|
||||
// Wide icons are shown if the currently selected preset is not compatible with the current printer,
|
||||
// and red flag is drown in front of the selected preset.
|
||||
bool wide_icons = selected_preset != nullptr && !selected_preset->is_compatible;
|
||||
float scale = m_em_unit*0.1f;
|
||||
|
||||
int shifl_Left = wide_icons ? int(scale * 16 + 0.5) : 0;
|
||||
#if defined(wxBITMAPCOMBOBOX_OWNERDRAWN_BASED)
|
||||
shifl_Left += int(scale * 4 + 0.5f); // IMAGE_SPACING_RIGHT = 4 for wxBitmapComboBox -> Space left of image
|
||||
#endif
|
||||
int icon_right_pos = shifl_Left + int(scale * (24+4) + 0.5);
|
||||
int mouse_pos = event.GetLogicalPosition(wxClientDC(this)).x;
|
||||
if (mouse_pos < shifl_Left || mouse_pos > icon_right_pos ) {
|
||||
// Let the combo box process the mouse click.
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Swallow the mouse click and open the color picker.
|
||||
|
||||
// get current color
|
||||
DynamicPrintConfig* cfg = wxGetApp().get_tab(Preset::TYPE_PRINTER)->get_config();
|
||||
auto colors = static_cast<ConfigOptionStrings*>(cfg->option("extruder_colour")->clone());
|
||||
wxColour clr(colors->values[m_extruder_idx]);
|
||||
if (!clr.IsOk())
|
||||
clr = wxColour(0,0,0); // Don't set alfa to transparence
|
||||
|
||||
auto data = new wxColourData();
|
||||
data->SetChooseFull(1);
|
||||
data->SetColour(clr);
|
||||
|
||||
wxColourDialog dialog(this, data);
|
||||
dialog.CenterOnParent();
|
||||
if (dialog.ShowModal() == wxID_OK)
|
||||
{
|
||||
colors->values[m_extruder_idx] = dialog.GetColourData().GetColour().GetAsString(wxC2S_HTML_SYNTAX).ToStdString();
|
||||
|
||||
DynamicPrintConfig cfg_new = *cfg;
|
||||
cfg_new.set_key_value("extruder_colour", colors);
|
||||
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg_new);
|
||||
this->update();
|
||||
wxGetApp().plater()->on_config_change(cfg_new);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
edit_btn = new ScalableButton(parent, wxID_ANY, "cog");
|
||||
edit_btn->SetToolTip(_L("Click to edit preset"));
|
||||
|
||||
edit_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent)
|
||||
{
|
||||
Tab* tab = wxGetApp().get_tab(m_type);
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
int page_id = wxGetApp().tab_panel()->FindPage(tab);
|
||||
if (page_id == wxNOT_FOUND)
|
||||
return;
|
||||
|
||||
wxGetApp().tab_panel()->SetSelection(page_id);
|
||||
|
||||
// Switch to Settings NotePad
|
||||
wxGetApp().mainframe->select_tab();
|
||||
|
||||
/* In a case of a multi-material printing, for editing another Filament Preset
|
||||
* it's needed to select this preset for the "Filament settings" Tab
|
||||
*/
|
||||
if (m_type == Preset::TYPE_FILAMENT && wxGetApp().extruders_edited_cnt() > 1)
|
||||
{
|
||||
const std::string& selected_preset = GetString(GetSelection()).ToUTF8().data();
|
||||
|
||||
// Call select_preset() only if there is new preset and not just modified
|
||||
if ( !boost::algorithm::ends_with(selected_preset, Preset::suffix_modified()) )
|
||||
{
|
||||
const std::string& preset_name = wxGetApp().preset_bundle->filaments.get_preset_name_by_alias(selected_preset);
|
||||
tab->select_preset(preset_name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PlaterPresetComboBox::~PlaterPresetComboBox()
|
||||
{
|
||||
if (edit_btn)
|
||||
edit_btn->Destroy();
|
||||
}
|
||||
|
||||
// Only the compatible presets are shown.
|
||||
// If an incompatible preset is selected, it is shown as well.
|
||||
void PlaterPresetComboBox::update()
|
||||
{
|
||||
if (m_type == Preset::TYPE_FILAMENT &&
|
||||
(m_collection->get_edited_preset().printer_technology() == ptSLA ||
|
||||
m_preset_bundle->filament_presets.size() <= m_extruder_idx) )
|
||||
return;
|
||||
|
||||
// Otherwise fill in the list from scratch.
|
||||
this->Freeze();
|
||||
this->Clear();
|
||||
size_t selected_preset_item = INT_MAX; // some value meaning that no one item is selected
|
||||
|
||||
const Preset* selected_filament_preset;
|
||||
std::string extruder_color;
|
||||
if (m_type == Preset::TYPE_FILAMENT)
|
||||
{
|
||||
unsigned char rgb[3];
|
||||
extruder_color = m_preset_bundle->printers.get_edited_preset().config.opt_string("extruder_colour", (unsigned int)m_extruder_idx);
|
||||
if (!m_bitmap_cache->parse_color(extruder_color, rgb))
|
||||
// Extruder color is not defined.
|
||||
extruder_color.clear();
|
||||
selected_filament_preset = m_collection->find_preset(m_preset_bundle->filament_presets[m_extruder_idx]);
|
||||
assert(selected_filament_preset);
|
||||
}
|
||||
|
||||
const Preset& selected_preset = m_type == Preset::TYPE_FILAMENT ? *selected_filament_preset : m_collection->get_selected_preset();
|
||||
// Show wide icons if the currently selected preset is not compatible with the current printer,
|
||||
// and draw a red flag in front of the selected preset.
|
||||
bool wide_icons = !selected_preset.is_compatible;
|
||||
|
||||
std::map<wxString, wxBitmap*> nonsys_presets;
|
||||
std::map<wxString, wxBitmap*> physical_printers;
|
||||
|
||||
wxString selected = "";
|
||||
wxString tooltip = "";
|
||||
const std::deque<Preset>& presets = m_collection->get_presets();
|
||||
|
||||
if (!presets.front().is_visible)
|
||||
this->set_label_marker(this->Append(separator(L("System presets")), wxNullBitmap));
|
||||
|
||||
for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i)
|
||||
{
|
||||
const Preset& preset = presets[i];
|
||||
bool is_selected = m_type == Preset::TYPE_FILAMENT ?
|
||||
m_preset_bundle->filament_presets[m_extruder_idx] == preset.name :
|
||||
i == m_collection->get_selected_idx();
|
||||
|
||||
if (!preset.is_visible || (!preset.is_compatible && !is_selected))
|
||||
continue;
|
||||
|
||||
std::string bitmap_key, filament_rgb, extruder_rgb;
|
||||
bool single_bar = false;
|
||||
if (m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA)
|
||||
bitmap_key = "sla_printer";
|
||||
else if (m_type == Preset::TYPE_FILAMENT)
|
||||
{
|
||||
// Assign an extruder color to the selected item if the extruder color is defined.
|
||||
filament_rgb = preset.config.opt_string("filament_colour", 0);
|
||||
extruder_rgb = (selected && !extruder_color.empty()) ? extruder_color : filament_rgb;
|
||||
single_bar = filament_rgb == extruder_rgb;
|
||||
|
||||
bitmap_key = single_bar ? filament_rgb : filament_rgb + extruder_rgb;
|
||||
}
|
||||
wxBitmap main_bmp = create_scaled_bitmap(m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name);
|
||||
|
||||
// If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
|
||||
// to the filament color image.
|
||||
if (wide_icons)
|
||||
bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt";
|
||||
bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst";
|
||||
bitmap_key += "-h" + std::to_string(icon_height);
|
||||
|
||||
wxBitmap* bmp = m_bitmap_cache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
if (wide_icons)
|
||||
// Paint a red flag for incompatible presets.
|
||||
bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(norm_icon_width, icon_height) : m_bitmapIncompatible.bmp());
|
||||
|
||||
if (m_type == Preset::TYPE_FILAMENT)
|
||||
{
|
||||
unsigned char rgb[3];
|
||||
// Paint the color bars.
|
||||
m_bitmap_cache->parse_color(filament_rgb, rgb);
|
||||
bmps.emplace_back(m_bitmap_cache->mksolid(single_bar ? wide_icon_width : norm_icon_width, icon_height, rgb));
|
||||
if (!single_bar) {
|
||||
m_bitmap_cache->parse_color(extruder_rgb, rgb);
|
||||
bmps.emplace_back(m_bitmap_cache->mksolid(thin_icon_width, icon_height, rgb));
|
||||
}
|
||||
// Paint a lock at the system presets.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(space_icon_width, icon_height));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Paint the color bars.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height));
|
||||
bmps.emplace_back(main_bmp);
|
||||
// Paint a lock at the system presets.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height));
|
||||
}
|
||||
bmps.emplace_back((preset.is_system || preset.is_default) ? m_bitmapLock.bmp() : m_bitmap_cache->mkclear(norm_icon_width, icon_height));
|
||||
bmp = m_bitmap_cache->insert(bitmap_key, bmps);
|
||||
}
|
||||
|
||||
const std::string name = preset.alias.empty() ? preset.name : preset.alias;
|
||||
if (preset.is_default || preset.is_system) {
|
||||
Append(wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
|
||||
!bmp ? main_bmp : *bmp);
|
||||
if (is_selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX) {
|
||||
selected_preset_item = GetCount() - 1;
|
||||
tooltip = wxString::FromUTF8(preset.name.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nonsys_presets.emplace(wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), bmp);
|
||||
if (is_selected) {
|
||||
selected = wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
|
||||
tooltip = wxString::FromUTF8(preset.name.c_str());
|
||||
}
|
||||
}
|
||||
if (i + 1 == m_collection->num_default_presets())
|
||||
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
|
||||
}
|
||||
if (!nonsys_presets.empty())
|
||||
{
|
||||
set_label_marker(Append(separator(L("User presets")), wxNullBitmap));
|
||||
for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
|
||||
Append(it->first, *it->second);
|
||||
if (it->first == selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX)
|
||||
selected_preset_item = GetCount() - 1;
|
||||
}
|
||||
}
|
||||
if (!physical_printers.empty())
|
||||
{
|
||||
set_label_marker(Append(separator(L("Physical printers")), wxNullBitmap));
|
||||
for (std::map<wxString, wxBitmap*>::iterator it = physical_printers.begin(); it != physical_printers.end(); ++it) {
|
||||
Append(it->first, *it->second);
|
||||
if (it->first == selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX)
|
||||
selected_preset_item = GetCount() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_type == Preset::TYPE_PRINTER || m_type == Preset::TYPE_SLA_MATERIAL) {
|
||||
std::string bitmap_key = "";
|
||||
// If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
|
||||
// to the filament color image.
|
||||
if (wide_icons)
|
||||
bitmap_key += "wide,";
|
||||
bitmap_key += "edit_preset_list";
|
||||
bitmap_key += "-h" + std::to_string(icon_height);
|
||||
|
||||
wxBitmap* bmp = m_bitmap_cache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.update_plater_ui
|
||||
std::vector<wxBitmap> bmps;
|
||||
if (wide_icons)
|
||||
// Paint a red flag for incompatible presets.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(norm_icon_width, icon_height));
|
||||
// Paint the color bars.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height));
|
||||
bmps.emplace_back(create_scaled_bitmap(m_main_bitmap_name));
|
||||
// Paint a lock at the system presets.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height));
|
||||
bmps.emplace_back(create_scaled_bitmap("edit_uni"));
|
||||
bmp = m_bitmap_cache->insert(bitmap_key, bmps);
|
||||
}
|
||||
if (m_type == Preset::TYPE_SLA_MATERIAL)
|
||||
set_label_marker(Append(separator(L("Add/Remove materials")), *bmp), LABEL_ITEM_WIZARD_MATERIALS);
|
||||
else
|
||||
set_label_marker(Append(separator(L("Add/Remove printers")), *bmp), LABEL_ITEM_WIZARD_PRINTERS);
|
||||
}
|
||||
if (m_type == Preset::TYPE_PRINTER) {
|
||||
std::string bitmap_key = "";
|
||||
if (wide_icons)
|
||||
bitmap_key += "wide,";
|
||||
bitmap_key += "edit_preset_list";
|
||||
bitmap_key += "-h" + std::to_string(icon_height);
|
||||
|
||||
wxBitmap* bmp = m_bitmap_cache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
if (wide_icons)
|
||||
// Paint a red flag for incompatible presets.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(norm_icon_width, icon_height));
|
||||
// Paint the color bars.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(thin_space_icon_width, icon_height));
|
||||
bmps.emplace_back(create_scaled_bitmap("printer"));
|
||||
// Paint a lock at the system presets.
|
||||
bmps.emplace_back(m_bitmap_cache->mkclear(wide_space_icon_width, icon_height));
|
||||
bmps.emplace_back(create_scaled_bitmap("edit_uni"));
|
||||
bmp = m_bitmap_cache->insert(bitmap_key, bmps);
|
||||
}
|
||||
set_label_marker(Append(separator(L("Add physical printer")), *bmp), LABEL_ITEM_PHYSICAL_PRINTERS);
|
||||
}
|
||||
|
||||
/* But, if selected_preset_item is still equal to INT_MAX, it means that
|
||||
* there is no presets added to the list.
|
||||
* So, select last combobox item ("Add/Remove preset")
|
||||
*/
|
||||
if (selected_preset_item == INT_MAX)
|
||||
selected_preset_item = GetCount() - 1;
|
||||
|
||||
SetSelection(selected_preset_item);
|
||||
SetToolTip(tooltip.IsEmpty() ? GetString(selected_preset_item) : tooltip);
|
||||
m_last_selected = selected_preset_item;
|
||||
Thaw();
|
||||
|
||||
// Update control min size after rescale (changed Display DPI under MSW)
|
||||
if (GetMinWidth() != 20 * m_em_unit)
|
||||
SetMinSize(wxSize(20 * m_em_unit, GetSize().GetHeight()));
|
||||
}
|
||||
|
||||
void PlaterPresetComboBox::msw_rescale()
|
||||
{
|
||||
PresetComboBox::msw_rescale();
|
||||
edit_btn->msw_rescale();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
// *** PlaterPresetComboBox ***
|
||||
// ---------------------------------
|
||||
|
||||
TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type) :
|
||||
PresetComboBox(parent, preset_type, wxSize(35 * wxGetApp().em_unit(), -1))
|
||||
{
|
||||
Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
|
||||
// see https://github.com/prusa3d/PrusaSlicer/issues/3889
|
||||
// Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
|
||||
// m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
|
||||
// So, use GetSelection() from event parameter
|
||||
auto selected_item = evt.GetSelection();
|
||||
|
||||
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
|
||||
if (marker >= LABEL_ITEM_MARKER && marker < LABEL_ITEM_MAX) {
|
||||
this->SetSelection(this->m_last_selected);
|
||||
if (marker == LABEL_ITEM_WIZARD_PRINTERS)
|
||||
wxTheApp->CallAfter([]() { wxGetApp().run_wizard(ConfigWizard::RR_USER, ConfigWizard::SP_PRINTERS); });
|
||||
}
|
||||
else if (m_last_selected != selected_item || m_collection->current_is_dirty()) {
|
||||
std::string selected_string = this->GetString(selected_item).ToUTF8().data();
|
||||
Tab* tab = wxGetApp().get_tab(this->m_type);
|
||||
assert (tab);
|
||||
tab->select_preset(selected_string);
|
||||
}
|
||||
|
||||
evt.StopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
// 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.
|
||||
void TabPresetComboBox::update()
|
||||
{
|
||||
Freeze();
|
||||
Clear();
|
||||
size_t selected_preset_item = INT_MAX; // some value meaning that no one item is selected
|
||||
|
||||
const std::deque<Preset>& presets = m_collection->get_presets();
|
||||
|
||||
std::map<wxString, wxBitmap*> nonsys_presets;
|
||||
wxString selected = "";
|
||||
if (!presets.front().is_visible)
|
||||
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
|
||||
int idx_selected = m_collection->get_selected_idx();
|
||||
for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i) {
|
||||
const Preset& preset = presets[i];
|
||||
if (!preset.is_visible || (!show_incompatible && !preset.is_compatible && i != idx_selected))
|
||||
continue;
|
||||
|
||||
std::string bitmap_key = "tab";
|
||||
wxBitmap main_bmp = create_scaled_bitmap(m_type == Preset::TYPE_PRINTER && preset.printer_technology() == ptSLA ? "sla_printer" : m_main_bitmap_name);
|
||||
if (m_type == Preset::TYPE_PRINTER) {
|
||||
bitmap_key += "_printer";
|
||||
if (preset.printer_technology() == ptSLA)
|
||||
bitmap_key += "_sla";
|
||||
}
|
||||
bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt";
|
||||
bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst";
|
||||
bitmap_key += "-h" + std::to_string(icon_height);
|
||||
|
||||
wxBitmap* bmp = m_bitmap_cache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
bmps.emplace_back(m_type == Preset::TYPE_PRINTER ? main_bmp : preset.is_compatible ? m_bitmapCompatible.bmp() : m_bitmapIncompatible.bmp());
|
||||
// Paint a lock at the system presets.
|
||||
bmps.emplace_back((preset.is_system || preset.is_default) ? m_bitmapLock.bmp() : m_bitmap_cache->mkclear(norm_icon_width, icon_height));
|
||||
bmp = m_bitmap_cache->insert(bitmap_key, bmps);
|
||||
}
|
||||
|
||||
if (preset.is_default || preset.is_system) {
|
||||
Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
|
||||
(bmp == 0) ? main_bmp : *bmp);
|
||||
if (i == idx_selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX)
|
||||
selected_preset_item = GetCount() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), bmp);
|
||||
if (i == idx_selected)
|
||||
selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
|
||||
}
|
||||
if (i + 1 == m_collection->num_default_presets())
|
||||
set_label_marker(Append(separator(L("System presets")), wxNullBitmap));
|
||||
}
|
||||
if (!nonsys_presets.empty())
|
||||
{
|
||||
set_label_marker(Append(separator(L("User presets")), wxNullBitmap));
|
||||
for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
|
||||
Append(it->first, *it->second);
|
||||
if (it->first == selected ||
|
||||
// just in case: mark selected_preset_item as a first added element
|
||||
selected_preset_item == INT_MAX)
|
||||
selected_preset_item = GetCount() - 1;
|
||||
}
|
||||
}
|
||||
if (m_type == Preset::TYPE_PRINTER) {
|
||||
std::string bitmap_key = "edit_preset_list";
|
||||
bitmap_key += "-h" + std::to_string(icon_height);
|
||||
|
||||
wxBitmap* bmp = m_bitmap_cache->find(bitmap_key);
|
||||
if (bmp == nullptr) {
|
||||
// Create the bitmap with color bars.
|
||||
std::vector<wxBitmap> bmps;
|
||||
bmps.emplace_back(create_scaled_bitmap(m_main_bitmap_name));
|
||||
bmps.emplace_back(create_scaled_bitmap("edit_uni"));
|
||||
bmp = m_bitmap_cache->insert(bitmap_key, bmps);
|
||||
}
|
||||
set_label_marker(Append(separator(L("Add/Remove printers")), *bmp), LABEL_ITEM_WIZARD_PRINTERS);
|
||||
}
|
||||
|
||||
/* But, if selected_preset_item is still equal to INT_MAX, it means that
|
||||
* there is no presets added to the list.
|
||||
* So, select last combobox item ("Add/Remove preset")
|
||||
*/
|
||||
if (selected_preset_item == INT_MAX)
|
||||
selected_preset_item = GetCount() - 1;
|
||||
|
||||
SetSelection(selected_preset_item);
|
||||
SetToolTip(GetString(selected_preset_item));
|
||||
Thaw();
|
||||
|
||||
m_last_selected = selected_preset_item;
|
||||
}
|
||||
|
||||
void TabPresetComboBox::msw_rescale()
|
||||
{
|
||||
PresetComboBox::msw_rescale();
|
||||
wxSize sz = wxSize(35 * m_em_unit, -1);
|
||||
SetMinSize(sz);
|
||||
SetSize(sz);
|
||||
}
|
||||
|
||||
void TabPresetComboBox::update_dirty()
|
||||
{
|
||||
// 1) Update the dirty flag of the current preset.
|
||||
m_collection->update_dirty();
|
||||
|
||||
// 2) Update the labels.
|
||||
wxWindowUpdateLocker noUpdates(this);
|
||||
for (unsigned int ui_id = 0; ui_id < GetCount(); ++ui_id) {
|
||||
std::string old_label = GetString(ui_id).utf8_str().data();
|
||||
std::string preset_name = Preset::remove_suffix_modified(old_label);
|
||||
const Preset* preset = m_collection->find_preset(preset_name, false);
|
||||
if (preset) {
|
||||
std::string new_label = preset->is_dirty ? preset->name + Preset::suffix_modified() : preset->name;
|
||||
if (old_label != new_label)
|
||||
SetString(ui_id, wxString::FromUTF8(new_label.c_str()));
|
||||
}
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
// wxWidgets on OSX do not upload the text of the combo box line automatically.
|
||||
// Force it to update by re-selecting.
|
||||
SetSelection(GetSelection());
|
||||
#endif /* __APPLE __ */
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------
|
||||
// PhysicalPrinterDialog
|
||||
//------------------------------------------
|
||||
|
||||
|
||||
PhysicalPrinterDialog::PhysicalPrinterDialog()
|
||||
: DPIDialog(NULL, wxID_ANY, _L("Search"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
{
|
||||
SetFont(wxGetApp().normal_font());
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
|
||||
int border = 10;
|
||||
int em = em_unit();
|
||||
|
||||
printer_text = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
|
||||
printer_presets = new PlaterPresetComboBox(this, Preset::TYPE_PRINTER);
|
||||
|
||||
wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
||||
|
||||
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
topSizer->Add(printer_text , 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
|
||||
topSizer->Add(printer_presets , 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, border);
|
||||
topSizer->Add(btns , 0, wxEXPAND | wxALL, border);
|
||||
|
||||
SetSizer(topSizer);
|
||||
topSizer->SetSizeHints(this);
|
||||
}
|
||||
|
||||
void PhysicalPrinterDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
const int& em = em_unit();
|
||||
|
||||
msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL });
|
||||
|
||||
const wxSize& size = wxSize(40 * em, 30 * em);
|
||||
SetMinSize(size);
|
||||
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
}} // namespace Slic3r::GUI
|
179
src/slic3r/GUI/PresetComboBoxes.hpp
Normal file
179
src/slic3r/GUI/PresetComboBoxes.hpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
#ifndef slic3r_PresetComboBoxes_hpp_
|
||||
#define slic3r_PresetComboBoxes_hpp_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <wx/bmpcbox.h>
|
||||
#include <wx/gdicmn.h>
|
||||
|
||||
#include "Preset.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
|
||||
class wxString;
|
||||
class wxTextCtrl;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace GUI {
|
||||
|
||||
class BitmapCache;
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
// *** PresetComboBox ***
|
||||
// ---------------------------------
|
||||
|
||||
// BitmapComboBox used to presets list on Sidebar and Tabs
|
||||
class PresetComboBox : public wxBitmapComboBox
|
||||
{
|
||||
public:
|
||||
PresetComboBox(wxWindow* parent, Preset::Type preset_type, const wxSize& size = wxDefaultSize);
|
||||
~PresetComboBox();
|
||||
|
||||
enum LabelItemType {
|
||||
LABEL_ITEM_MARKER = 0xffffff01,
|
||||
LABEL_ITEM_PHYSICAL_PRINTERS,
|
||||
LABEL_ITEM_WIZARD_PRINTERS,
|
||||
LABEL_ITEM_WIZARD_FILAMENTS,
|
||||
LABEL_ITEM_WIZARD_MATERIALS,
|
||||
|
||||
LABEL_ITEM_MAX,
|
||||
};
|
||||
|
||||
void set_label_marker(int item, LabelItemType label_item_type = LABEL_ITEM_MARKER);
|
||||
int em_unit() const { return m_em_unit; }
|
||||
|
||||
virtual void update() {};
|
||||
virtual void msw_rescale();
|
||||
|
||||
protected:
|
||||
typedef std::size_t Marker;
|
||||
|
||||
Preset::Type m_type;
|
||||
std::string m_main_bitmap_name;
|
||||
|
||||
PresetBundle* m_preset_bundle {nullptr};
|
||||
PresetCollection* m_collection {nullptr};
|
||||
|
||||
// Caching color bitmaps for the filament combo box.
|
||||
BitmapCache* m_bitmap_cache {nullptr};
|
||||
// Indicator, that the preset is compatible with the selected printer.
|
||||
ScalableBitmap m_bitmapCompatible;
|
||||
// Indicator, that the preset is NOT compatible with the selected printer.
|
||||
ScalableBitmap m_bitmapIncompatible;
|
||||
// Indicator, that the preset is system and not modified.
|
||||
ScalableBitmap m_bitmapLock;
|
||||
|
||||
int m_last_selected;
|
||||
int m_em_unit;
|
||||
|
||||
// parameters for an icon's drawing
|
||||
int icon_height;
|
||||
int norm_icon_width;
|
||||
int thin_icon_width;
|
||||
int wide_icon_width;
|
||||
int space_icon_width;
|
||||
int thin_space_icon_width;
|
||||
int wide_space_icon_width;
|
||||
|
||||
#ifdef __linux__
|
||||
static const char* separator_head() { return "------- "; }
|
||||
static const char* separator_tail() { return " -------"; }
|
||||
#else // __linux__
|
||||
static const char* separator_head() { return "————— "; }
|
||||
static const char* separator_tail() { return " —————"; }
|
||||
#endif // __linux__
|
||||
static wxString separator(const std::string& label);
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* For PresetComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina
|
||||
* (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean
|
||||
* "please scale this to such and such" but rather
|
||||
* "the wxImage is already sized for backing scale such and such". )
|
||||
* Unfortunately, the constructor changes the size of wxBitmap too.
|
||||
* Thus We need to use unscaled size value for bitmaps that we use
|
||||
* to avoid scaled size of control items.
|
||||
* For this purpose control drawing methods and
|
||||
* control size calculation methods (virtual) are overridden.
|
||||
**/
|
||||
virtual bool OnAddBitmap(const wxBitmap& bitmap) override;
|
||||
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, int item, int flags) const override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void fill_width_height();
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
// *** PlaterPresetComboBox ***
|
||||
// ---------------------------------
|
||||
|
||||
class PlaterPresetComboBox : public PresetComboBox
|
||||
{
|
||||
public:
|
||||
PlaterPresetComboBox(wxWindow *parent, Preset::Type preset_type);
|
||||
~PlaterPresetComboBox();
|
||||
|
||||
ScalableButton* edit_btn { nullptr };
|
||||
|
||||
void set_extruder_idx(const int extr_idx) { m_extruder_idx = extr_idx; }
|
||||
int get_extruder_idx() const { return m_extruder_idx; }
|
||||
|
||||
void update() override;
|
||||
void msw_rescale() override;
|
||||
|
||||
private:
|
||||
int m_extruder_idx = -1;
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
// *** PlaterPresetComboBox ***
|
||||
// ---------------------------------
|
||||
|
||||
class TabPresetComboBox : public PresetComboBox
|
||||
{
|
||||
public:
|
||||
TabPresetComboBox(wxWindow *parent, Preset::Type preset_type);
|
||||
~TabPresetComboBox() {}
|
||||
void set_show_incompatible_presets(bool show_incompatible_presets) {
|
||||
show_incompatible = show_incompatible_presets;
|
||||
}
|
||||
|
||||
void update() override;
|
||||
void update_dirty();
|
||||
void msw_rescale() override;
|
||||
|
||||
private:
|
||||
bool show_incompatible{false};
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------
|
||||
// PhysicalPrinterDialog
|
||||
//------------------------------------------
|
||||
|
||||
class PhysicalPrinterDialog : public DPIDialog
|
||||
{
|
||||
std::string printer_name;
|
||||
std::string preset_name;
|
||||
|
||||
wxTextCtrl* printer_text { nullptr };
|
||||
PresetComboBox* printer_presets;
|
||||
|
||||
public:
|
||||
PhysicalPrinterDialog();
|
||||
~PhysicalPrinterDialog() {}
|
||||
|
||||
protected:
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
void on_sys_color_changed() override {};
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "wxExtensions.hpp"
|
||||
#include "PresetComboBoxes.hpp"
|
||||
#include <wx/wupdlock.h>
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
|
@ -160,10 +161,7 @@ void Tab::create_preset_tab()
|
|||
#endif //__WXOSX__
|
||||
|
||||
// preset chooser
|
||||
m_presets_choice = new PresetBitmapComboBox(panel, wxSize(35 * m_em_unit, -1));
|
||||
|
||||
// search combox
|
||||
// m_search = new Search::SearchCtrl(panel);
|
||||
m_presets_choice = new TabPresetComboBox(panel, m_type);
|
||||
|
||||
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||
|
||||
|
@ -278,35 +276,6 @@ void Tab::create_preset_tab()
|
|||
m_treectrl->Bind(wxEVT_TREE_SEL_CHANGED, &Tab::OnTreeSelChange, this);
|
||||
m_treectrl->Bind(wxEVT_KEY_DOWN, &Tab::OnKeyDown, this);
|
||||
|
||||
m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) {
|
||||
//! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox,
|
||||
//! but the OSX version derived from wxOwnerDrawnCombo, instead of:
|
||||
//! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data());
|
||||
//! we doing next:
|
||||
// int selected_item = m_presets_choice->GetSelection();
|
||||
|
||||
// see https://github.com/prusa3d/PrusaSlicer/issues/3889
|
||||
// Under OSX: in case of use of a same names written in different case (like "ENDER" and "Ender")
|
||||
// m_presets_choice->GetSelection() will return first item, because search in PopupListCtrl is case-insensitive.
|
||||
// So, use GetSelection() from event parameter
|
||||
int selected_item = e.GetSelection();
|
||||
if (m_selected_preset_item == size_t(selected_item) && !m_presets->current_is_dirty())
|
||||
return;
|
||||
if (selected_item >= 0) {
|
||||
std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data();
|
||||
if (selected_string.find(PresetCollection::separator_head()) == 0
|
||||
/*selected_string == "------- System presets -------" ||
|
||||
selected_string == "------- User presets -------"*/) {
|
||||
m_presets_choice->SetSelection(m_selected_preset_item);
|
||||
if (wxString::FromUTF8(selected_string.c_str()) == PresetCollection::separator(L("Add a new printer")))
|
||||
wxTheApp->CallAfter([]() { wxGetApp().run_wizard(ConfigWizard::RR_USER); });
|
||||
return;
|
||||
}
|
||||
m_selected_preset_item = selected_item;
|
||||
select_preset(selected_string);
|
||||
}
|
||||
}));
|
||||
|
||||
m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); }));
|
||||
m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); }));
|
||||
m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) {
|
||||
|
@ -778,14 +747,14 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
|
|||
// comparing the selected preset config with $self->{config}.
|
||||
void Tab::update_dirty()
|
||||
{
|
||||
m_presets->update_dirty_ui(m_presets_choice);
|
||||
m_presets_choice->update_dirty();
|
||||
on_presets_changed();
|
||||
update_changed_ui();
|
||||
}
|
||||
|
||||
void Tab::update_tab_ui()
|
||||
{
|
||||
m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets, m_em_unit);
|
||||
m_presets_choice->update();
|
||||
}
|
||||
|
||||
// Load a provied DynamicConfig into the tab, modifying the active preset.
|
||||
|
@ -850,12 +819,10 @@ void Tab::msw_rescale()
|
|||
m_em_unit = wxGetApp().em_unit();
|
||||
|
||||
m_mode_sizer->msw_rescale();
|
||||
m_presets_choice->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();
|
||||
|
@ -963,7 +930,7 @@ void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bo
|
|||
// Don't select another profile if this profile happens to become incompatible.
|
||||
m_preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
|
||||
}
|
||||
m_presets->update_dirty_ui(m_presets_choice);
|
||||
m_presets_choice->update_dirty();
|
||||
on_presets_changed();
|
||||
update();
|
||||
}
|
||||
|
@ -3360,6 +3327,7 @@ void Tab::delete_preset()
|
|||
void Tab::toggle_show_hide_incompatible()
|
||||
{
|
||||
m_show_incompatible_presets = !m_show_incompatible_presets;
|
||||
m_presets_choice->set_show_incompatible_presets(m_show_incompatible_presets);
|
||||
update_show_hide_incompatible_button();
|
||||
update_tab_ui();
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class TabPresetComboBox;
|
||||
|
||||
// Single Tab page containing a{ vsizer } of{ optgroups }
|
||||
// package Slic3r::GUI::Tab::Page;
|
||||
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
|
||||
|
@ -113,7 +115,7 @@ protected:
|
|||
Preset::Type m_type;
|
||||
std::string m_name;
|
||||
const wxString m_title;
|
||||
PresetBitmapComboBox* m_presets_choice;
|
||||
TabPresetComboBox* m_presets_choice;
|
||||
ScalableButton* m_search_btn;
|
||||
ScalableButton* m_btn_save_preset;
|
||||
ScalableButton* m_btn_delete_preset;
|
||||
|
@ -206,8 +208,6 @@ protected:
|
|||
bool m_is_nonsys_values{ true };
|
||||
bool m_postpone_update_ui {false};
|
||||
|
||||
size_t m_selected_preset_item{ 0 };
|
||||
|
||||
void set_type();
|
||||
|
||||
int m_em_unit;
|
||||
|
@ -320,7 +320,6 @@ public:
|
|||
|
||||
DynamicPrintConfig* get_config() { return m_config; }
|
||||
PresetCollection* get_presets() { return m_presets; }
|
||||
size_t get_selected_preset_item() { return m_selected_preset_item; }
|
||||
|
||||
void on_value_change(const std::string& opt_key, const boost::any& value);
|
||||
|
||||
|
|
|
@ -300,94 +300,6 @@ void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt)
|
|||
}
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
// *** PresetBitmapComboBox ***
|
||||
|
||||
/* For PresetBitmapComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina
|
||||
* (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean
|
||||
* "please scale this to such and such" but rather
|
||||
* "the wxImage is already sized for backing scale such and such". )
|
||||
* Unfortunately, the constructor changes the size of wxBitmap too.
|
||||
* Thus We need to use unscaled size value for bitmaps that we use
|
||||
* to avoid scaled size of control items.
|
||||
* For this purpose control drawing methods and
|
||||
* control size calculation methods (virtual) are overridden.
|
||||
**/
|
||||
|
||||
PresetBitmapComboBox::PresetBitmapComboBox(wxWindow* parent, const wxSize& size) :
|
||||
wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, size, 0, nullptr, wxCB_READONLY)
|
||||
{}
|
||||
|
||||
#ifdef __APPLE__
|
||||
bool PresetBitmapComboBox::OnAddBitmap(const wxBitmap& bitmap)
|
||||
{
|
||||
if (bitmap.IsOk())
|
||||
{
|
||||
// we should use scaled! size values of bitmap
|
||||
int width = (int)bitmap.GetScaledWidth();
|
||||
int height = (int)bitmap.GetScaledHeight();
|
||||
|
||||
if (m_usedImgSize.x < 0)
|
||||
{
|
||||
// If size not yet determined, get it from this image.
|
||||
m_usedImgSize.x = width;
|
||||
m_usedImgSize.y = height;
|
||||
|
||||
// Adjust control size to vertically fit the bitmap
|
||||
wxWindow* ctrl = GetControl();
|
||||
ctrl->InvalidateBestSize();
|
||||
wxSize newSz = ctrl->GetBestSize();
|
||||
wxSize sz = ctrl->GetSize();
|
||||
if (newSz.y > sz.y)
|
||||
ctrl->SetSize(sz.x, newSz.y);
|
||||
else
|
||||
DetermineIndent();
|
||||
}
|
||||
|
||||
wxCHECK_MSG(width == m_usedImgSize.x && height == m_usedImgSize.y,
|
||||
false,
|
||||
"you can only add images of same size");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PresetBitmapComboBox::OnDrawItem(wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int item,
|
||||
int flags) const
|
||||
{
|
||||
const wxBitmap& bmp = *(wxBitmap*)m_bitmaps[item];
|
||||
if (bmp.IsOk())
|
||||
{
|
||||
// we should use scaled! size values of bitmap
|
||||
wxCoord w = bmp.GetScaledWidth();
|
||||
wxCoord h = bmp.GetScaledHeight();
|
||||
|
||||
const int imgSpacingLeft = 4;
|
||||
|
||||
// Draw the image centered
|
||||
dc.DrawBitmap(bmp,
|
||||
rect.x + (m_usedImgSize.x - w) / 2 + imgSpacingLeft,
|
||||
rect.y + (rect.height - h) / 2,
|
||||
true);
|
||||
}
|
||||
|
||||
wxString text = GetString(item);
|
||||
if (!text.empty())
|
||||
dc.DrawText(text,
|
||||
rect.x + m_imgAreaWidth + 1,
|
||||
rect.y + (rect.height - dc.GetCharHeight()) / 2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *** wxDataViewTreeCtrlComboPopup ***
|
||||
|
||||
const unsigned int wxDataViewTreeCtrlComboPopup::DefaultWidth = 270;
|
||||
|
|
|
@ -95,37 +95,6 @@ public:
|
|||
void OnListBoxSelection(wxCommandEvent& evt);
|
||||
};
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
// *** PresetBitmapComboBox ***
|
||||
|
||||
// BitmapComboBox used to presets list on Sidebar and Tabs
|
||||
class PresetBitmapComboBox: public wxBitmapComboBox
|
||||
{
|
||||
public:
|
||||
PresetBitmapComboBox(wxWindow* parent, const wxSize& size = wxDefaultSize);
|
||||
~PresetBitmapComboBox() {}
|
||||
|
||||
#ifdef __APPLE__
|
||||
protected:
|
||||
/* For PresetBitmapComboBox we use bitmaps that are created from images that are already scaled appropriately for Retina
|
||||
* (Contrary to the intuition, the `scale` argument for Bitmap's constructor doesn't mean
|
||||
* "please scale this to such and such" but rather
|
||||
* "the wxImage is already sized for backing scale such and such". )
|
||||
* Unfortunately, the constructor changes the size of wxBitmap too.
|
||||
* Thus We need to use unscaled size value for bitmaps that we use
|
||||
* to avoid scaled size of control items.
|
||||
* For this purpose control drawing methods and
|
||||
* control size calculation methods (virtual) are overridden.
|
||||
**/
|
||||
virtual bool OnAddBitmap(const wxBitmap& bitmap) override;
|
||||
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, int item, int flags) const override;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *** wxDataViewTreeCtrlComboBox ***
|
||||
|
||||
|
|
Loading…
Reference in a new issue