ConfigWizard refactoring
This commit is contained in:
parent
f0cee79170
commit
b0f54e5709
Binary file not shown.
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 55 KiB |
@ -5,6 +5,7 @@
|
||||
#include <unordered_map>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <wx/settings.h>
|
||||
#include <wx/stattext.h>
|
||||
@ -13,6 +14,10 @@
|
||||
#include <wx/statbmp.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/display.h>
|
||||
#include <wx/debug.h>
|
||||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "PresetBundle.hpp"
|
||||
@ -33,12 +38,12 @@ struct PrinterPickerEvent : public wxEvent
|
||||
std::string variant_name;
|
||||
bool enable;
|
||||
|
||||
PrinterPickerEvent(wxEventType eventType, int winid, std::string vendor_id, std::string model_id, std::string variant_name, bool enable) :
|
||||
wxEvent(winid, eventType),
|
||||
vendor_id(std::move(vendor_id)),
|
||||
model_id(std::move(model_id)),
|
||||
variant_name(std::move(variant_name)),
|
||||
enable(enable)
|
||||
PrinterPickerEvent(wxEventType eventType, int winid, std::string vendor_id, std::string model_id, std::string variant_name, bool enable)
|
||||
: wxEvent(winid, eventType)
|
||||
, vendor_id(std::move(vendor_id))
|
||||
, model_id(std::move(model_id))
|
||||
, variant_name(std::move(variant_name))
|
||||
, enable(enable)
|
||||
{}
|
||||
|
||||
virtual wxEvent *Clone() const
|
||||
@ -49,21 +54,17 @@ struct PrinterPickerEvent : public wxEvent
|
||||
|
||||
wxDEFINE_EVENT(EVT_PRINTER_PICK, PrinterPickerEvent);
|
||||
|
||||
PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, const AppConfig &appconfig_vendors) :
|
||||
wxPanel(parent),
|
||||
vendor_id(vendor.id),
|
||||
variants_checked(0)
|
||||
PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors, const ModelFilter &filter)
|
||||
: wxPanel(parent)
|
||||
, vendor_id(vendor.id)
|
||||
{
|
||||
const auto &models = vendor.models;
|
||||
|
||||
auto *sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto *printer_grid = new wxFlexGridSizer(models.size(), 0, 20);
|
||||
printer_grid->SetFlexibleDirection(wxVERTICAL | wxHORIZONTAL);
|
||||
sizer->Add(printer_grid);
|
||||
|
||||
auto namefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
namefont.SetWeight(wxFONTWEIGHT_BOLD);
|
||||
const auto font_title = GetFont().MakeBold().Scaled(1.3);
|
||||
const auto font_name = GetFont().MakeBold();
|
||||
const auto font_alt_nozzle = GetFont().Scaled(0.9);
|
||||
|
||||
// wxGrid appends widgets by rows, but we need to construct them in columns.
|
||||
// These vectors are used to hold the elements so that they can be appended in the right order.
|
||||
@ -72,10 +73,12 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, cons
|
||||
std::vector<wxPanel*> variants_panels;
|
||||
|
||||
for (const auto &model : models) {
|
||||
if (! filter(model)) { continue; }
|
||||
|
||||
wxBitmap bitmap(GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str())), wxBITMAP_TYPE_PNG);
|
||||
|
||||
auto *title = new wxStaticText(this, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
title->SetFont(namefont);
|
||||
title->SetFont(font_name);
|
||||
title->Wrap(std::max((int)MODEL_MIN_WRAP, bitmap.GetWidth()));
|
||||
titles.push_back(title);
|
||||
|
||||
@ -87,45 +90,105 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, cons
|
||||
variants_panel->SetSizer(variants_sizer);
|
||||
const auto model_id = model.id;
|
||||
|
||||
bool default_variant = true; // Mark the first variant as default in the GUI
|
||||
for (const auto &variant : model.variants) {
|
||||
const auto label = wxString::Format("%s %s %s %s", variant.name, _(L("mm")), _(L("nozzle")),
|
||||
(default_variant ? "(" + _(L("default")) + ")" : wxString()));
|
||||
default_variant = false;
|
||||
for (size_t i = 0; i < model.variants.size(); i++) {
|
||||
const auto &variant = model.variants[i];
|
||||
|
||||
const auto label = model.technology == ptFFF
|
||||
? wxString::Format("%s %s %s", variant.name, _(L("mm")), _(L("nozzle")))
|
||||
: from_u8(model.name);
|
||||
|
||||
if (i == 1) {
|
||||
auto *alt_label = new wxStaticText(variants_panel, wxID_ANY, _(L("Alternate nozzles:")));
|
||||
alt_label->SetFont(font_alt_nozzle);
|
||||
variants_sizer->Add(alt_label, 0, wxBOTTOM, 3);
|
||||
}
|
||||
|
||||
auto *cbox = new Checkbox(variants_panel, label, model_id, variant.name);
|
||||
const size_t idx = cboxes.size();
|
||||
cboxes.push_back(cbox);
|
||||
i == 0 ? cboxes.push_back(cbox) : cboxes_alt.push_back(cbox);
|
||||
|
||||
bool enabled = appconfig_vendors.get_variant("PrusaResearch", model_id, variant.name);
|
||||
variants_checked += enabled;
|
||||
cbox->SetValue(enabled);
|
||||
|
||||
variants_sizer->Add(cbox, 0, wxBOTTOM, 3);
|
||||
cbox->Bind(wxEVT_CHECKBOX, [this, idx](wxCommandEvent &event) {
|
||||
if (idx >= this->cboxes.size()) { return; }
|
||||
this->on_checkbox(this->cboxes[idx], event.IsChecked());
|
||||
|
||||
cbox->Bind(wxEVT_CHECKBOX, [this, cbox](wxCommandEvent &event) {
|
||||
on_checkbox(cbox, event.IsChecked());
|
||||
});
|
||||
}
|
||||
|
||||
variants_panels.push_back(variants_panel);
|
||||
}
|
||||
|
||||
for (auto title : titles) { printer_grid->Add(title, 0, wxBOTTOM, 3); }
|
||||
for (auto bitmap : bitmaps) { printer_grid->Add(bitmap, 0, wxBOTTOM, 20); }
|
||||
for (auto vp : variants_panels) { printer_grid->Add(vp); }
|
||||
const size_t cols = std::min(max_cols, titles.size());
|
||||
|
||||
auto *all_none_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto *sel_all = new wxButton(this, wxID_ANY, _(L("Select all")));
|
||||
auto *sel_none = new wxButton(this, wxID_ANY, _(L("Select none")));
|
||||
auto *printer_grid = new wxFlexGridSizer(cols, 0, 20);
|
||||
printer_grid->SetFlexibleDirection(wxVERTICAL | wxHORIZONTAL);
|
||||
|
||||
if (titles.size() > 0) {
|
||||
const size_t odd_items = titles.size() % cols;
|
||||
|
||||
for (size_t i = 0; i < titles.size() - odd_items; i += cols) {
|
||||
for (size_t j = i; j < i + cols; j++) { printer_grid->Add(titles[j], 0, wxBOTTOM, 3); }
|
||||
for (size_t j = i; j < i + cols; j++) { printer_grid->Add(bitmaps[j], 0, wxBOTTOM, 20); }
|
||||
for (size_t j = i; j < i + cols; j++) { printer_grid->Add(variants_panels[j]); }
|
||||
|
||||
// Add separator space
|
||||
if (i > 0) {
|
||||
for (size_t j = i; j < i + cols; j++) { printer_grid->Add(1, 100); }
|
||||
}
|
||||
}
|
||||
|
||||
if (odd_items > 0) {
|
||||
for (size_t i = 0; i < cols; i++) { printer_grid->Add(1, 100); }
|
||||
|
||||
const size_t rem = titles.size() - odd_items;
|
||||
|
||||
for (size_t i = rem; i < titles.size(); i++) { printer_grid->Add(titles[i], 0, wxBOTTOM, 3); }
|
||||
for (size_t i = 0; i < cols - odd_items; i++) { printer_grid->AddSpacer(1); }
|
||||
for (size_t i = rem; i < titles.size(); i++) { printer_grid->Add(bitmaps[i], 0, wxBOTTOM, 20); }
|
||||
for (size_t i = 0; i < cols - odd_items; i++) { printer_grid->AddSpacer(1); }
|
||||
for (size_t i = rem; i < titles.size(); i++) { printer_grid->Add(variants_panels[i]); }
|
||||
}
|
||||
}
|
||||
|
||||
auto *title_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto *title_widget = new wxStaticText(this, wxID_ANY, title);
|
||||
title_widget->SetFont(font_title);
|
||||
title_sizer->Add(title_widget);
|
||||
title_sizer->AddStretchSpacer();
|
||||
|
||||
if (titles.size() > 1) {
|
||||
// It only makes sense to add the All / None buttons if there's multiple printers
|
||||
|
||||
auto *sel_all = new wxButton(this, wxID_ANY, _(L("All")));
|
||||
auto *sel_none = new wxButton(this, wxID_ANY, _(L("None")));
|
||||
sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true); });
|
||||
sel_none->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(false); });
|
||||
all_none_sizer->AddStretchSpacer();
|
||||
all_none_sizer->Add(sel_all);
|
||||
all_none_sizer->Add(sel_none);
|
||||
sizer->AddStretchSpacer();
|
||||
sizer->Add(all_none_sizer, 0, wxEXPAND);
|
||||
title_sizer->Add(sel_all, 0, wxRIGHT, BTN_SPACING);
|
||||
title_sizer->Add(sel_none);
|
||||
}
|
||||
|
||||
sizer->Add(title_sizer, 0, wxEXPAND | wxBOTTOM, BTN_SPACING);
|
||||
sizer->Add(printer_grid);
|
||||
|
||||
// auto *all_none_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
// auto *sel_all = new wxButton(this, wxID_ANY, _(L("Select all")));
|
||||
// auto *sel_none = new wxButton(this, wxID_ANY, _(L("Select none")));
|
||||
// sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true); });
|
||||
// sel_none->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(false); });
|
||||
// all_none_sizer->AddStretchSpacer();
|
||||
// all_none_sizer->Add(sel_all);
|
||||
// all_none_sizer->Add(sel_none);
|
||||
// sizer->AddStretchSpacer();
|
||||
// sizer->Add(all_none_sizer, 0, wxEXPAND);
|
||||
|
||||
SetSizer(sizer);
|
||||
}
|
||||
|
||||
PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors)
|
||||
: PrinterPicker(parent, vendor, std::move(title), max_cols, appconfig_vendors, [](const VendorProfile::PrinterModel&) { return true; })
|
||||
{}
|
||||
|
||||
void PrinterPicker::select_all(bool select)
|
||||
{
|
||||
for (const auto &cb : cboxes) {
|
||||
@ -134,6 +197,16 @@ void PrinterPicker::select_all(bool select)
|
||||
on_checkbox(cb, select);
|
||||
}
|
||||
}
|
||||
|
||||
// Alt nozzles are de-selected if this is an all-deselect, left intact otherwise
|
||||
if (! select) {
|
||||
for (const auto &cb : cboxes_alt) {
|
||||
if (cb->GetValue()) {
|
||||
cb->SetValue(false);
|
||||
on_checkbox(cb, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrinterPicker::select_one(size_t i, bool select)
|
||||
@ -146,7 +219,6 @@ void PrinterPicker::select_one(size_t i, bool select)
|
||||
|
||||
void PrinterPicker::on_checkbox(const Checkbox *cbox, bool checked)
|
||||
{
|
||||
variants_checked += checked ? 1 : -1;
|
||||
PrinterPickerEvent evt(EVT_PRINTER_PICK, GetId(), vendor_id, cbox->model, cbox->variant, checked);
|
||||
AddPendingEvent(evt);
|
||||
}
|
||||
@ -154,19 +226,16 @@ void PrinterPicker::on_checkbox(const Checkbox *cbox, bool checked)
|
||||
|
||||
// Wizard page base
|
||||
|
||||
ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname) :
|
||||
wxPanel(parent->p->hscroll),
|
||||
parent(parent),
|
||||
shortname(std::move(shortname)),
|
||||
p_prev(nullptr),
|
||||
p_next(nullptr)
|
||||
ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname, unsigned indent)
|
||||
: wxPanel(parent->p->hscroll)
|
||||
, parent(parent)
|
||||
, shortname(std::move(shortname))
|
||||
, indent(indent)
|
||||
{
|
||||
auto *sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto *text = new wxStaticText(this, wxID_ANY, std::move(title), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
auto font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
font.SetWeight(wxFONTWEIGHT_BOLD);
|
||||
font.SetPointSize(14);
|
||||
const auto font = GetFont().MakeBold().Scaled(1.5);
|
||||
text->SetFont(font);
|
||||
sizer->Add(text, 0, wxALIGN_LEFT, 0);
|
||||
sizer->AddSpacer(10);
|
||||
@ -186,18 +255,6 @@ ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxStrin
|
||||
|
||||
ConfigWizardPage::~ConfigWizardPage() {}
|
||||
|
||||
ConfigWizardPage* ConfigWizardPage::chain(ConfigWizardPage *page)
|
||||
{
|
||||
if (p_next != nullptr) { p_next->p_prev = nullptr; }
|
||||
p_next = page;
|
||||
if (page != nullptr) {
|
||||
if (page->p_prev != nullptr) { page->p_prev->p_next = nullptr; }
|
||||
page->p_prev = this;
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
void ConfigWizardPage::append_text(wxString text)
|
||||
{
|
||||
auto *widget = new wxStaticText(this, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
@ -217,16 +274,12 @@ bool ConfigWizardPage::Show(bool show)
|
||||
return wxPanel::Show(show);
|
||||
}
|
||||
|
||||
void ConfigWizardPage::enable_next(bool enable) { parent->p->enable_next(enable); }
|
||||
|
||||
|
||||
// Wizard pages
|
||||
|
||||
PageWelcome::PageWelcome(ConfigWizard *parent, bool check_first_variant) :
|
||||
ConfigWizardPage(parent, wxString::Format(_(L("Welcome to the Slic3r %s")), ConfigWizard::name()), _(L("Welcome"))),
|
||||
printer_picker(nullptr),
|
||||
others_buttons(new wxPanel(parent)),
|
||||
cbox_reset(nullptr)
|
||||
PageWelcome::PageWelcome(ConfigWizard *parent)
|
||||
: ConfigWizardPage(parent, wxString::Format(_(L("Welcome to the Slic3r %s")), ConfigWizard::name()), _(L("Welcome")))
|
||||
, cbox_reset(nullptr)
|
||||
{
|
||||
if (wizard_p()->run_reason == ConfigWizard::RR_DATA_EMPTY) {
|
||||
wxString::Format(_(L("Run %s")), ConfigWizard::name());
|
||||
@ -239,56 +292,81 @@ PageWelcome::PageWelcome(ConfigWizard *parent, bool check_first_variant) :
|
||||
append(cbox_reset);
|
||||
}
|
||||
|
||||
const auto &vendors = wizard_p()->vendors;
|
||||
const auto vendor_prusa = vendors.find("PrusaResearch");
|
||||
Show();
|
||||
}
|
||||
|
||||
|
||||
PagePrinters::PagePrinters(ConfigWizard *parent, wxString title, wxString shortname, const VendorProfile &vendor, unsigned indent, Technology technology)
|
||||
: ConfigWizardPage(parent, std::move(title), std::move(shortname), indent)
|
||||
{
|
||||
enum {
|
||||
COL_SIZE = 200,
|
||||
};
|
||||
|
||||
bool check_first_variant = wizard_p()->check_first_variant();
|
||||
|
||||
if (vendor_prusa != vendors.cend()) {
|
||||
AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors;
|
||||
|
||||
printer_picker = new PrinterPicker(this, vendor_prusa->second, appconfig_vendors);
|
||||
const auto families = vendor.families();
|
||||
for (const auto &family : families) {
|
||||
const auto filter = [&](const VendorProfile::PrinterModel &model) {
|
||||
return (model.technology == ptFFF && technology & T_FFF
|
||||
|| model.technology == ptSLA && technology & T_SLA)
|
||||
&& model.family == family;
|
||||
};
|
||||
|
||||
if (std::find_if(vendor.models.begin(), vendor.models.end(), filter) == vendor.models.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto picker_title = family.empty() ? wxString() : wxString::Format(_(L("%s Family")), family);
|
||||
auto *picker = new PrinterPicker(this, vendor, picker_title, MAX_COLS, appconfig_vendors, filter);
|
||||
|
||||
if (check_first_variant) {
|
||||
// Select the default (first) model/variant on the Prusa vendor
|
||||
printer_picker->select_one(0, true);
|
||||
picker->select_one(0, true);
|
||||
check_first_variant = false;
|
||||
}
|
||||
printer_picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) {
|
||||
|
||||
picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) {
|
||||
appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable);
|
||||
this->on_variant_checked();
|
||||
});
|
||||
|
||||
append(printer_picker);
|
||||
append(new wxStaticLine(this));
|
||||
|
||||
append(picker);
|
||||
printer_pickers.push_back(picker);
|
||||
}
|
||||
|
||||
const size_t num_other_vendors = vendors.size() - (vendor_prusa != vendors.cend());
|
||||
auto *sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto *other_vendors = new wxButton(others_buttons, wxID_ANY, _(L("Other vendors")));
|
||||
other_vendors->Enable(num_other_vendors > 0);
|
||||
auto *custom_setup = new wxButton(others_buttons, wxID_ANY, _(L("Custom setup")));
|
||||
|
||||
sizer->Add(other_vendors);
|
||||
sizer->AddSpacer(BTN_SPACING);
|
||||
sizer->Add(custom_setup);
|
||||
|
||||
other_vendors->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->wizard_p()->on_other_vendors(); });
|
||||
custom_setup->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->wizard_p()->on_custom_setup(); });
|
||||
|
||||
others_buttons->SetSizer(sizer);
|
||||
}
|
||||
|
||||
void PageWelcome::on_page_set()
|
||||
void PagePrinters::select_all(bool select)
|
||||
{
|
||||
chain(wizard_p()->page_update);
|
||||
on_variant_checked();
|
||||
for (auto picker : printer_pickers) {
|
||||
picker->select_all(select);
|
||||
}
|
||||
}
|
||||
|
||||
void PageWelcome::on_variant_checked()
|
||||
|
||||
PageCustom::PageCustom(ConfigWizard *parent)
|
||||
: ConfigWizardPage(parent, _(L("Custom Printer Setup")), _(L("Custom Printer")))
|
||||
{
|
||||
enable_next(printer_picker != nullptr ? printer_picker->variants_checked > 0 : false);
|
||||
cb_custom = new wxCheckBox(this, wxID_ANY, _(L("Define a custom printer profile")));
|
||||
tc_profile_name = new wxTextCtrl(this, wxID_ANY, "My Settings");
|
||||
auto *label = new wxStaticText(this, wxID_ANY, _(L("Custom profile name:")));
|
||||
|
||||
cb_custom->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) {
|
||||
wizard_p()->on_custom_setup(custom_wanted());
|
||||
});
|
||||
|
||||
append(cb_custom);
|
||||
append(label);
|
||||
append(tc_profile_name);
|
||||
}
|
||||
|
||||
PageUpdate::PageUpdate(ConfigWizard *parent) :
|
||||
ConfigWizardPage(parent, _(L("Automatic updates")), _(L("Updates"))),
|
||||
version_check(true),
|
||||
preset_update(true)
|
||||
PageUpdate::PageUpdate(ConfigWizard *parent)
|
||||
: ConfigWizardPage(parent, _(L("Automatic updates")), _(L("Updates")))
|
||||
, version_check(true)
|
||||
, preset_update(true)
|
||||
{
|
||||
const AppConfig *app_config = GUI::get_app_config();
|
||||
auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
@ -316,8 +394,8 @@ PageUpdate::PageUpdate(ConfigWizard *parent) :
|
||||
box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); });
|
||||
}
|
||||
|
||||
PageVendors::PageVendors(ConfigWizard *parent) :
|
||||
ConfigWizardPage(parent, _(L("Other Vendors")), _(L("Other Vendors")))
|
||||
PageVendors::PageVendors(ConfigWizard *parent)
|
||||
: ConfigWizardPage(parent, _(L("Other Vendors")), _(L("Other Vendors")))
|
||||
{
|
||||
append_text(_(L("Pick another vendor supported by Slic3r PE:")));
|
||||
|
||||
@ -331,14 +409,13 @@ PageVendors::PageVendors(ConfigWizard *parent) :
|
||||
const auto &vendor = vendor_pair.second;
|
||||
if (vendor.id == "PrusaResearch") { continue; }
|
||||
|
||||
auto *picker = new PrinterPicker(this, vendor, appconfig_vendors);
|
||||
auto *picker = new PrinterPicker(this, vendor, "", MAX_COLS, appconfig_vendors);
|
||||
picker->Hide();
|
||||
pickers.push_back(picker);
|
||||
choices_vendors.Add(vendor.name);
|
||||
|
||||
picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) {
|
||||
appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable);
|
||||
this->on_variant_checked();
|
||||
});
|
||||
}
|
||||
|
||||
@ -356,31 +433,19 @@ PageVendors::PageVendors(ConfigWizard *parent) :
|
||||
for (PrinterPicker *picker : pickers) { this->append(picker); }
|
||||
}
|
||||
|
||||
void PageVendors::on_page_set()
|
||||
{
|
||||
on_variant_checked();
|
||||
}
|
||||
|
||||
void PageVendors::on_vendor_pick(size_t i)
|
||||
{
|
||||
for (PrinterPicker *picker : pickers) { picker->Hide(); }
|
||||
if (i < pickers.size()) {
|
||||
pickers[i]->Show();
|
||||
wizard_p()->layout_fit();
|
||||
parent->Layout();
|
||||
}
|
||||
}
|
||||
|
||||
void PageVendors::on_variant_checked()
|
||||
{
|
||||
size_t variants_checked = 0;
|
||||
for (const PrinterPicker *picker : pickers) { variants_checked += picker->variants_checked; }
|
||||
enable_next(variants_checked > 0);
|
||||
}
|
||||
|
||||
PageFirmware::PageFirmware(ConfigWizard *parent) :
|
||||
ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware"))),
|
||||
gcode_opt(*print_config_def.get("gcode_flavor")),
|
||||
gcode_picker(nullptr)
|
||||
PageFirmware::PageFirmware(ConfigWizard *parent)
|
||||
: ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware")), 1)
|
||||
, gcode_opt(*print_config_def.get("gcode_flavor"))
|
||||
, gcode_picker(nullptr)
|
||||
{
|
||||
append_text(_(L("Choose the type of firmware used by your printer.")));
|
||||
append_text(gcode_opt.tooltip);
|
||||
@ -409,15 +474,15 @@ PageFirmware::PageFirmware(ConfigWizard *parent) :
|
||||
void PageFirmware::apply_custom_config(DynamicPrintConfig &config)
|
||||
{
|
||||
auto sel = gcode_picker->GetSelection();
|
||||
if (sel >= 0 && sel < gcode_opt.enum_labels.size()) {
|
||||
if (sel >= 0 && (size_t)sel < gcode_opt.enum_labels.size()) {
|
||||
auto *opt = new ConfigOptionEnum<GCodeFlavor>(static_cast<GCodeFlavor>(sel));
|
||||
config.set_key_value("gcode_flavor", opt);
|
||||
}
|
||||
}
|
||||
|
||||
PageBedShape::PageBedShape(ConfigWizard *parent) :
|
||||
ConfigWizardPage(parent, _(L("Bed Shape and Size")), _(L("Bed Shape"))),
|
||||
shape_panel(new BedShapePanel(this))
|
||||
PageBedShape::PageBedShape(ConfigWizard *parent)
|
||||
: ConfigWizardPage(parent, _(L("Bed Shape and Size")), _(L("Bed Shape")), 1)
|
||||
, shape_panel(new BedShapePanel(this))
|
||||
{
|
||||
append_text(_(L("Set the shape of your printer's bed.")));
|
||||
|
||||
@ -432,10 +497,10 @@ void PageBedShape::apply_custom_config(DynamicPrintConfig &config)
|
||||
config.set_key_value("bed_shape", opt);
|
||||
}
|
||||
|
||||
PageDiameters::PageDiameters(ConfigWizard *parent) :
|
||||
ConfigWizardPage(parent, _(L("Filament and Nozzle Diameters")), _(L("Print Diameters"))),
|
||||
spin_nozzle(new wxSpinCtrlDouble(this, wxID_ANY)),
|
||||
spin_filam(new wxSpinCtrlDouble(this, wxID_ANY))
|
||||
PageDiameters::PageDiameters(ConfigWizard *parent)
|
||||
: ConfigWizardPage(parent, _(L("Filament and Nozzle Diameters")), _(L("Print Diameters")), 1)
|
||||
, spin_nozzle(new wxSpinCtrlDouble(this, wxID_ANY))
|
||||
, spin_filam(new wxSpinCtrlDouble(this, wxID_ANY))
|
||||
{
|
||||
spin_nozzle->SetDigits(2);
|
||||
spin_nozzle->SetIncrement(0.1);
|
||||
@ -483,10 +548,10 @@ void PageDiameters::apply_custom_config(DynamicPrintConfig &config)
|
||||
config.set_key_value("filament_diameter", opt_filam);
|
||||
}
|
||||
|
||||
PageTemperatures::PageTemperatures(ConfigWizard *parent) :
|
||||
ConfigWizardPage(parent, _(L("Extruder and Bed Temperatures")), _(L("Temperatures"))),
|
||||
spin_extr(new wxSpinCtrlDouble(this, wxID_ANY)),
|
||||
spin_bed(new wxSpinCtrlDouble(this, wxID_ANY))
|
||||
PageTemperatures::PageTemperatures(ConfigWizard *parent)
|
||||
: ConfigWizardPage(parent, _(L("Extruder and Bed Temperatures")), _(L("Temperatures")), 1)
|
||||
, spin_extr(new wxSpinCtrlDouble(this, wxID_ANY))
|
||||
, spin_bed(new wxSpinCtrlDouble(this, wxID_ANY))
|
||||
{
|
||||
spin_extr->SetIncrement(5.0);
|
||||
const auto &def_extr = *print_config_def.get("temperature");
|
||||
@ -542,17 +607,21 @@ void PageTemperatures::apply_custom_config(DynamicPrintConfig &config)
|
||||
|
||||
// Index
|
||||
|
||||
ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) :
|
||||
wxPanel(parent),
|
||||
bg(GUI::from_u8(Slic3r::var("Slic3r_192px_transparent.png")), wxBITMAP_TYPE_PNG),
|
||||
bullet_black(GUI::from_u8(Slic3r::var("bullet_black.png")), wxBITMAP_TYPE_PNG),
|
||||
bullet_blue(GUI::from_u8(Slic3r::var("bullet_blue.png")), wxBITMAP_TYPE_PNG),
|
||||
bullet_white(GUI::from_u8(Slic3r::var("bullet_white.png")), wxBITMAP_TYPE_PNG)
|
||||
ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent)
|
||||
: wxPanel(parent)
|
||||
, bg(GUI::from_u8(Slic3r::var("Slic3r_192px_transparent.png")), wxBITMAP_TYPE_PNG)
|
||||
, bullet_black(GUI::from_u8(Slic3r::var("bullet_black.png")), wxBITMAP_TYPE_PNG)
|
||||
, bullet_blue(GUI::from_u8(Slic3r::var("bullet_blue.png")), wxBITMAP_TYPE_PNG)
|
||||
, bullet_white(GUI::from_u8(Slic3r::var("bullet_white.png")), wxBITMAP_TYPE_PNG)
|
||||
, item_active(0)
|
||||
, item_hover(-1)
|
||||
, last_page((size_t)-1)
|
||||
{
|
||||
SetMinSize(bg.GetSize());
|
||||
|
||||
wxClientDC dc(this);
|
||||
text_height = dc.GetCharHeight();
|
||||
const wxSize size = GetTextExtent("m");
|
||||
em = size.x;
|
||||
em_h = size.y;
|
||||
|
||||
// Add logo bitmap.
|
||||
// This could be done in on_paint() along with the index labels, but I've found it tricky
|
||||
@ -566,33 +635,103 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) :
|
||||
SetSizer(sizer);
|
||||
|
||||
Bind(wxEVT_PAINT, &ConfigWizardIndex::on_paint, this);
|
||||
}
|
||||
Bind(wxEVT_MOTION, &ConfigWizardIndex::on_mouse_move, this);
|
||||
|
||||
void ConfigWizardIndex::load_items(ConfigWizardPage *firstpage)
|
||||
{
|
||||
items.clear();
|
||||
item_active = items.cend();
|
||||
|
||||
for (auto *page = firstpage; page != nullptr; page = page->page_next()) {
|
||||
items.emplace_back(page->shortname);
|
||||
Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &evt) {
|
||||
if (item_hover != -1) {
|
||||
item_hover = -1;
|
||||
Refresh();
|
||||
}
|
||||
evt.Skip();
|
||||
});
|
||||
|
||||
Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &evt) {
|
||||
if (item_hover >= 0) { go_to(item_hover); }
|
||||
});
|
||||
}
|
||||
|
||||
wxDECLARE_EVENT(EVT_INDEX_PAGE, wxCommandEvent);
|
||||
|
||||
void ConfigWizardIndex::add_page(ConfigWizardPage *page)
|
||||
{
|
||||
last_page = items.size();
|
||||
items.emplace_back(Item { page->shortname, page->indent, page });
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void ConfigWizardIndex::set_active(ConfigWizardPage *page)
|
||||
void ConfigWizardIndex::add_label(wxString label, unsigned indent)
|
||||
{
|
||||
item_active = std::find(items.cbegin(), items.cend(), page->shortname);
|
||||
items.emplace_back(Item { std::move(label), indent, nullptr });
|
||||
Refresh();
|
||||
}
|
||||
|
||||
ConfigWizardPage* ConfigWizardIndex::active_page() const
|
||||
{
|
||||
if (item_active >= items.size()) { return nullptr; }
|
||||
|
||||
return items[item_active].page;
|
||||
}
|
||||
|
||||
void ConfigWizardIndex::go_prev()
|
||||
{
|
||||
// Search for a preceiding item that is a page (not a label, ie. page != nullptr)
|
||||
|
||||
for (size_t i = item_active; i > 0; i--) {
|
||||
if (items[i - 1].page != nullptr) {
|
||||
go_to(i - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWizardIndex::go_next()
|
||||
{
|
||||
// Search for a next item that is a page (not a label, ie. page != nullptr)
|
||||
|
||||
for (size_t i = item_active + 1; i < items.size(); i++) {
|
||||
if (items[i].page != nullptr) {
|
||||
go_to(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWizardIndex::go_to(size_t i)
|
||||
{
|
||||
if (i < items.size() && items[i].page != nullptr) {
|
||||
auto *former_active = active_page();
|
||||
if (former_active != nullptr) { former_active->Hide(); }
|
||||
|
||||
item_active = i;
|
||||
items[i].page->Show();
|
||||
|
||||
wxCommandEvent evt(EVT_INDEX_PAGE, GetId());
|
||||
AddPendingEvent(evt);
|
||||
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWizardIndex::go_to(ConfigWizardPage *page)
|
||||
{
|
||||
if (page == nullptr) { return; }
|
||||
|
||||
for (size_t i = 0; i < items.size(); i++) {
|
||||
if (items[i].page == page) { go_to(i); }
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWizardIndex::clear()
|
||||
{
|
||||
auto *former_active = active_page();
|
||||
if (former_active != nullptr) { former_active->Hide(); }
|
||||
|
||||
items.clear();
|
||||
item_active = 0;
|
||||
}
|
||||
|
||||
void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
|
||||
{
|
||||
enum {
|
||||
MARGIN = 10,
|
||||
SPACING = 5,
|
||||
};
|
||||
|
||||
const auto size = GetClientSize();
|
||||
if (size.GetHeight() == 0 || size.GetWidth() == 0) { return; }
|
||||
|
||||
@ -600,20 +739,40 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
|
||||
|
||||
const auto bullet_w = bullet_black.GetSize().GetWidth();
|
||||
const auto bullet_h = bullet_black.GetSize().GetHeight();
|
||||
const int yoff_icon = bullet_h < text_height ? (text_height - bullet_h) / 2 : 0;
|
||||
const int yoff_text = bullet_h > text_height ? (bullet_h - text_height) / 2 : 0;
|
||||
const int yinc = std::max(bullet_h, text_height) + SPACING;
|
||||
const int yoff_icon = bullet_h < em_h ? (em_h - bullet_h) / 2 : 0;
|
||||
const int yoff_text = bullet_h > em_h ? (bullet_h - em_h) / 2 : 0;
|
||||
const int yinc = item_height();
|
||||
|
||||
unsigned y = 0;
|
||||
for (auto it = items.cbegin(); it != items.cend(); ++it) {
|
||||
if (it < item_active) { dc.DrawBitmap(bullet_black, MARGIN, y + yoff_icon, false); }
|
||||
if (it == item_active) { dc.DrawBitmap(bullet_blue, MARGIN, y + yoff_icon, false); }
|
||||
if (it > item_active) { dc.DrawBitmap(bullet_white, MARGIN, y + yoff_icon, false); }
|
||||
dc.DrawText(*it, MARGIN + bullet_w + SPACING, y + yoff_text);
|
||||
for (size_t i = 0; i < items.size(); i++) {
|
||||
const Item& item = items[i];
|
||||
unsigned x = em/2 + item.indent * em;
|
||||
|
||||
if (i == item_active || item_hover >= 0 && i == (size_t)item_hover) {
|
||||
dc.DrawBitmap(bullet_blue, x, y + yoff_icon, false);
|
||||
}
|
||||
else if (i < item_active) { dc.DrawBitmap(bullet_black, x, y + yoff_icon, false); }
|
||||
else if (i > item_active) { dc.DrawBitmap(bullet_white, x, y + yoff_icon, false); }
|
||||
|
||||
dc.DrawText(item.label, x + bullet_w + em/2, y + yoff_text);
|
||||
y += yinc;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt)
|
||||
{
|
||||
const wxClientDC dc(this);
|
||||
const wxPoint pos = evt.GetLogicalPosition(dc);
|
||||
|
||||
const ssize_t item_hover_new = pos.y / item_height();
|
||||
|
||||
if (item_hover_new < items.size() && item_hover_new != item_hover) {
|
||||
item_hover = item_hover_new;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
|
||||
// priv
|
||||
@ -629,6 +788,36 @@ static const std::unordered_map<std::string, std::pair<std::string, std::string>
|
||||
{ "Original Prusa i3 MK3.ini", std::make_pair("MK3", "0.4") },
|
||||
}};
|
||||
|
||||
void ConfigWizard::priv::load_pages(bool custom_setup)
|
||||
{
|
||||
const auto former_active = index->active_item();
|
||||
|
||||
index->clear();
|
||||
|
||||
index->add_page(page_welcome);
|
||||
index->add_page(page_fff);
|
||||
index->add_page(page_msla);
|
||||
index->add_page(page_custom);
|
||||
|
||||
if (custom_setup) {
|
||||
index->add_page(page_firmware);
|
||||
index->add_page(page_bed);
|
||||
index->add_page(page_diams);
|
||||
index->add_page(page_temps);
|
||||
}
|
||||
|
||||
index->add_page(page_update);
|
||||
|
||||
index->go_to(former_active); // Will restore the active item/page if possible
|
||||
|
||||
q->Layout();
|
||||
}
|
||||
|
||||
bool ConfigWizard::priv::check_first_variant() const
|
||||
{
|
||||
return run_reason == RR_DATA_EMPTY || run_reason == RR_DATA_LEGACY;
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::load_vendors()
|
||||
{
|
||||
const auto vendor_dir = fs::path(Slic3r::data_dir()) / "vendor";
|
||||
@ -681,44 +870,9 @@ void ConfigWizard::priv::load_vendors()
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::index_refresh()
|
||||
{
|
||||
index->load_items(page_welcome);
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::add_page(ConfigWizardPage *page)
|
||||
{
|
||||
hscroll_sizer->Add(page, 0, wxEXPAND);
|
||||
|
||||
auto *extra_buttons = page->extra_buttons();
|
||||
if (extra_buttons != nullptr) {
|
||||
btnsizer->Prepend(extra_buttons, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::set_page(ConfigWizardPage *page)
|
||||
{
|
||||
if (page == nullptr) { return; }
|
||||
if (page_current != nullptr) { page_current->Hide(); }
|
||||
page_current = page;
|
||||
enable_next(true);
|
||||
|
||||
page->on_page_set();
|
||||
index->load_items(page_welcome);
|
||||
index->set_active(page);
|
||||
page->Show();
|
||||
|
||||
btn_prev->Enable(page->page_prev() != nullptr);
|
||||
btn_next->Show(page->page_next() != nullptr);
|
||||
btn_finish->Show(page->page_next() == nullptr);
|
||||
|
||||
layout_fit();
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::layout_fit()
|
||||
{
|
||||
q->Layout();
|
||||
q->Fit();
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::enable_next(bool enable)
|
||||
@ -727,26 +881,13 @@ void ConfigWizard::priv::enable_next(bool enable)
|
||||
btn_finish->Enable(enable);
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::on_other_vendors()
|
||||
void ConfigWizard::priv::on_custom_setup(bool custom_wanted)
|
||||
{
|
||||
page_welcome
|
||||
->chain(page_vendors)
|
||||
->chain(page_update);
|
||||
set_page(page_vendors);
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::on_custom_setup()
|
||||
{
|
||||
page_welcome->chain(page_firmware);
|
||||
page_temps->chain(page_update);
|
||||
set_page(page_firmware);
|
||||
load_pages(custom_wanted);
|
||||
}
|
||||
|
||||
void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater)
|
||||
{
|
||||
const bool is_custom_setup = page_welcome->page_next() == page_firmware;
|
||||
|
||||
if (! is_custom_setup) {
|
||||
const auto enabled_vendors = appconfig_vendors.vendors();
|
||||
|
||||
// Install bundles from resources if needed:
|
||||
@ -788,21 +929,27 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
|
||||
app_config->set("preset_update", page_update->preset_update ? "1" : "0");
|
||||
app_config->reset_selections();
|
||||
preset_bundle->load_presets(*app_config);
|
||||
} else {
|
||||
for (ConfigWizardPage *page = page_firmware; page != nullptr; page = page->page_next()) {
|
||||
page->apply_custom_config(*custom_config);
|
||||
}
|
||||
preset_bundle->load_config("My Settings", *custom_config);
|
||||
|
||||
|
||||
if (page_custom->custom_wanted()) {
|
||||
page_firmware->apply_custom_config(*custom_config);
|
||||
page_bed->apply_custom_config(*custom_config);
|
||||
page_diams->apply_custom_config(*custom_config);
|
||||
page_temps->apply_custom_config(*custom_config);
|
||||
|
||||
const std::string profile_name = page_custom->profile_name();
|
||||
preset_bundle->load_config(profile_name, *custom_config);
|
||||
}
|
||||
|
||||
// Update the selections from the compatibilty.
|
||||
preset_bundle->export_selections(*app_config);
|
||||
}
|
||||
|
||||
// Public
|
||||
|
||||
ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) :
|
||||
wxDialog(parent, wxID_ANY, _(name().ToStdString()), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
|
||||
p(new priv(this))
|
||||
ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason)
|
||||
: wxDialog(parent, wxID_ANY, _(name().ToStdString()), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
, p(new priv(this))
|
||||
{
|
||||
p->run_reason = reason;
|
||||
|
||||
@ -828,6 +975,9 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) :
|
||||
topsizer->AddSpacer(INDEX_MARGIN);
|
||||
topsizer->Add(p->hscroll, 1, wxEXPAND);
|
||||
|
||||
auto *btn_sel_all = new wxButton(this, wxID_ANY, _(L("Select all printers")));
|
||||
p->btnsizer->Add(btn_sel_all);
|
||||
|
||||
p->btn_prev = new wxButton(this, wxID_ANY, _(L("< &Back")));
|
||||
p->btn_next = new wxButton(this, wxID_ANY, _(L("&Next >")));
|
||||
p->btn_finish = new wxButton(this, wxID_APPLY, _(L("&Finish")));
|
||||
@ -838,45 +988,78 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) :
|
||||
p->btnsizer->Add(p->btn_finish, 0, wxLEFT, BTN_SPACING);
|
||||
p->btnsizer->Add(p->btn_cancel, 0, wxLEFT, BTN_SPACING);
|
||||
|
||||
p->add_page(p->page_welcome = new PageWelcome(this, reason == RR_DATA_EMPTY || reason == RR_DATA_LEGACY));
|
||||
const auto &vendors = p->vendors;
|
||||
const auto vendor_prusa_it = vendors.find("PrusaResearch");
|
||||
wxCHECK_RET(vendor_prusa_it != vendors.cend(), "Vendor PrusaResearch not found");
|
||||
const VendorProfile &vendor_prusa = vendor_prusa_it->second;
|
||||
|
||||
p->add_page(p->page_welcome = new PageWelcome(this));
|
||||
|
||||
p->page_fff = new PagePrinters(this, _(L("Prusa FFF Technology Printers")), "Prusa FFF", vendor_prusa, 0, PagePrinters::T_FFF);
|
||||
p->add_page(p->page_fff);
|
||||
|
||||
p->page_msla = new PagePrinters(this, _(L("Prusa MSLA Technology Printers")), "Prusa MSLA", vendor_prusa, 0, PagePrinters::T_SLA);
|
||||
p->add_page(p->page_msla);
|
||||
|
||||
p->add_page(p->page_custom = new PageCustom(this));
|
||||
p->add_page(p->page_update = new PageUpdate(this));
|
||||
p->add_page(p->page_vendors = new PageVendors(this));
|
||||
p->add_page(p->page_firmware = new PageFirmware(this));
|
||||
p->add_page(p->page_bed = new PageBedShape(this));
|
||||
p->add_page(p->page_diams = new PageDiameters(this));
|
||||
p->add_page(p->page_temps = new PageTemperatures(this));
|
||||
p->index_refresh();
|
||||
|
||||
p->page_welcome->chain(p->page_update);
|
||||
p->page_firmware
|
||||
->chain(p->page_bed)
|
||||
->chain(p->page_diams)
|
||||
->chain(p->page_temps);
|
||||
p->load_pages(false);
|
||||
|
||||
vsizer->Add(topsizer, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
|
||||
vsizer->Add(hline, 0, wxEXPAND);
|
||||
vsizer->Add(p->btnsizer, 0, wxEXPAND | wxALL, DIALOG_MARGIN);
|
||||
|
||||
p->set_page(p->page_welcome);
|
||||
SetSizer(vsizer);
|
||||
SetSizerAndFit(vsizer);
|
||||
|
||||
// We can now enable scrolling on hscroll
|
||||
p->hscroll->SetScrollRate(30, 30);
|
||||
// Compare current ("ideal") wizard size with the size of the current screen.
|
||||
// If the screen is smaller, resize wizrad to match, which will enable scrollbars.
|
||||
auto wizard_size = GetSize();
|
||||
unsigned width, height;
|
||||
if (GUI::get_current_screen_size(this, width, height)) {
|
||||
wizard_size.SetWidth(std::min(wizard_size.GetWidth(), (int)(width - 2 * DIALOG_MARGIN)));
|
||||
wizard_size.SetHeight(std::min(wizard_size.GetHeight(), (int)(height - 2 * DIALOG_MARGIN)));
|
||||
SetMinSize(wizard_size);
|
||||
}
|
||||
Fit();
|
||||
|
||||
p->btn_prev->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_prev(); });
|
||||
p->btn_next->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_next(); });
|
||||
p->btn_finish->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->EndModal(wxID_OK); });
|
||||
// XXX: set size right away on windows, create util function
|
||||
Bind(wxEVT_CREATE, [this](wxWindowCreateEvent &event) {
|
||||
CallAfter([this]() {
|
||||
// Clamp the Wizard size based on screen dimensions
|
||||
// Note: Using EVT_SHOW + CallAfter because any sooner than this
|
||||
// on some Linux boxes wxDisplay::GetFromWindow() returns 0 no matter what.
|
||||
|
||||
const auto idx = wxDisplay::GetFromWindow(this);
|
||||
wxDisplay display(idx != wxNOT_FOUND ? idx : 0u);
|
||||
|
||||
const auto disp_rect = display.GetClientArea();
|
||||
wxRect window_rect(
|
||||
disp_rect.x + disp_rect.width / 20,
|
||||
disp_rect.y + disp_rect.height / 20,
|
||||
9*disp_rect.width / 10,
|
||||
9*disp_rect.height / 10);
|
||||
|
||||
SetSize(window_rect);
|
||||
});
|
||||
});
|
||||
|
||||
p->btn_prev->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { this->p->index->go_prev(); });
|
||||
p->btn_next->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { this->p->index->go_next(); });
|
||||
p->btn_finish->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { this->EndModal(wxID_OK); });
|
||||
p->btn_finish->Hide();
|
||||
|
||||
btn_sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) {
|
||||
p->page_fff->select_all(true);
|
||||
p->page_msla->select_all(true);
|
||||
p->index->go_to(p->page_update);
|
||||
});
|
||||
|
||||
p->index->Bind(EVT_INDEX_PAGE, [this](const wxCommandEvent &) {
|
||||
const bool is_last = p->index->active_is_last();
|
||||
p->btn_next->Show(! is_last);
|
||||
p->btn_finish->Show(is_last);
|
||||
|
||||
Layout();
|
||||
});
|
||||
}
|
||||
|
||||
ConfigWizard::~ConfigWizard() {}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <wx/sizer.h>
|
||||
@ -13,6 +14,7 @@
|
||||
#include <wx/button.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "slic3r/Utils/PresetUpdater.hpp"
|
||||
@ -34,8 +36,13 @@ enum {
|
||||
BTN_SPACING = 10,
|
||||
INDENT_SPACING = 30,
|
||||
VERTICAL_SPACING = 10,
|
||||
|
||||
MAX_COLS = 4,
|
||||
ROW_SPACING = 75,
|
||||
};
|
||||
|
||||
typedef std::function<bool(const VendorProfile::PrinterModel&)> ModelFilter;
|
||||
|
||||
struct PrinterPicker: wxPanel
|
||||
{
|
||||
struct Checkbox : wxCheckBox
|
||||
@ -52,9 +59,10 @@ struct PrinterPicker: wxPanel
|
||||
|
||||
const std::string vendor_id;
|
||||
std::vector<Checkbox*> cboxes;
|
||||
unsigned variants_checked;
|
||||
std::vector<Checkbox*> cboxes_alt;
|
||||
|
||||
PrinterPicker(wxWindow *parent, const VendorProfile &vendor, const AppConfig &appconfig_vendors);
|
||||
PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors, const ModelFilter &filter);
|
||||
PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors);
|
||||
|
||||
void select_all(bool select);
|
||||
void select_one(size_t i, bool select);
|
||||
@ -66,15 +74,11 @@ struct ConfigWizardPage: wxPanel
|
||||
ConfigWizard *parent;
|
||||
const wxString shortname;
|
||||
wxBoxSizer *content;
|
||||
const unsigned indent;
|
||||
|
||||
ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname);
|
||||
|
||||
ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname, unsigned indent = 0);
|
||||
virtual ~ConfigWizardPage();
|
||||
|
||||
ConfigWizardPage* page_prev() const { return p_prev; }
|
||||
ConfigWizardPage* page_next() const { return p_next; }
|
||||
ConfigWizardPage* chain(ConfigWizardPage *page);
|
||||
|
||||
template<class T>
|
||||
void append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
|
||||
{
|
||||
@ -88,29 +92,46 @@ struct ConfigWizardPage: wxPanel
|
||||
|
||||
virtual bool Show(bool show = true);
|
||||
virtual bool Hide() { return Show(false); }
|
||||
virtual wxPanel* extra_buttons() { return nullptr; }
|
||||
virtual void on_page_set() {}
|
||||
virtual wxPanel* extra_buttons() { return nullptr; } // XXX
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config) {}
|
||||
|
||||
void enable_next(bool enable);
|
||||
private:
|
||||
ConfigWizardPage *p_prev;
|
||||
ConfigWizardPage *p_next;
|
||||
};
|
||||
|
||||
struct PageWelcome: ConfigWizardPage
|
||||
{
|
||||
PrinterPicker *printer_picker;
|
||||
wxPanel *others_buttons;
|
||||
wxCheckBox *cbox_reset;
|
||||
|
||||
PageWelcome(ConfigWizard *parent, bool check_first_variant);
|
||||
|
||||
virtual wxPanel* extra_buttons() { return others_buttons; }
|
||||
virtual void on_page_set();
|
||||
PageWelcome(ConfigWizard *parent);
|
||||
|
||||
bool reset_user_profile() const { return cbox_reset != nullptr ? cbox_reset->GetValue() : false; }
|
||||
void on_variant_checked();
|
||||
};
|
||||
|
||||
struct PagePrinters: ConfigWizardPage
|
||||
{
|
||||
enum Technology {
|
||||
// Bitflag equivalent of PrinterTechnology
|
||||
T_FFF = 0x1,
|
||||
T_SLA = 0x2,
|
||||
T_Any = ~0,
|
||||
};
|
||||
|
||||
std::vector<PrinterPicker *> printer_pickers;
|
||||
|
||||
PagePrinters(ConfigWizard *parent, wxString title, wxString shortname, const VendorProfile &vendor, unsigned indent, Technology technology);
|
||||
|
||||
void select_all(bool select);
|
||||
};
|
||||
|
||||
struct PageCustom: ConfigWizardPage
|
||||
{
|
||||
PageCustom(ConfigWizard *parent);
|
||||
|
||||
bool custom_wanted() const { return cb_custom->GetValue(); }
|
||||
std::string profile_name() const { return into_u8(tc_profile_name->GetValue()); }
|
||||
|
||||
private:
|
||||
wxCheckBox *cb_custom;
|
||||
wxTextCtrl *tc_profile_name;
|
||||
|
||||
};
|
||||
|
||||
struct PageUpdate: ConfigWizardPage
|
||||
@ -127,10 +148,7 @@ struct PageVendors: ConfigWizardPage
|
||||
|
||||
PageVendors(ConfigWizard *parent);
|
||||
|
||||
virtual void on_page_set();
|
||||
|
||||
void on_vendor_pick(size_t i);
|
||||
void on_variant_checked();
|
||||
};
|
||||
|
||||
struct PageFirmware: ConfigWizardPage
|
||||
@ -174,21 +192,62 @@ class ConfigWizardIndex: public wxPanel
|
||||
public:
|
||||
ConfigWizardIndex(wxWindow *parent);
|
||||
|
||||
void load_items(ConfigWizardPage *firstpage);
|
||||
void set_active(ConfigWizardPage *page);
|
||||
void add_page(ConfigWizardPage *page);
|
||||
void add_label(wxString label, unsigned indent = 0);
|
||||
|
||||
size_t active_item() const { return item_active; }
|
||||
ConfigWizardPage* active_page() const;
|
||||
bool active_is_last() const { return item_active < items.size() && item_active == last_page; }
|
||||
|
||||
void go_prev();
|
||||
void go_next();
|
||||
void go_to(size_t i);
|
||||
void go_to(ConfigWizardPage *page);
|
||||
|
||||
void clear();
|
||||
|
||||
// XXX
|
||||
// void load_items(ConfigWizardPage *firstpage);
|
||||
// void set_active(ConfigWizardPage *page);
|
||||
private:
|
||||
// enum {
|
||||
// // Units in em
|
||||
// MARGIN = 1,
|
||||
// SPACING = 1,
|
||||
// };
|
||||
|
||||
struct Item
|
||||
{
|
||||
wxString label;
|
||||
unsigned indent;
|
||||
ConfigWizardPage *page; // nullptr page => label-only item
|
||||
|
||||
// bool operator==(const wxString &label) const { return this->label == label; }
|
||||
bool operator==(ConfigWizardPage *page) const { return this->page == page; }
|
||||
};
|
||||
|
||||
int em;
|
||||
int em_h;
|
||||
|
||||
const wxBitmap bg;
|
||||
const wxBitmap bullet_black;
|
||||
const wxBitmap bullet_blue;
|
||||
const wxBitmap bullet_white;
|
||||
int text_height;
|
||||
|
||||
std::vector<wxString> items;
|
||||
std::vector<wxString>::const_iterator item_active;
|
||||
std::vector<Item> items;
|
||||
// std::vector<Item>::const_iterator item_active;
|
||||
size_t item_active;
|
||||
ssize_t item_hover;
|
||||
size_t last_page;
|
||||
|
||||
int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em) + em; }
|
||||
|
||||
void on_paint(wxPaintEvent &evt);
|
||||
void on_mouse_move(wxMouseEvent &evt);
|
||||
};
|
||||
|
||||
wxDEFINE_EVENT(EVT_INDEX_PAGE, wxCommandEvent);
|
||||
|
||||
struct ConfigWizard::priv
|
||||
{
|
||||
ConfigWizard *q;
|
||||
@ -209,8 +268,13 @@ struct ConfigWizard::priv
|
||||
wxButton *btn_cancel = nullptr;
|
||||
|
||||
PageWelcome *page_welcome = nullptr;
|
||||
PagePrinters *page_fff = nullptr;
|
||||
PagePrinters *page_msla = nullptr;
|
||||
PageCustom *page_custom = nullptr;
|
||||
PageUpdate *page_update = nullptr;
|
||||
PageVendors *page_vendors = nullptr;
|
||||
PageVendors *page_vendors = nullptr; // XXX: ?
|
||||
|
||||
// Custom setup pages
|
||||
PageFirmware *page_firmware = nullptr;
|
||||
PageBedShape *page_bed = nullptr;
|
||||
PageDiameters *page_diams = nullptr;
|
||||
@ -218,17 +282,14 @@ struct ConfigWizard::priv
|
||||
|
||||
priv(ConfigWizard *q) : q(q) {}
|
||||
|
||||
void load_pages(bool custom_setup);
|
||||
|
||||
bool check_first_variant() const;
|
||||
void load_vendors();
|
||||
void add_page(ConfigWizardPage *page);
|
||||
void index_refresh();
|
||||
void set_page(ConfigWizardPage *page);
|
||||
void layout_fit();
|
||||
void go_prev() { if (page_current != nullptr) { set_page(page_current->page_prev()); } }
|
||||
void go_next() { if (page_current != nullptr) { set_page(page_current->page_next()); } }
|
||||
void enable_next(bool enable);
|
||||
|
||||
void on_other_vendors();
|
||||
void on_custom_setup();
|
||||
void on_custom_setup(bool custom_wanted);
|
||||
|
||||
void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater);
|
||||
};
|
||||
|
@ -355,21 +355,6 @@ boost::filesystem::path into_path(const wxString &str)
|
||||
return boost::filesystem::path(str.wx_str());
|
||||
}
|
||||
|
||||
bool get_current_screen_size(wxWindow *window, unsigned &width, unsigned &height)
|
||||
{
|
||||
const auto idx = wxDisplay::GetFromWindow(window);
|
||||
if (idx == wxNOT_FOUND) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wxDisplay display(idx);
|
||||
const auto disp_size = display.GetClientArea();
|
||||
width = disp_size.GetWidth();
|
||||
height = disp_size.GetHeight();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void about()
|
||||
{
|
||||
AboutDialog dlg;
|
||||
|
@ -71,9 +71,6 @@ wxString from_path(const boost::filesystem::path &path);
|
||||
// boost path from wxString
|
||||
boost::filesystem::path into_path(const wxString &str);
|
||||
|
||||
// Returns the dimensions of the screen on which the main frame is displayed
|
||||
bool get_current_screen_size(wxWindow *window, unsigned &width, unsigned &height);
|
||||
|
||||
// Display an About dialog
|
||||
extern void about();
|
||||
// Ask the destop to open the datadir using the default file explorer.
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/bmpcbox.h>
|
||||
#include <wx/statbox.h>
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <Windows.h>
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <boost/format.hpp>
|
||||
@ -128,11 +129,14 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
|
||||
VendorProfile::PrinterModel model;
|
||||
model.id = section.first.substr(printer_model_key.size());
|
||||
model.name = section.second.get<std::string>("name", model.id);
|
||||
|
||||
auto technology_field = section.second.get<std::string>("technology", "FFF");
|
||||
if (! ConfigOptionEnum<PrinterTechnology>::from_string(technology_field, model.technology)) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Invalid printer technology field: `%2%`") % id % technology_field;
|
||||
model.technology = ptFFF;
|
||||
}
|
||||
|
||||
model.family = section.second.get<std::string>("family", model.id);
|
||||
#if 0
|
||||
// Remove SLA printers from the initial alpha.
|
||||
if (model.technology == ptSLA)
|
||||
@ -157,6 +161,20 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::string> VendorProfile::families() const
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
unsigned num_familiies = 0;
|
||||
|
||||
for (auto &model : models) {
|
||||
if (!model.family.empty() && std::find(res.begin(), res.end(), model.family) == res.end()) {
|
||||
res.push_back(model.family);
|
||||
num_familiies++;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Suffix to be added to a modified preset name in the combo box.
|
||||
static std::string g_suffix_modified = " (modified)";
|
||||
|
@ -54,13 +54,16 @@ public:
|
||||
std::string id;
|
||||
std::string name;
|
||||
PrinterTechnology technology;
|
||||
std::string family;
|
||||
std::vector<PrinterVariant> variants;
|
||||
|
||||
PrinterVariant* variant(const std::string &name) {
|
||||
for (auto &v : this->variants)
|
||||
if (v.name == name)
|
||||
return &v;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
|
||||
};
|
||||
std::vector<PrinterModel> models;
|
||||
@ -72,6 +75,7 @@ public:
|
||||
static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true);
|
||||
|
||||
size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
|
||||
std::vector<std::string> families() const;
|
||||
|
||||
bool operator< (const VendorProfile &rhs) const { return this->id < rhs.id; }
|
||||
bool operator==(const VendorProfile &rhs) const { return this->id == rhs.id; }
|
||||
|
Loading…
Reference in New Issue
Block a user