ConfigWizard: Basic structure / WIP
This commit is contained in:
parent
e37cbdfcfc
commit
3fcf194e39
@ -101,6 +101,8 @@ sub OnInit {
|
|||||||
$self->{app_config}->set('version', $Slic3r::VERSION);
|
$self->{app_config}->set('version', $Slic3r::VERSION);
|
||||||
$self->{app_config}->save;
|
$self->{app_config}->save;
|
||||||
|
|
||||||
|
my $slic3r_update_avail = $self->{app_config}->get("version_check") && $self->{app_config}->get("version_online") != $Slic3r::VERSION;
|
||||||
|
|
||||||
Slic3r::GUI::set_app_config($self->{app_config});
|
Slic3r::GUI::set_app_config($self->{app_config});
|
||||||
Slic3r::GUI::load_language();
|
Slic3r::GUI::load_language();
|
||||||
|
|
||||||
@ -111,6 +113,7 @@ sub OnInit {
|
|||||||
warn $@ . "\n";
|
warn $@ . "\n";
|
||||||
show_error(undef, $@);
|
show_error(undef, $@);
|
||||||
}
|
}
|
||||||
|
# TODO: check previously downloaded updates
|
||||||
$run_wizard = 1 if $self->{preset_bundle}->has_defauls_only;
|
$run_wizard = 1 if $self->{preset_bundle}->has_defauls_only;
|
||||||
|
|
||||||
Slic3r::GUI::set_preset_bundle($self->{preset_bundle});
|
Slic3r::GUI::set_preset_bundle($self->{preset_bundle});
|
||||||
@ -134,15 +137,20 @@ sub OnInit {
|
|||||||
$self->{app_config}->save if $self->{app_config}->dirty;
|
$self->{app_config}->save if $self->{app_config}->dirty;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($run_wizard) {
|
|
||||||
# On OSX the UI was not initialized correctly if the wizard was called
|
# On OSX the UI was not initialized correctly if the wizard was called
|
||||||
# before the UI was up and running.
|
# before the UI was up and running.
|
||||||
$self->CallAfter(sub {
|
$self->CallAfter(sub {
|
||||||
|
if ($slic3r_update_avail) {
|
||||||
|
# TODO
|
||||||
|
} elsif ($run_wizard) {
|
||||||
# Run the config wizard, don't offer the "reset user profile" checkbox.
|
# Run the config wizard, don't offer the "reset user profile" checkbox.
|
||||||
$self->{mainframe}->config_wizard(1);
|
$self->{mainframe}->config_wizard(1);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# XXX: recreate_GUI ???
|
||||||
|
Slic3r::PresetUpdater::download($self->{app_config}, $self->{preset_bundle});
|
||||||
|
});
|
||||||
|
|
||||||
# The following event is emited by the C++ menu implementation of application language change.
|
# The following event is emited by the C++ menu implementation of application language change.
|
||||||
EVT_COMMAND($self, -1, $LANGUAGE_CHANGE_EVENT, sub{
|
EVT_COMMAND($self, -1, $LANGUAGE_CHANGE_EVENT, sub{
|
||||||
$self->recreate_GUI;
|
$self->recreate_GUI;
|
||||||
|
@ -643,6 +643,12 @@ sub config_wizard {
|
|||||||
my ($self, $fresh_start) = @_;
|
my ($self, $fresh_start) = @_;
|
||||||
# Exit wizard if there are unsaved changes and the user cancels the action.
|
# Exit wizard if there are unsaved changes and the user cancels the action.
|
||||||
return unless $self->check_unsaved_changes;
|
return unless $self->check_unsaved_changes;
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Offer "reset user profile"
|
||||||
|
Slic3r::GUI::open_config_wizard();
|
||||||
|
return;
|
||||||
|
|
||||||
# Enumerate the profiles bundled with the Slic3r installation under resources/profiles.
|
# Enumerate the profiles bundled with the Slic3r installation under resources/profiles.
|
||||||
my $directory = Slic3r::resources_dir() . "/profiles";
|
my $directory = Slic3r::resources_dir() . "/profiles";
|
||||||
my @profiles = ();
|
my @profiles = ();
|
||||||
|
BIN
resources/icons/printers/MK2S.png
Normal file
BIN
resources/icons/printers/MK2S.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
BIN
resources/icons/printers/MK2SMM.png
Normal file
BIN
resources/icons/printers/MK2SMM.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
BIN
resources/icons/printers/MK3.png
Normal file
BIN
resources/icons/printers/MK3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
@ -7,21 +7,25 @@ name = Prusa Research
|
|||||||
# This means, the server may force the Slic3r configuration to be downgraded.
|
# This means, the server may force the Slic3r configuration to be downgraded.
|
||||||
config_version = 0.1
|
config_version = 0.1
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch.ini
|
# TODO: proper URL
|
||||||
|
# config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch.ini
|
||||||
|
config_update_url = https://gist.githubusercontent.com/vojtechkral/4d8fd4a3b8699a01ec892c264178461c/raw/e9187c3e15ceaf1a90f29b7c43cf3ccc746140f0/PrusaResearch.ini
|
||||||
|
|
||||||
# The printer models will be shown by the Configuration Wizard in this order,
|
# The printer models will be shown by the Configuration Wizard in this order,
|
||||||
# also the first model installed & the first nozzle installed will be activated after install.
|
# also the first model installed & the first nozzle installed will be activated after install.
|
||||||
#TODO: One day we may differentiate variants of the nozzles / hot ends,
|
#TODO: One day we may differentiate variants of the nozzles / hot ends,
|
||||||
#for example by the melt zone size, or whether the nozzle is hardened.
|
#for example by the melt zone size, or whether the nozzle is hardened.
|
||||||
[printer_model:MK3]
|
[printer_model:MK3]
|
||||||
|
name = Original Prusa i3 MK3
|
||||||
variants = 0.4; 0.25; 0.6
|
variants = 0.4; 0.25; 0.6
|
||||||
|
|
||||||
[printer_model:MK2S]
|
[printer_model:MK2S]
|
||||||
|
name = Original Prusa i3 MK2S
|
||||||
variants = 0.4; 0.25; 0.6
|
variants = 0.4; 0.25; 0.6
|
||||||
|
|
||||||
[printer_model:MK2SMM]
|
[printer_model:MK2SMM]
|
||||||
# Printer model name will be shown by the installation wizard.
|
# Printer model name will be shown by the installation wizard.
|
||||||
name = MK2S Multi Material
|
name = Original Prusa i3 MK2SMM
|
||||||
variants = 0.4; 0.6
|
variants = 0.4; 0.6
|
||||||
|
|
||||||
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
||||||
|
@ -205,12 +205,16 @@ add_library(libslic3r_gui STATIC
|
|||||||
${LIBDIR}/slic3r/GUI/BonjourDialog.hpp
|
${LIBDIR}/slic3r/GUI/BonjourDialog.hpp
|
||||||
${LIBDIR}/slic3r/Utils/ASCIIFolding.cpp
|
${LIBDIR}/slic3r/Utils/ASCIIFolding.cpp
|
||||||
${LIBDIR}/slic3r/Utils/ASCIIFolding.hpp
|
${LIBDIR}/slic3r/Utils/ASCIIFolding.hpp
|
||||||
|
${LIBDIR}/slic3r/GUI/ConfigWizard.cpp
|
||||||
|
${LIBDIR}/slic3r/GUI/ConfigWizard.hpp
|
||||||
${LIBDIR}/slic3r/Utils/Http.cpp
|
${LIBDIR}/slic3r/Utils/Http.cpp
|
||||||
${LIBDIR}/slic3r/Utils/Http.hpp
|
${LIBDIR}/slic3r/Utils/Http.hpp
|
||||||
${LIBDIR}/slic3r/Utils/OctoPrint.cpp
|
${LIBDIR}/slic3r/Utils/OctoPrint.cpp
|
||||||
${LIBDIR}/slic3r/Utils/OctoPrint.hpp
|
${LIBDIR}/slic3r/Utils/OctoPrint.hpp
|
||||||
${LIBDIR}/slic3r/Utils/Bonjour.cpp
|
${LIBDIR}/slic3r/Utils/Bonjour.cpp
|
||||||
${LIBDIR}/slic3r/Utils/Bonjour.hpp
|
${LIBDIR}/slic3r/Utils/Bonjour.hpp
|
||||||
|
${LIBDIR}/slic3r/Utils/PresetUpdate.cpp
|
||||||
|
${LIBDIR}/slic3r/Utils/PresetUpdate.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(admesh STATIC
|
add_library(admesh STATIC
|
||||||
@ -356,6 +360,7 @@ set(XS_XSP_FILES
|
|||||||
${XSP_DIR}/SurfaceCollection.xsp
|
${XSP_DIR}/SurfaceCollection.xsp
|
||||||
${XSP_DIR}/TriangleMesh.xsp
|
${XSP_DIR}/TriangleMesh.xsp
|
||||||
${XSP_DIR}/Utils_OctoPrint.xsp
|
${XSP_DIR}/Utils_OctoPrint.xsp
|
||||||
|
${XSP_DIR}/Utils_PresetUpdate.xsp
|
||||||
${XSP_DIR}/XS.xsp
|
${XSP_DIR}/XS.xsp
|
||||||
)
|
)
|
||||||
foreach (file ${XS_XSP_FILES})
|
foreach (file ${XS_XSP_FILES})
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
|
#include "libslic3r.h"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
extern void set_logging_level(unsigned int level);
|
extern void set_logging_level(unsigned int level);
|
||||||
|
@ -42,7 +42,7 @@ void AppConfig::set_defaults()
|
|||||||
set("no_defaults", "1");
|
set("no_defaults", "1");
|
||||||
if (get("show_incompatible_presets").empty())
|
if (get("show_incompatible_presets").empty())
|
||||||
set("show_incompatible_presets", "0");
|
set("show_incompatible_presets", "0");
|
||||||
// Version check is enabled by default in the config, but it is not implemented yet.
|
// Version check is enabled by default in the config, but it is not implemented yet. // XXX
|
||||||
if (get("version_check").empty())
|
if (get("version_check").empty())
|
||||||
set("version_check", "1");
|
set("version_check", "1");
|
||||||
// Use OpenGL 1.1 even if OpenGL 2.0 is available. This is mainly to support some buggy Intel HD Graphics drivers.
|
// Use OpenGL 1.1 even if OpenGL 2.0 is available. This is mainly to support some buggy Intel HD Graphics drivers.
|
||||||
|
433
xs/src/slic3r/GUI/ConfigWizard.cpp
Normal file
433
xs/src/slic3r/GUI/ConfigWizard.cpp
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
#include "ConfigWizard_private.hpp"
|
||||||
|
|
||||||
|
#include <iostream> // XXX
|
||||||
|
#include <algorithm>
|
||||||
|
#include <utility>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include <wx/settings.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
#include <wx/dcclient.h>
|
||||||
|
#include <wx/statbmp.h>
|
||||||
|
#include <wx/checkbox.h>
|
||||||
|
#include <wx/statline.h>
|
||||||
|
|
||||||
|
#include "libslic3r/Utils.hpp"
|
||||||
|
#include "PresetBundle.hpp"
|
||||||
|
#include "GUI.hpp"
|
||||||
|
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
|
||||||
|
// Wizard page base
|
||||||
|
|
||||||
|
ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname) :
|
||||||
|
wxPanel(parent),
|
||||||
|
parent(parent),
|
||||||
|
shortname(std::move(shortname)),
|
||||||
|
p_prev(nullptr),
|
||||||
|
p_next(nullptr)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
text->SetFont(font);
|
||||||
|
sizer->Add(text, 0, wxALIGN_LEFT, 0);
|
||||||
|
sizer->AddSpacer(10);
|
||||||
|
|
||||||
|
content = new wxBoxSizer(wxVERTICAL);
|
||||||
|
sizer->Add(content, 1);
|
||||||
|
|
||||||
|
SetSizer(sizer);
|
||||||
|
|
||||||
|
this->Hide();
|
||||||
|
|
||||||
|
Bind(wxEVT_SIZE, [this](wxSizeEvent &event) {
|
||||||
|
this->Layout();
|
||||||
|
event.Skip();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
widget->Wrap(CONTENT_WIDTH);
|
||||||
|
widget->SetMinSize(wxSize(CONTENT_WIDTH, -1));
|
||||||
|
// content->Add(widget, 1, wxALIGN_LEFT | wxTOP | wxBOTTOM, 10);
|
||||||
|
content->Add(widget, 0, wxALIGN_LEFT | wxTOP | wxBOTTOM, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigWizardPage::append_widget(wxWindow *widget, int proportion)
|
||||||
|
{
|
||||||
|
content->Add(widget, proportion, wxEXPAND | wxTOP | wxBOTTOM, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigWizardPage::append_spacer(int space)
|
||||||
|
{
|
||||||
|
content->AddSpacer(space);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigWizardPage::Show(bool show)
|
||||||
|
{
|
||||||
|
if (extra_buttons() != nullptr) { extra_buttons()->Show(show); }
|
||||||
|
return wxPanel::Show(show);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigWizardPage::enable_next(bool enable) { parent->p->enable_next(enable); }
|
||||||
|
|
||||||
|
|
||||||
|
// Wizard pages
|
||||||
|
|
||||||
|
PageWelcome::PageWelcome(ConfigWizard *parent, const PresetBundle &bundle) :
|
||||||
|
ConfigWizardPage(parent, _(L("Welcome to the Slic3r Configuration assistant")), _(L("Welcome"))),
|
||||||
|
others_buttons(new wxPanel(parent)),
|
||||||
|
variants_checked(0)
|
||||||
|
{
|
||||||
|
append_text(_(L("Hello, welcome to Slic3r Prusa Edition! TODO: This text.")));
|
||||||
|
|
||||||
|
const auto &vendors = bundle.vendors;
|
||||||
|
const auto vendor_prusa = std::find(vendors.cbegin(), vendors.cend(), VendorProfile("PrusaResearch"));
|
||||||
|
|
||||||
|
// TODO: preload checkiness from app config
|
||||||
|
|
||||||
|
if (vendor_prusa != vendors.cend()) {
|
||||||
|
const auto &models = vendor_prusa->models;
|
||||||
|
|
||||||
|
auto *printer_picker = new wxPanel(this);
|
||||||
|
auto *printer_grid = new wxFlexGridSizer(models.size(), 0, 20);
|
||||||
|
printer_grid->SetFlexibleDirection(wxVERTICAL);
|
||||||
|
printer_picker->SetSizer(printer_grid);
|
||||||
|
|
||||||
|
auto namefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||||
|
namefont.SetWeight(wxFONTWEIGHT_BOLD);
|
||||||
|
|
||||||
|
for (auto model = models.cbegin(); model != models.cend(); ++model) {
|
||||||
|
auto *panel = new wxPanel(printer_picker);
|
||||||
|
auto *sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
panel->SetSizer(sizer);
|
||||||
|
|
||||||
|
auto *title = new wxStaticText(panel, wxID_ANY, model->name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||||
|
title->SetFont(namefont);
|
||||||
|
sizer->Add(title, 0, wxBOTTOM, 3);
|
||||||
|
|
||||||
|
auto bitmap_file = wxString::Format("printers/%s.png", model->id);
|
||||||
|
wxBitmap bitmap(GUI::from_u8(Slic3r::var(bitmap_file.ToStdString())), wxBITMAP_TYPE_PNG);
|
||||||
|
auto *bitmap_widget = new wxStaticBitmap(panel, wxID_ANY, bitmap);
|
||||||
|
sizer->Add(bitmap_widget, 0, wxBOTTOM, 3);
|
||||||
|
|
||||||
|
sizer->AddSpacer(20);
|
||||||
|
|
||||||
|
for (const auto &variant : model->variants) {
|
||||||
|
auto *cbox = new wxCheckBox(panel, wxID_ANY, wxString::Format("%s %s %s", variant.name, _(L("mm")), _(L("nozzle"))));
|
||||||
|
sizer->Add(cbox, 0, wxBOTTOM, 3);
|
||||||
|
cbox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) {
|
||||||
|
this->variants_checked += event.IsChecked() ? 1 : -1;
|
||||||
|
this->on_variant_checked();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
printer_grid->Add(panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
append_widget(printer_picker);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto *sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
auto *other_vendors = new wxButton(others_buttons, wxID_ANY, _(L("Other vendors")));
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
chain(wizard_p()->page_update);
|
||||||
|
on_variant_checked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageWelcome::on_variant_checked()
|
||||||
|
{
|
||||||
|
enable_next(variants_checked > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
PageUpdate::PageUpdate(ConfigWizard *parent) :
|
||||||
|
ConfigWizardPage(parent, _(L("Automatic updates")), _(L("Updates")))
|
||||||
|
{
|
||||||
|
append_text(_(L("TODO: text")));
|
||||||
|
auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for Slic3r updates")));
|
||||||
|
box_slic3r->SetValue(true);
|
||||||
|
append_widget(box_slic3r);
|
||||||
|
|
||||||
|
append_text(_(L("TODO: text")));
|
||||||
|
auto *box_presets = new wxCheckBox(this, wxID_ANY, _(L("Update built-in Presets automatically")));
|
||||||
|
box_presets->SetValue(true);
|
||||||
|
append_widget(box_presets);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageUpdate::presets_update_enable(bool enable)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
PageVendors::PageVendors(ConfigWizard *parent) :
|
||||||
|
ConfigWizardPage(parent, _(L("Other Vendors")), _(L("Other Vendors")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
PageFirmware::PageFirmware(ConfigWizard *parent) :
|
||||||
|
ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
PageBedShape::PageBedShape(ConfigWizard *parent) :
|
||||||
|
ConfigWizardPage(parent, _(L("Bed Shape and Size")), _(L("Bed Shape")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
PageDiameters::PageDiameters(ConfigWizard *parent) :
|
||||||
|
ConfigWizardPage(parent, _(L("Filament and Nozzle Diameter")), _(L("Print Diameters")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
PageTemperatures::PageTemperatures(ConfigWizard *parent) :
|
||||||
|
ConfigWizardPage(parent, _(L("Bed and Extruder Temperature")), _(L("Temperatures")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
SetMinSize(bg.GetSize());
|
||||||
|
Bind(wxEVT_PAINT, &ConfigWizardIndex::on_paint, this);
|
||||||
|
|
||||||
|
wxClientDC dc(this);
|
||||||
|
text_height = dc.GetCharHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigWizardIndex::set_active(ConfigWizardPage *page)
|
||||||
|
{
|
||||||
|
item_active = std::find(items.cbegin(), items.cend(), page->shortname);
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
MARGIN = 10,
|
||||||
|
SPACING = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto size = GetClientSize();
|
||||||
|
const auto h = size.GetHeight();
|
||||||
|
const auto w = size.GetWidth();
|
||||||
|
if (h == 0 || w == 0) { return; }
|
||||||
|
|
||||||
|
wxPaintDC dc(this);
|
||||||
|
dc.DrawBitmap(bg, 0, h - bg.GetHeight(), false);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
y += yinc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// priv
|
||||||
|
|
||||||
|
void ConfigWizard::priv::index_refresh()
|
||||||
|
{
|
||||||
|
index->load_items(page_welcome);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigWizard::priv::add_page(ConfigWizardPage *page)
|
||||||
|
{
|
||||||
|
topsizer->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);
|
||||||
|
|
||||||
|
q->Layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigWizard::priv::enable_next(bool enable)
|
||||||
|
{
|
||||||
|
btn_next->Enable(enable);
|
||||||
|
btn_finish->Enable(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigWizard::priv::on_other_vendors()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public
|
||||||
|
|
||||||
|
ConfigWizard::ConfigWizard(wxWindow *parent, const PresetBundle &bundle) :
|
||||||
|
wxDialog(parent, wxID_ANY, _(L("Configuration Assistant")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
|
||||||
|
p(new priv(this))
|
||||||
|
{
|
||||||
|
p->index = new ConfigWizardIndex(this);
|
||||||
|
|
||||||
|
auto *vsizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
p->topsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
auto *hline = new wxStaticLine(this);
|
||||||
|
p->btnsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
|
p->topsizer->Add(p->index, 0, wxEXPAND);
|
||||||
|
p->topsizer->AddSpacer(INDEX_MARGIN);
|
||||||
|
|
||||||
|
// TODO: btn labels vs default w/ icons ... use arrows from resources? (no apply icon)
|
||||||
|
// Also: http://docs.wxwidgets.org/3.0/page_stockitems.html
|
||||||
|
p->btn_prev = new wxButton(this, wxID_BACKWARD, _(L("< &Back")));
|
||||||
|
p->btn_next = new wxButton(this, wxID_FORWARD, _(L("&Next >")));
|
||||||
|
p->btn_finish = new wxButton(this, wxID_APPLY, _(L("&Finish")));
|
||||||
|
p->btn_cancel = new wxButton(this, wxID_CANCEL);
|
||||||
|
p->btnsizer->AddStretchSpacer();
|
||||||
|
p->btnsizer->Add(p->btn_prev, 0, wxLEFT, BTN_SPACING);
|
||||||
|
p->btnsizer->Add(p->btn_next, 0, wxLEFT, BTN_SPACING);
|
||||||
|
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, bundle));
|
||||||
|
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);
|
||||||
|
|
||||||
|
vsizer->Add(p->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);
|
||||||
|
SetSizerAndFit(vsizer);
|
||||||
|
SetMinSize(GetSize());
|
||||||
|
|
||||||
|
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(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigWizard::~ConfigWizard() {}
|
||||||
|
|
||||||
|
void ConfigWizard::run(wxWindow *parent)
|
||||||
|
{
|
||||||
|
PresetBundle bundle;
|
||||||
|
|
||||||
|
const auto profiles_dir = fs::path(resources_dir()) / "profiles";
|
||||||
|
for (fs::directory_iterator it(profiles_dir); it != fs::directory_iterator(); ++it) {
|
||||||
|
if (it->path().extension() == ".ini") {
|
||||||
|
bundle.load_configbundle(it->path().native(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
for (const auto &vendor : bundle.vendors) {
|
||||||
|
std::cerr << "vendor: " << vendor.name << std::endl;
|
||||||
|
std::cerr << " URL: " << vendor.config_update_url << std::endl;
|
||||||
|
for (const auto &model : vendor.models) {
|
||||||
|
std::cerr << "\tmodel: " << model.id << " (" << model.name << ")" << std::endl;
|
||||||
|
for (const auto &variant : model.variants) {
|
||||||
|
std::cerr << "\t\tvariant: " << variant.name << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigWizard wizard(parent, bundle);
|
||||||
|
wizard.ShowModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
38
xs/src/slic3r/GUI/ConfigWizard.hpp
Normal file
38
xs/src/slic3r/GUI/ConfigWizard.hpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef slic3r_ConfigWizard_hpp_
|
||||||
|
#define slic3r_ConfigWizard_hpp_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <wx/dialog.h>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class PresetBundle;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigWizard: public wxDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConfigWizard(wxWindow *parent, const PresetBundle &bundle);
|
||||||
|
ConfigWizard(ConfigWizard &&) = delete;
|
||||||
|
ConfigWizard(const ConfigWizard &) = delete;
|
||||||
|
ConfigWizard &operator=(ConfigWizard &&) = delete;
|
||||||
|
ConfigWizard &operator=(const ConfigWizard &) = delete;
|
||||||
|
~ConfigWizard();
|
||||||
|
|
||||||
|
static void run(wxWindow *parent);
|
||||||
|
private:
|
||||||
|
struct priv;
|
||||||
|
std::unique_ptr<priv> p;
|
||||||
|
|
||||||
|
friend class ConfigWizardPage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
162
xs/src/slic3r/GUI/ConfigWizard_private.hpp
Normal file
162
xs/src/slic3r/GUI/ConfigWizard_private.hpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#ifndef slic3r_ConfigWizard_private_hpp_
|
||||||
|
#define slic3r_ConfigWizard_private_hpp_
|
||||||
|
|
||||||
|
#include "ConfigWizard.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/panel.h>
|
||||||
|
#include <wx/button.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DIALOG_MARGIN = 15,
|
||||||
|
INDEX_MARGIN = 40,
|
||||||
|
BTN_SPACING = 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConfigWizardPage: wxPanel
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
CONTENT_WIDTH = 500,
|
||||||
|
};
|
||||||
|
|
||||||
|
ConfigWizard *parent;
|
||||||
|
const wxString shortname;
|
||||||
|
wxBoxSizer *content;
|
||||||
|
|
||||||
|
ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname);
|
||||||
|
|
||||||
|
virtual ~ConfigWizardPage();
|
||||||
|
|
||||||
|
ConfigWizardPage *page_prev() const { return p_prev; }
|
||||||
|
ConfigWizardPage *page_next() const { return p_next; }
|
||||||
|
ConfigWizardPage* chain(ConfigWizardPage *page);
|
||||||
|
|
||||||
|
void append_text(wxString text);
|
||||||
|
void append_widget(wxWindow *widget, int proportion = 0);
|
||||||
|
void append_spacer(int space);
|
||||||
|
|
||||||
|
ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
|
||||||
|
|
||||||
|
virtual bool Show(bool show = true);
|
||||||
|
virtual bool Hide() { return Show(false); }
|
||||||
|
virtual wxPanel* extra_buttons() { return nullptr; }
|
||||||
|
virtual void on_page_set() {}
|
||||||
|
|
||||||
|
void enable_next(bool enable);
|
||||||
|
private:
|
||||||
|
ConfigWizardPage *p_prev;
|
||||||
|
ConfigWizardPage *p_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PageWelcome: ConfigWizardPage
|
||||||
|
{
|
||||||
|
wxPanel *others_buttons;
|
||||||
|
unsigned variants_checked;
|
||||||
|
|
||||||
|
PageWelcome(ConfigWizard *parent, const PresetBundle &bundle);
|
||||||
|
|
||||||
|
virtual wxPanel* extra_buttons() { return others_buttons; }
|
||||||
|
virtual void on_page_set();
|
||||||
|
|
||||||
|
void on_variant_checked();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PageUpdate: ConfigWizardPage
|
||||||
|
{
|
||||||
|
PageUpdate(ConfigWizard *parent);
|
||||||
|
|
||||||
|
void presets_update_enable(bool enable);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PageVendors: ConfigWizardPage
|
||||||
|
{
|
||||||
|
PageVendors(ConfigWizard *parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PageFirmware: ConfigWizardPage
|
||||||
|
{
|
||||||
|
PageFirmware(ConfigWizard *parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PageBedShape: ConfigWizardPage
|
||||||
|
{
|
||||||
|
PageBedShape(ConfigWizard *parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PageDiameters: ConfigWizardPage
|
||||||
|
{
|
||||||
|
PageDiameters(ConfigWizard *parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PageTemperatures: ConfigWizardPage
|
||||||
|
{
|
||||||
|
PageTemperatures(ConfigWizard *parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigWizardIndex: public wxPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConfigWizardIndex(wxWindow *parent);
|
||||||
|
|
||||||
|
void load_items(ConfigWizardPage *firstpage);
|
||||||
|
void set_active(ConfigWizardPage *page);
|
||||||
|
private:
|
||||||
|
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;
|
||||||
|
|
||||||
|
void on_paint(wxPaintEvent & evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConfigWizard::priv
|
||||||
|
{
|
||||||
|
ConfigWizard *q;
|
||||||
|
wxBoxSizer *topsizer = nullptr;
|
||||||
|
wxBoxSizer *btnsizer = nullptr;
|
||||||
|
ConfigWizardPage *page_current = nullptr;
|
||||||
|
ConfigWizardIndex *index = nullptr;
|
||||||
|
wxButton *btn_prev = nullptr;
|
||||||
|
wxButton *btn_next = nullptr;
|
||||||
|
wxButton *btn_finish = nullptr;
|
||||||
|
wxButton *btn_cancel = nullptr;
|
||||||
|
|
||||||
|
PageWelcome *page_welcome = nullptr;
|
||||||
|
PageUpdate *page_update = nullptr;
|
||||||
|
PageVendors *page_vendors = nullptr;
|
||||||
|
PageFirmware *page_firmware = nullptr;
|
||||||
|
PageBedShape *page_bed = nullptr;
|
||||||
|
PageDiameters *page_diams = nullptr;
|
||||||
|
PageTemperatures *page_temps = nullptr;
|
||||||
|
|
||||||
|
priv(ConfigWizard *q) : q(q) {}
|
||||||
|
|
||||||
|
void add_page(ConfigWizardPage *page);
|
||||||
|
void index_refresh();
|
||||||
|
void set_page(ConfigWizardPage *page);
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -44,6 +44,7 @@
|
|||||||
#include "TabIface.hpp"
|
#include "TabIface.hpp"
|
||||||
#include "AppConfig.hpp"
|
#include "AppConfig.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
#include "ConfigWizard.hpp"
|
||||||
#include "Preferences.hpp"
|
#include "Preferences.hpp"
|
||||||
#include "PresetBundle.hpp"
|
#include "PresetBundle.hpp"
|
||||||
|
|
||||||
@ -352,6 +353,20 @@ void add_debug_menu(wxMenuBar *menu, int event_language_change)
|
|||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void open_config_wizard()
|
||||||
|
{
|
||||||
|
if (g_wxMainFrame == nullptr) {
|
||||||
|
throw std::runtime_error("Main frame not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto *wizard = new ConfigWizard(static_cast<wxWindow*>(g_wxMainFrame)); // FIXME: lifetime
|
||||||
|
|
||||||
|
// wizard->run();
|
||||||
|
ConfigWizard::run(g_wxMainFrame);
|
||||||
|
|
||||||
|
// show_info(g_wxMainFrame, "After wizard", "After wizard");
|
||||||
|
}
|
||||||
|
|
||||||
void open_preferences_dialog(int event_preferences)
|
void open_preferences_dialog(int event_preferences)
|
||||||
{
|
{
|
||||||
auto dlg = new PreferencesDialog(g_wxMainFrame, event_preferences);
|
auto dlg = new PreferencesDialog(g_wxMainFrame, event_preferences);
|
||||||
|
@ -73,6 +73,7 @@ void break_to_debugger();
|
|||||||
// Passing the wxWidgets GUI classes instantiated by the Perl part to C++.
|
// Passing the wxWidgets GUI classes instantiated by the Perl part to C++.
|
||||||
void set_wxapp(wxApp *app);
|
void set_wxapp(wxApp *app);
|
||||||
void set_main_frame(wxFrame *main_frame);
|
void set_main_frame(wxFrame *main_frame);
|
||||||
|
// wxFrame* get_main_frame();
|
||||||
void set_tab_panel(wxNotebook *tab_panel);
|
void set_tab_panel(wxNotebook *tab_panel);
|
||||||
void set_app_config(AppConfig *app_config);
|
void set_app_config(AppConfig *app_config);
|
||||||
void set_preset_bundle(PresetBundle *preset_bundle);
|
void set_preset_bundle(PresetBundle *preset_bundle);
|
||||||
@ -84,6 +85,9 @@ wxColour* get_sys_label_clr();
|
|||||||
|
|
||||||
void add_debug_menu(wxMenuBar *menu, int event_language_change);
|
void add_debug_menu(wxMenuBar *menu, int event_language_change);
|
||||||
|
|
||||||
|
// Opens the first-time configuration wizard
|
||||||
|
void open_config_wizard();
|
||||||
|
|
||||||
// Create "Preferences" dialog after selecting menu "Preferences" in Perl part
|
// Create "Preferences" dialog after selecting menu "Preferences" in Perl part
|
||||||
void open_preferences_dialog(int event_preferences);
|
void open_preferences_dialog(int event_preferences);
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ void PreferencesDialog::build()
|
|||||||
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
|
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO
|
||||||
// $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
|
// $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
|
||||||
// opt_id = > 'version_check',
|
// opt_id = > 'version_check',
|
||||||
// type = > 'bool',
|
// type = > 'bool',
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
|
|
||||||
struct PrinterModel {
|
struct PrinterModel {
|
||||||
PrinterModel() {}
|
PrinterModel() {}
|
||||||
PrinterModel(const std::string &name) : name(name) {}
|
std::string id;
|
||||||
std::string name;
|
std::string name;
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
std::vector<PrinterVariant> variants;
|
std::vector<PrinterVariant> variants;
|
||||||
@ -51,11 +51,10 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
|
const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
|
||||||
|
|
||||||
bool operator< (const PrinterModel &rhs) const { return this->name < rhs.name; }
|
|
||||||
bool operator==(const PrinterModel &rhs) const { return this->name == rhs.name; }
|
|
||||||
};
|
};
|
||||||
std::set<PrinterModel> models;
|
std::vector<PrinterModel> models;
|
||||||
|
|
||||||
|
VendorProfile(std::string id) : id(std::move(id)) {}
|
||||||
|
|
||||||
size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
|
size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "PresetBundle.hpp"
|
#include "PresetBundle.hpp"
|
||||||
#include "BitmapCache.hpp"
|
#include "BitmapCache.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/algorithm/clamp.hpp>
|
#include <boost/algorithm/clamp.hpp>
|
||||||
@ -104,6 +105,7 @@ void PresetBundle::setup_directories()
|
|||||||
std::initializer_list<boost::filesystem::path> paths = {
|
std::initializer_list<boost::filesystem::path> paths = {
|
||||||
data_dir,
|
data_dir,
|
||||||
data_dir / "vendor",
|
data_dir / "vendor",
|
||||||
|
data_dir / "cache",
|
||||||
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
|
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
|
||||||
// Store the print/filament/printer presets into a "presets" directory.
|
// Store the print/filament/printer presets into a "presets" directory.
|
||||||
data_dir / "presets",
|
data_dir / "presets",
|
||||||
@ -198,6 +200,7 @@ static inline std::string remove_ini_suffix(const std::string &name)
|
|||||||
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
|
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
|
||||||
void PresetBundle::load_installed_printers(const AppConfig &config)
|
void PresetBundle::load_installed_printers(const AppConfig &config)
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
// m_storage
|
// m_storage
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,7 +670,7 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree)
|
|||||||
static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorProfile &vendor_profile)
|
static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorProfile &vendor_profile)
|
||||||
{
|
{
|
||||||
const std::string printer_model_key = "printer_model:";
|
const std::string printer_model_key = "printer_model:";
|
||||||
for (auto §ion : tree)
|
for (auto §ion : tree) {
|
||||||
if (section.first == "vendor") {
|
if (section.first == "vendor") {
|
||||||
// Load the names of the active presets.
|
// Load the names of the active presets.
|
||||||
for (auto &kvp : section.second) {
|
for (auto &kvp : section.second) {
|
||||||
@ -682,7 +685,8 @@ static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorP
|
|||||||
}
|
}
|
||||||
} else if (boost::starts_with(section.first, printer_model_key)) {
|
} else if (boost::starts_with(section.first, printer_model_key)) {
|
||||||
VendorProfile::PrinterModel model;
|
VendorProfile::PrinterModel model;
|
||||||
model.name = section.first.substr(printer_model_key.size());
|
model.id = section.first.substr(printer_model_key.size());
|
||||||
|
model.name = section.second.get<std::string>("name", model.id);
|
||||||
section.second.get<std::string>("variants", "");
|
section.second.get<std::string>("variants", "");
|
||||||
std::vector<std::string> variants;
|
std::vector<std::string> variants;
|
||||||
if (Slic3r::unescape_strings_cstyle(section.second.get<std::string>("variants", ""), variants)) {
|
if (Slic3r::unescape_strings_cstyle(section.second.get<std::string>("variants", ""), variants)) {
|
||||||
@ -693,8 +697,9 @@ static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorP
|
|||||||
} else {
|
} else {
|
||||||
// Log error?
|
// Log error?
|
||||||
}
|
}
|
||||||
if (! model.name.empty() && ! model.variants.empty())
|
if (! model.id.empty() && ! model.variants.empty())
|
||||||
vendor_profile.models.insert(model);
|
vendor_profile.models.push_back(std::move(model));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,12 +724,11 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
|||||||
pt::ptree tree;
|
pt::ptree tree;
|
||||||
boost::nowide::ifstream ifs(path);
|
boost::nowide::ifstream ifs(path);
|
||||||
pt::read_ini(ifs, tree);
|
pt::read_ini(ifs, tree);
|
||||||
// Flatten the config bundle by applying the inheritance rules. Internal profiles (with names starting with '*') are removed.
|
|
||||||
flatten_configbundle_hierarchy(tree);
|
|
||||||
|
|
||||||
const VendorProfile *vendor_profile = nullptr;
|
const VendorProfile *vendor_profile = nullptr;
|
||||||
if (flags & LOAD_CFGBNDLE_SYSTEM) {
|
if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) {
|
||||||
VendorProfile vp;
|
boost::filesystem::path fspath(path);
|
||||||
|
VendorProfile vp(fspath.stem().native());
|
||||||
load_vendor_profile(tree, vp);
|
load_vendor_profile(tree, vp);
|
||||||
if (vp.name.empty())
|
if (vp.name.empty())
|
||||||
throw std::runtime_error(std::string("Vendor Config Bundle is not valid: Missing vendor name key."));
|
throw std::runtime_error(std::string("Vendor Config Bundle is not valid: Missing vendor name key."));
|
||||||
@ -733,6 +737,13 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
|||||||
vendor_profile = &(*this->vendors.insert(vp).first);
|
vendor_profile = &(*this->vendors.insert(vp).first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & LOAD_CFGBUNDLE_VENDOR_ONLY) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.5) Flatten the config bundle by applying the inheritance rules. Internal profiles (with names starting with '*') are removed.
|
||||||
|
flatten_configbundle_hierarchy(tree);
|
||||||
|
|
||||||
// 2) Parse the property_tree, extract the active preset names and the profiles, save them into local config files.
|
// 2) Parse the property_tree, extract the active preset names and the profiles, save them into local config files.
|
||||||
std::vector<std::string> loaded_prints;
|
std::vector<std::string> loaded_prints;
|
||||||
std::vector<std::string> loaded_filaments;
|
std::vector<std::string> loaded_filaments;
|
||||||
@ -803,7 +814,9 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
|
|||||||
section.first << "\" defines no printer variant, it will be ignored.";
|
section.first << "\" defines no printer variant, it will be ignored.";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto it_model = vendor_profile->models.find(VendorProfile::PrinterModel(printer_model));
|
auto it_model = std::find_if(vendor_profile->models.cbegin(), vendor_profile->models.cend(),
|
||||||
|
[&](const VendorProfile::PrinterModel &m) { return m.id == printer_model; }
|
||||||
|
);
|
||||||
if (it_model == vendor_profile->models.end()) {
|
if (it_model == vendor_profile->models.end()) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
|
BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
|
||||||
section.first << "\" defines invalid printer model \"" << printer_model << "\", it will be ignored.";
|
section.first << "\" defines invalid printer model \"" << printer_model << "\", it will be ignored.";
|
||||||
|
@ -81,6 +81,7 @@ public:
|
|||||||
LOAD_CFGBNDLE_RESET_USER_PROFILE = 2,
|
LOAD_CFGBNDLE_RESET_USER_PROFILE = 2,
|
||||||
// Load a system config bundle.
|
// Load a system config bundle.
|
||||||
LOAD_CFGBNDLE_SYSTEM = 4,
|
LOAD_CFGBNDLE_SYSTEM = 4,
|
||||||
|
LOAD_CFGBUNDLE_VENDOR_ONLY = 8,
|
||||||
};
|
};
|
||||||
// Load the config bundle, store it to the user profile directory by default.
|
// Load the config bundle, store it to the user profile directory by default.
|
||||||
size_t load_configbundle(const std::string &path, unsigned int flags = LOAD_CFGBNDLE_SAVE);
|
size_t load_configbundle(const std::string &path, unsigned int flags = LOAD_CFGBNDLE_SAVE);
|
||||||
|
104
xs/src/slic3r/Utils/PresetUpdate.cpp
Normal file
104
xs/src/slic3r/Utils/PresetUpdate.cpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include "PresetUpdate.hpp"
|
||||||
|
|
||||||
|
#include <iostream> // XXX
|
||||||
|
#include <thread>
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
|
||||||
|
#include "libslic3r/Utils.hpp"
|
||||||
|
#include "slic3r/GUI/PresetBundle.hpp"
|
||||||
|
#include "slic3r/Utils/Http.hpp"
|
||||||
|
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
|
||||||
|
struct PresetUpdater::priv
|
||||||
|
{
|
||||||
|
PresetBundle *bundle;
|
||||||
|
fs::path cache_path;
|
||||||
|
std::thread thread;
|
||||||
|
|
||||||
|
priv(PresetBundle *bundle);
|
||||||
|
|
||||||
|
void download();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
PresetUpdater::priv::priv(PresetBundle *bundle) :
|
||||||
|
bundle(bundle),
|
||||||
|
cache_path(fs::path(Slic3r::data_dir()) / "cache")
|
||||||
|
{}
|
||||||
|
|
||||||
|
void PresetUpdater::priv::download()
|
||||||
|
{
|
||||||
|
std::cerr << "PresetUpdater::priv::download()" << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "Bundle vendors: " << bundle->vendors.size() << std::endl;
|
||||||
|
for (const auto &vendor : bundle->vendors) {
|
||||||
|
std::cerr << "vendor: " << vendor.name << std::endl;
|
||||||
|
std::cerr << " URL: " << vendor.config_update_url << std::endl;
|
||||||
|
|
||||||
|
// TODO: Proper caching
|
||||||
|
|
||||||
|
auto target_path = cache_path / vendor.id;
|
||||||
|
target_path += ".ini";
|
||||||
|
std::cerr << "target_path: " << target_path << std::endl;
|
||||||
|
|
||||||
|
Http::get(vendor.config_update_url)
|
||||||
|
.on_complete([&](std::string body, unsigned http_status) {
|
||||||
|
std::cerr << "Got ini: " << http_status << ", body: " << body.size() << std::endl;
|
||||||
|
fs::fstream file(target_path, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||||
|
file.write(body.c_str(), body.size());
|
||||||
|
})
|
||||||
|
.on_error([](std::string body, std::string error, unsigned http_status) {
|
||||||
|
// TODO: what about errors?
|
||||||
|
std::cerr << "Error: " << http_status << ", " << error << std::endl;
|
||||||
|
})
|
||||||
|
.perform_sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PresetUpdater::PresetUpdater(PresetBundle *preset_bundle) : p(new priv(preset_bundle)) {}
|
||||||
|
|
||||||
|
|
||||||
|
// Public
|
||||||
|
|
||||||
|
PresetUpdater::~PresetUpdater()
|
||||||
|
{
|
||||||
|
if (p && p->thread.joinable()) {
|
||||||
|
p->thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PresetUpdater::download(AppConfig *app_config, PresetBundle *preset_bundle)
|
||||||
|
{
|
||||||
|
std::cerr << "PresetUpdater::download()" << std::endl;
|
||||||
|
|
||||||
|
auto self = std::make_shared<PresetUpdater>(preset_bundle);
|
||||||
|
auto thread = std::thread([self](){
|
||||||
|
self->p->download();
|
||||||
|
});
|
||||||
|
self->p->thread = std::move(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: remove
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
void preset_update_check()
|
||||||
|
{
|
||||||
|
std::cerr << "preset_update_check()" << std::endl;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// 1. Get a version tag or the whole bundle from the web
|
||||||
|
// 2. Store into temporary location (?)
|
||||||
|
// 3. ???
|
||||||
|
// 4. Profit!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
xs/src/slic3r/Utils/PresetUpdate.hpp
Normal file
38
xs/src/slic3r/Utils/PresetUpdate.hpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef slic3r_PresetUpdate_hpp_
|
||||||
|
#define slic3r_PresetUpdate_hpp_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
|
||||||
|
class AppConfig;
|
||||||
|
class PresetBundle;
|
||||||
|
|
||||||
|
class PresetUpdater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PresetUpdater(PresetBundle *preset_bundle);
|
||||||
|
PresetUpdater(PresetUpdater &&) = delete;
|
||||||
|
PresetUpdater(const PresetUpdater &) = delete;
|
||||||
|
PresetUpdater &operator=(PresetUpdater &&) = delete;
|
||||||
|
PresetUpdater &operator=(const PresetUpdater &) = delete;
|
||||||
|
~PresetUpdater();
|
||||||
|
|
||||||
|
static void download(AppConfig *app_config, PresetBundle *preset_bundle);
|
||||||
|
private:
|
||||||
|
struct priv;
|
||||||
|
std::unique_ptr<priv> p;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Remove
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
void preset_update_check();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -54,6 +54,9 @@ int combochecklist_get_flags(SV *ui)
|
|||||||
void set_app_config(AppConfig *app_config)
|
void set_app_config(AppConfig *app_config)
|
||||||
%code%{ Slic3r::GUI::set_app_config(app_config); %};
|
%code%{ Slic3r::GUI::set_app_config(app_config); %};
|
||||||
|
|
||||||
|
void open_config_wizard()
|
||||||
|
%code%{ Slic3r::GUI::open_config_wizard(); %};
|
||||||
|
|
||||||
void open_preferences_dialog(int preferences_event)
|
void open_preferences_dialog(int preferences_event)
|
||||||
%code%{ Slic3r::GUI::open_preferences_dialog(preferences_event); %};
|
%code%{ Slic3r::GUI::open_preferences_dialog(preferences_event); %};
|
||||||
|
|
||||||
|
18
xs/xsp/Utils_PresetUpdate.xsp
Normal file
18
xs/xsp/Utils_PresetUpdate.xsp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
%module{Slic3r::XS};
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <xsinit.h>
|
||||||
|
#include "slic3r/Utils/PresetUpdate.hpp"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%name{Slic3r::PresetUpdater} class PresetUpdater {
|
||||||
|
static void download(PresetBundle *preset_bundle);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: remove:
|
||||||
|
|
||||||
|
%package{Slic3r::Utils};
|
||||||
|
|
||||||
|
void preset_update_check()
|
||||||
|
%code%{ Slic3r::Utils::preset_update_check(); %};
|
@ -235,6 +235,9 @@ PresetHints* O_OBJECT_SLIC3R
|
|||||||
Ref<PresetHints> O_OBJECT_SLIC3R_T
|
Ref<PresetHints> O_OBJECT_SLIC3R_T
|
||||||
TabIface* O_OBJECT_SLIC3R
|
TabIface* O_OBJECT_SLIC3R
|
||||||
Ref<TabIface> O_OBJECT_SLIC3R_T
|
Ref<TabIface> O_OBJECT_SLIC3R_T
|
||||||
|
# TODO: remove:
|
||||||
|
# ConfigWizard* O_OBJECT_SLIC3R
|
||||||
|
# Ref<ConfigWizard> O_OBJECT_SLIC3R_T
|
||||||
|
|
||||||
OctoPrint* O_OBJECT_SLIC3R
|
OctoPrint* O_OBJECT_SLIC3R
|
||||||
Ref<OctoPrint> O_OBJECT_SLIC3R_T
|
Ref<OctoPrint> O_OBJECT_SLIC3R_T
|
||||||
|
Loading…
Reference in New Issue
Block a user