#ifndef slic3r_ConfigWizard_private_hpp_ #define slic3r_ConfigWizard_private_hpp_ #include "ConfigWizard.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libslic3r/PrintConfig.hpp" #include "slic3r/Utils/PresetUpdater.hpp" #include "AppConfig.hpp" #include "PresetBundle.hpp" #include "BedShapeDialog.hpp" namespace fs = boost::filesystem; namespace Slic3r { namespace GUI { enum { WRAP_WIDTH = 500, MODEL_MIN_WRAP = 150, DIALOG_MARGIN = 15, INDEX_MARGIN = 40, BTN_SPACING = 10, INDENT_SPACING = 30, VERTICAL_SPACING = 10, MAX_COLS = 4, ROW_SPACING = 75, }; // Configuration data structures extensions needed for the wizard enum Technology { // Bitflag equivalent of PrinterTechnology T_FFF = 0x1, T_SLA = 0x2, T_ANY = ~0, }; struct Materials { Technology technology; std::set presets; std::set types; Materials(Technology technology) : technology(technology) {} void push(const Preset *preset); void clear(); bool containts(const Preset *preset) { return presets.find(preset) != presets.end(); } const std::string& appconfig_section() const; const std::string& get_type(const Preset *preset) const; const std::string& get_vendor(const Preset *preset) const; template void filter_presets(const std::string &type, const std::string &vendor, F cb) { for (const Preset *preset : presets) { if ((type.empty() || get_type(preset) == type) && (vendor.empty() || get_vendor(preset) == vendor)) { cb(preset); } } } static const std::string UNKNOWN; static const std::string& get_filament_type(const Preset *preset); static const std::string& get_filament_vendor(const Preset *preset); static const std::string& get_material_type(const Preset *preset); static const std::string& get_material_vendor(const Preset *preset); }; struct Bundle { std::unique_ptr preset_bundle; VendorProfile *vendor_profile; const bool is_in_resources; const bool is_prusa_bundle; Bundle(fs::path source_path, bool is_in_resources, bool is_prusa_bundle = false); Bundle(Bundle &&other); const std::string& vendor_id() const { return vendor_profile->id; } }; struct BundleMap: std::unordered_map { static BundleMap load(); Bundle& prusa_bundle(); const Bundle& prusa_bundle() const; }; struct PrinterPickerEvent; // GUI elements typedef std::function ModelFilter; struct PrinterPicker: wxPanel { struct Checkbox : wxCheckBox { Checkbox(wxWindow *parent, const wxString &label, const std::string &model, const std::string &variant) : wxCheckBox(parent, wxID_ANY, label), model(model), variant(variant) {} std::string model; std::string variant; }; const std::string vendor_id; std::vector cboxes; std::vector cboxes_alt; PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig, const ModelFilter &filter); PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig); void select_all(bool select, bool alternates = false); void select_one(size_t i, bool select); bool any_selected() const; int get_width() const { return width; } const std::vector& get_button_indexes() { return m_button_indexes; } static const std::string PRINTER_PLACEHOLDER; private: int width; std::vector m_button_indexes; void on_checkbox(const Checkbox *cbox, bool checked); }; struct ConfigWizardPage: wxPanel { ConfigWizard *parent; const wxString shortname; wxBoxSizer *content; const unsigned indent; ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname, unsigned indent = 0); virtual ~ConfigWizardPage(); template T* append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10) { content->Add(thing, proportion, flag, border); return thing; } wxStaticText* append_text(wxString text); void append_spacer(int space); ConfigWizard::priv *wizard_p() const { return parent->p.get(); } virtual void apply_custom_config(DynamicPrintConfig &config) {} virtual void set_run_reason(ConfigWizard::RunReason run_reason) {} virtual void on_activate() {} }; struct PageWelcome: ConfigWizardPage { wxStaticText *welcome_text; wxCheckBox *cbox_reset; PageWelcome(ConfigWizard *parent); bool reset_user_profile() const { return cbox_reset != nullptr ? cbox_reset->GetValue() : false; } virtual void set_run_reason(ConfigWizard::RunReason run_reason) override; }; struct PagePrinters: ConfigWizardPage { std::vector printer_pickers; Technology technology; bool install; PagePrinters(ConfigWizard *parent, wxString title, wxString shortname, const VendorProfile &vendor, unsigned indent, Technology technology); void select_all(bool select, bool alternates = false); int get_width() const; bool any_selected() const; virtual void set_run_reason(ConfigWizard::RunReason run_reason) override; }; // Here we extend wxListBox and wxCheckListBox // to make the client data API much easier to use. template struct DataList : public T { DataList(wxWindow *parent) : T(parent, wxID_ANY) {} // Note: We're _not_ using wxLB_SORT here because it doesn't do the right thing, // eg. "ABS" is sorted before "(All)" int append(const std::string &label, const D *data) { void *ptr = reinterpret_cast(const_cast(data)); return this->Append(from_u8(label), ptr); } int append(const wxString &label, const D *data) { void *ptr = reinterpret_cast(const_cast(data)); return this->Append(label, ptr); } const D& get_data(int n) { return *reinterpret_cast(this->GetClientData(n)); } int find(const D &data) { for (unsigned i = 0; i < this->GetCount(); i++) { if (get_data(i) == data) { return i; } } return wxNOT_FOUND; } }; typedef DataList StringList; typedef DataList PresetList; struct PageMaterials: ConfigWizardPage { Materials *materials; StringList *list_l1, *list_l2; PresetList *list_l3; int sel1_prev, sel2_prev; bool presets_loaded; static const std::string EMPTY; PageMaterials(ConfigWizard *parent, Materials *materials, wxString title, wxString shortname, wxString list1name); void reload_presets(); void update_lists(int sel1, int sel2); void select_material(int i); void select_all(bool select); void clear(); virtual void on_activate() override; }; 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: static const char* default_profile_name; wxCheckBox *cb_custom; wxTextCtrl *tc_profile_name; wxString profile_name_prev; }; struct PageUpdate: ConfigWizardPage { bool version_check; bool preset_update; PageUpdate(ConfigWizard *parent); }; struct PageMode: ConfigWizardPage { wxRadioButton *radio_simple; wxRadioButton *radio_advanced; wxRadioButton *radio_expert; PageMode(ConfigWizard *parent); void serialize_mode(AppConfig *app_config) const; virtual void on_activate(); }; struct PageVendors: ConfigWizardPage { PageVendors(ConfigWizard *parent); }; struct PageFirmware: ConfigWizardPage { const ConfigOptionDef &gcode_opt; wxChoice *gcode_picker; PageFirmware(ConfigWizard *parent); virtual void apply_custom_config(DynamicPrintConfig &config); }; struct PageBedShape: ConfigWizardPage { BedShapePanel *shape_panel; PageBedShape(ConfigWizard *parent); virtual void apply_custom_config(DynamicPrintConfig &config); }; struct PageDiameters: ConfigWizardPage { wxSpinCtrlDouble *spin_nozzle; wxSpinCtrlDouble *spin_filam; PageDiameters(ConfigWizard *parent); virtual void apply_custom_config(DynamicPrintConfig &config); }; struct PageTemperatures: ConfigWizardPage { wxSpinCtrlDouble *spin_extr; wxSpinCtrlDouble *spin_bed; PageTemperatures(ConfigWizard *parent); virtual void apply_custom_config(DynamicPrintConfig &config); }; typedef std::map Pages3rdparty; class ConfigWizardIndex: public wxPanel { public: ConfigWizardIndex(wxWindow *parent); 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(const ConfigWizardPage *page); void clear(); void msw_rescale(); int em() const { return em_w; } static const size_t NO_ITEM = size_t(-1); private: struct Item { wxString label; unsigned indent; ConfigWizardPage *page; // nullptr page => label-only item bool operator==(ConfigWizardPage *page) const { return this->page == page; } }; int em_w; int em_h; ScalableBitmap bg; ScalableBitmap bullet_black; ScalableBitmap bullet_blue; ScalableBitmap bullet_white; wxStaticBitmap* logo; std::vector items; size_t item_active; ssize_t item_hover; size_t last_page; int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em_w) + em_w; } void on_paint(wxPaintEvent &evt); void on_mouse_move(wxMouseEvent &evt); }; wxDEFINE_EVENT(EVT_INDEX_PAGE, wxCommandEvent); // ConfigWizard private data struct ConfigWizard::priv { ConfigWizard *q; ConfigWizard::RunReason run_reason = RR_USER; AppConfig appconfig_new; // Backing for vendor/model/variant and material selections in the GUI BundleMap bundles; // Holds all loaded config bundles, the key is the vendor names. // Materials refers to Presets in those bundles by pointers. // Also we update the is_visible flag in printer Presets according to the // PrinterPickers state. Materials filaments; // Holds available filament presets and their types & vendors Materials sla_materials; // Ditto for SLA materials std::unique_ptr custom_config; // Backing for custom printer definition bool any_fff_selected; // Used to decide whether to display Filaments page bool any_sla_selected; // Used to decide whether to display SLA Materials page wxScrolledWindow *hscroll = nullptr; wxBoxSizer *hscroll_sizer = nullptr; wxBoxSizer *btnsizer = nullptr; ConfigWizardPage *page_current = nullptr; ConfigWizardIndex *index = nullptr; wxButton *btn_sel_all = nullptr; wxButton *btn_prev = nullptr; wxButton *btn_next = nullptr; wxButton *btn_finish = nullptr; wxButton *btn_cancel = nullptr; PageWelcome *page_welcome = nullptr; PagePrinters *page_fff = nullptr; PagePrinters *page_msla = nullptr; PageMaterials *page_filaments = nullptr; PageMaterials *page_sla_materials = nullptr; PageCustom *page_custom = nullptr; PageUpdate *page_update = nullptr; PageMode *page_mode = nullptr; PageVendors *page_vendors = nullptr; Pages3rdparty pages_3rdparty; // Custom setup pages PageFirmware *page_firmware = nullptr; PageBedShape *page_bed = nullptr; PageDiameters *page_diams = nullptr; PageTemperatures *page_temps = nullptr; // Pointers to all pages (regardless or whether currently part of the ConfigWizardIndex) std::vector all_pages; priv(ConfigWizard *q) : q(q) , filaments(T_FFF) , sla_materials(T_SLA) , any_sla_selected(false) {} void load_pages(); void init_dialog_size(); void load_vendors(); void add_page(ConfigWizardPage *page); void enable_next(bool enable); void set_start_page(ConfigWizard::StartPage start_page); void create_3rdparty_pages(); void set_run_reason(RunReason run_reason); void update_materials(Technology technology); void on_custom_setup(); void on_printer_pick(PagePrinters *page, const PrinterPickerEvent &evt); void on_3rdparty_install(const VendorProfile *vendor, bool install); void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater); int em() const { return index->em(); } }; } } #endif