Add dedicated subclass NotificationProgressIndicator

to replace ProgressStatusBar and revert changes from b9dab754, keep UI jobs untouched
This commit is contained in:
tamasmeszaros 2021-09-21 12:34:40 +02:00
parent 7e3306c68f
commit 63647f594e
16 changed files with 161 additions and 99 deletions

View File

@ -179,6 +179,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Jobs/SLAImportJob.hpp GUI/Jobs/SLAImportJob.hpp
GUI/Jobs/SLAImportJob.cpp GUI/Jobs/SLAImportJob.cpp
GUI/Jobs/ProgressIndicator.hpp GUI/Jobs/ProgressIndicator.hpp
GUI/Jobs/NotificationProgressIndicator.hpp
GUI/Jobs/NotificationProgressIndicator.cpp
GUI/ProgressStatusBar.hpp GUI/ProgressStatusBar.hpp
GUI/ProgressStatusBar.cpp GUI/ProgressStatusBar.cpp
GUI/Mouse3DController.cpp GUI/Mouse3DController.cpp

View File

@ -2279,7 +2279,7 @@ wxBookCtrlBase* GUI_App::tab_panel() const
return mainframe->m_tabpanel; return mainframe->m_tabpanel;
} }
std::shared_ptr<NotificationManager> GUI_App::notification_manager() NotificationManager * GUI_App::notification_manager()
{ {
return plater_->get_notification_manager(); return plater_->get_notification_manager();
} }

View File

@ -275,7 +275,7 @@ public:
ObjectLayers* obj_layers(); ObjectLayers* obj_layers();
Plater* plater(); Plater* plater();
Model& model(); Model& model();
std::shared_ptr<NotificationManager> notification_manager(); NotificationManager * notification_manager();
// Parameters extracted from the command line to be passed to GUI after initialization. // Parameters extracted from the command line to be passed to GUI after initialization.
GUI_InitParams* init_params { nullptr }; GUI_InitParams* init_params { nullptr };

View File

@ -725,7 +725,7 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
double top_area = area(object->get_layer(int(object->layers().size()) - 1)->lslices); double top_area = area(object->get_layer(int(object->layers().size()) - 1)->lslices);
if( bottom_area - top_area > delta_area) { if( bottom_area - top_area > delta_area) {
std::shared_ptr<NotificationManager> notif_mngr = wxGetApp().plater()->get_notification_manager(); NotificationManager *notif_mngr = wxGetApp().plater()->get_notification_manager();
notif_mngr->push_notification( notif_mngr->push_notification(
NotificationType::SignDetected, NotificationManager::NotificationLevel::RegularNotificationLevel, NotificationType::SignDetected, NotificationManager::NotificationLevel::RegularNotificationLevel,
_u8L("NOTE:") + "\n" + _u8L("Sliced object looks like the sign") + "\n", _u8L("NOTE:") + "\n" + _u8L("Sliced object looks like the sign") + "\n",

View File

@ -9,7 +9,6 @@ namespace Slic3r {
class ModelInstance; class ModelInstance;
namespace GUI { namespace GUI {
class NotificationManager;
class ArrangeJob : public PlaterJob class ArrangeJob : public PlaterJob
{ {
@ -18,21 +17,21 @@ class ArrangeJob : public PlaterJob
ArrangePolygons m_selected, m_unselected, m_unprintable; ArrangePolygons m_selected, m_unselected, m_unprintable;
std::vector<ModelInstance*> m_unarranged; std::vector<ModelInstance*> m_unarranged;
// clear m_selected and m_unselected, reserve space for next usage // clear m_selected and m_unselected, reserve space for next usage
void clear_input(); void clear_input();
// Prepare all objects on the bed regardless of the selection // Prepare all objects on the bed regardless of the selection
void prepare_all(); void prepare_all();
// Prepare the selected and unselected items separately. If nothing is // Prepare the selected and unselected items separately. If nothing is
// selected, behaves as if everything would be selected. // selected, behaves as if everything would be selected.
void prepare_selected(); void prepare_selected();
ArrangePolygon get_arrange_poly_(ModelInstance *mi); ArrangePolygon get_arrange_poly_(ModelInstance *mi);
protected: protected:
void prepare() override; void prepare() override;
void on_exception(const std::exception_ptr &) override; void on_exception(const std::exception_ptr &) override;
@ -40,15 +39,15 @@ protected:
void process() override; void process() override;
public: public:
ArrangeJob(std::shared_ptr<NotificationManager> nm, Plater *plater) ArrangeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: PlaterJob{nm, plater} : PlaterJob{std::move(pri), plater}
{} {}
int status_range() const override int status_range() const override
{ {
return int(m_selected.size() + m_unprintable.size()); return int(m_selected.size() + m_unprintable.size());
} }
void finalize() override; void finalize() override;
}; };

View File

@ -6,7 +6,6 @@
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
class Plater; class Plater;
class NotificationManager;
class FillBedJob : public PlaterJob class FillBedJob : public PlaterJob
{ {
@ -28,8 +27,8 @@ protected:
void process() override; void process() override;
public: public:
FillBedJob(std::shared_ptr<NotificationManager> nm, Plater *plater) FillBedJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: PlaterJob{nm, plater} : PlaterJob{std::move(pri), plater}
{} {}
int status_range() const override int status_range() const override

View File

@ -2,11 +2,9 @@
#include <exception> #include <exception>
#include "Job.hpp" #include "Job.hpp"
#include "../NotificationManager.hpp"
#include <libslic3r/Thread.hpp> #include <libslic3r/Thread.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
namespace Slic3r { namespace Slic3r {
void GUI::Job::run(std::exception_ptr &eptr) void GUI::Job::run(std::exception_ptr &eptr)
@ -19,7 +17,7 @@ void GUI::Job::run(std::exception_ptr &eptr)
} }
m_running.store(false); m_running.store(false);
// ensure to call the last status to finalize the job // ensure to call the last status to finalize the job
update_status(status_range(), ""); update_status(status_range(), "");
} }
@ -32,8 +30,8 @@ void GUI::Job::update_status(int st, const wxString &msg)
wxQueueEvent(this, evt); wxQueueEvent(this, evt);
} }
GUI::Job::Job(std::shared_ptr<NotificationManager> nm) GUI::Job::Job(std::shared_ptr<ProgressIndicator> pri)
: m_notifications(nm) : m_progress(std::move(pri))
{ {
m_thread_evt_id = wxNewId(); m_thread_evt_id = wxNewId();
@ -42,21 +40,21 @@ GUI::Job::Job(std::shared_ptr<NotificationManager> nm)
auto msg = evt.GetString(); auto msg = evt.GetString();
if (!msg.empty() && !m_worker_error) if (!msg.empty() && !m_worker_error)
m_notifications->progress_indicator_set_status_text(msg.ToUTF8().data()); m_progress->set_status_text(msg.ToUTF8().data());
if (m_finalized) return; if (m_finalized) return;
m_notifications->progress_indicator_set_progress(evt.GetInt()); m_progress->set_progress(evt.GetInt());
if (evt.GetInt() == status_range() || m_worker_error) { if (evt.GetInt() == status_range() || m_worker_error) {
// set back the original range and cancel callback // set back the original range and cancel callback
m_notifications->progress_indicator_set_range(m_range); m_progress->set_range(m_range);
m_notifications->progress_indicator_set_cancel_callback(); m_progress->set_cancel_callback();
wxEndBusyCursor(); wxEndBusyCursor();
if (m_worker_error) { if (m_worker_error) {
m_finalized = true; m_finalized = true;
m_notifications->progress_indicator_set_status_text(""); m_progress->set_status_text("");
m_notifications->progress_indicator_set_progress(m_range); m_progress->set_progress(m_range);
on_exception(m_worker_error); on_exception(m_worker_error);
} }
else { else {
@ -86,22 +84,22 @@ void GUI::Job::start()
{ // Start the job. No effect if the job is already running { // Start the job. No effect if the job is already running
if (!m_running.load()) { if (!m_running.load()) {
prepare(); prepare();
// Save the current status indicatior range and push the new one // Save the current status indicatior range and push the new one
m_range = m_notifications->progress_indicator_get_range(); m_range = m_progress->get_range();
m_notifications->progress_indicator_set_range(status_range()); m_progress->set_range(status_range());
// init cancellation flag and set the cancel callback // init cancellation flag and set the cancel callback
m_canceled.store(false); m_canceled.store(false);
m_notifications->progress_indicator_set_cancel_callback( m_progress->set_cancel_callback(
[this]() { m_canceled.store(true); }); [this]() { m_canceled.store(true); });
m_finalized = false; m_finalized = false;
m_finalizing = false; m_finalizing = false;
// Changing cursor to busy // Changing cursor to busy
wxBeginBusyCursor(); wxBeginBusyCursor();
try { // Execute the job try { // Execute the job
m_worker_error = nullptr; m_worker_error = nullptr;
m_thread = create_thread([this] { this->run(m_worker_error); }); m_thread = create_thread([this] { this->run(m_worker_error); });
@ -110,7 +108,7 @@ void GUI::Job::start()
_(L("ERROR: not enough resources to " _(L("ERROR: not enough resources to "
"execute a new job."))); "execute a new job.")));
} }
// The state changes will be undone when the process hits the // The state changes will be undone when the process hits the
// last status value, in the status update handler (see ctor) // last status value, in the status update handler (see ctor)
} }
@ -119,12 +117,12 @@ void GUI::Job::start()
bool GUI::Job::join(int timeout_ms) bool GUI::Job::join(int timeout_ms)
{ {
if (!m_thread.joinable()) return true; if (!m_thread.joinable()) return true;
if (timeout_ms <= 0) if (timeout_ms <= 0)
m_thread.join(); m_thread.join();
else if (!m_thread.try_join_for(boost::chrono::milliseconds(timeout_ms))) else if (!m_thread.try_join_for(boost::chrono::milliseconds(timeout_ms)))
return false; return false;
return true; return true;
} }
@ -137,10 +135,10 @@ void GUI::ExclusiveJobGroup::start(size_t jid) {
void GUI::ExclusiveJobGroup::join_all(int wait_ms) void GUI::ExclusiveJobGroup::join_all(int wait_ms)
{ {
std::vector<bool> aborted(m_jobs.size(), false); std::vector<bool> aborted(m_jobs.size(), false);
for (size_t jid = 0; jid < m_jobs.size(); ++jid) for (size_t jid = 0; jid < m_jobs.size(); ++jid)
aborted[jid] = m_jobs[jid]->join(wait_ms); aborted[jid] = m_jobs[jid]->join(wait_ms);
if (!std::all_of(aborted.begin(), aborted.end(), [](bool t) { return t; })) if (!std::all_of(aborted.begin(), aborted.end(), [](bool t) { return t; }))
BOOST_LOG_TRIVIAL(error) << "Could not abort a job!"; BOOST_LOG_TRIVIAL(error) << "Could not abort a job!";
} }

View File

@ -8,13 +8,14 @@
#include <slic3r/GUI/I18N.hpp> #include <slic3r/GUI/I18N.hpp>
#include "ProgressIndicator.hpp"
#include <wx/event.h> #include <wx/event.h>
#include <boost/thread.hpp> #include <boost/thread.hpp>
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
class NotificationManager;
// A class to handle UI jobs like arranging and optimizing rotation. // A class to handle UI jobs like arranging and optimizing rotation.
// These are not instant jobs, the user has to be informed about their // These are not instant jobs, the user has to be informed about their
// state in the status progress indicator. On the other hand they are // state in the status progress indicator. On the other hand they are
@ -32,7 +33,7 @@ class Job : public wxEvtHandler
boost::thread m_thread; boost::thread m_thread;
std::atomic<bool> m_running{false}, m_canceled{false}; std::atomic<bool> m_running{false}, m_canceled{false};
bool m_finalized = false, m_finalizing = false; bool m_finalized = false, m_finalizing = false;
std::shared_ptr<NotificationManager> m_notifications; std::shared_ptr<ProgressIndicator> m_progress;
std::exception_ptr m_worker_error = nullptr; std::exception_ptr m_worker_error = nullptr;
void run(std::exception_ptr &); void run(std::exception_ptr &);
@ -64,7 +65,7 @@ protected:
} }
public: public:
Job(std::shared_ptr<NotificationManager> nm); Job(std::shared_ptr<ProgressIndicator> pri);
bool is_finalized() const { return m_finalized; } bool is_finalized() const { return m_finalized; }

View File

@ -0,0 +1,33 @@
#include "NotificationProgressIndicator.hpp"
#include "slic3r/GUI/NotificationManager.hpp"
namespace Slic3r { namespace GUI {
NotificationProgressIndicator::NotificationProgressIndicator(NotificationManager *nm): m_nm{nm} {}
void NotificationProgressIndicator::set_range(int range)
{
m_nm->progress_indicator_set_range(range);
}
void NotificationProgressIndicator::set_cancel_callback(CancelFn fn)
{
m_nm->progress_indicator_set_cancel_callback(std::move(fn));
}
void NotificationProgressIndicator::set_progress(int pr)
{
m_nm->progress_indicator_set_progress(pr);
}
void NotificationProgressIndicator::set_status_text(const char *msg)
{
m_nm->progress_indicator_set_status_text(msg);
}
int NotificationProgressIndicator::get_range() const
{
return m_nm->progress_indicator_get_range();
}
}} // namespace Slic3r::GUI

View File

@ -0,0 +1,26 @@
#ifndef NOTIFICATIONPROGRESSINDICATOR_HPP
#define NOTIFICATIONPROGRESSINDICATOR_HPP
#include "ProgressIndicator.hpp"
namespace Slic3r { namespace GUI {
class NotificationManager;
class NotificationProgressIndicator: public ProgressIndicator {
NotificationManager *m_nm = nullptr;
public:
explicit NotificationProgressIndicator(NotificationManager *nm);
void set_range(int range) override;
void set_cancel_callback(CancelFn = CancelFn()) override;
void set_progress(int pr) override;
void set_status_text(const char *) override; // utf8 char array
int get_range() const override;
};
}} // namespace Slic3r::GUI
#endif // NOTIFICATIONPROGRESSINDICATOR_HPP

View File

@ -6,7 +6,6 @@
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
class Plater; class Plater;
class NotificationManager;
class PlaterJob : public Job { class PlaterJob : public Job {
protected: protected:
@ -16,8 +15,8 @@ protected:
public: public:
PlaterJob(std::shared_ptr<NotificationManager> nm, Plater *plater): PlaterJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater):
Job{nm}, m_plater{plater} {} Job{std::move(pri)}, m_plater{plater} {}
}; };
}} // namespace Slic3r::GUI }} // namespace Slic3r::GUI

View File

@ -10,8 +10,6 @@ namespace Slic3r {
namespace GUI { namespace GUI {
class NotificationManager;
class RotoptimizeJob : public PlaterJob class RotoptimizeJob : public PlaterJob
{ {
using FindFn = std::function<Vec2d(const ModelObject & mo, using FindFn = std::function<Vec2d(const ModelObject & mo,
@ -54,8 +52,8 @@ protected:
public: public:
RotoptimizeJob(std::shared_ptr<NotificationManager> nm, Plater *plater) RotoptimizeJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: PlaterJob{nm, plater} : PlaterJob{std::move(pri), plater}
{} {}
void finalize() override; void finalize() override;

View File

@ -6,7 +6,6 @@
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/GUI_ObjectList.hpp" #include "slic3r/GUI/GUI_ObjectList.hpp"
#include "slic3r/GUI/NotificationManager.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
#include "libslic3r/PresetBundle.hpp" #include "libslic3r/PresetBundle.hpp"
@ -20,79 +19,79 @@
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
enum class Sel { modelAndProfile, profileOnly, modelOnly}; enum class Sel { modelAndProfile, profileOnly, modelOnly};
class ImportDlg: public wxDialog { class ImportDlg: public wxDialog {
wxFilePickerCtrl *m_filepicker; wxFilePickerCtrl *m_filepicker;
wxComboBox *m_import_dropdown, *m_quality_dropdown; wxComboBox *m_import_dropdown, *m_quality_dropdown;
public: public:
ImportDlg(Plater *plater) ImportDlg(Plater *plater)
: wxDialog{plater, wxID_ANY, "Import SLA archive"} : wxDialog{plater, wxID_ANY, "Import SLA archive"}
{ {
auto szvert = new wxBoxSizer{wxVERTICAL}; auto szvert = new wxBoxSizer{wxVERTICAL};
auto szfilepck = new wxBoxSizer{wxHORIZONTAL}; auto szfilepck = new wxBoxSizer{wxHORIZONTAL};
m_filepicker = new wxFilePickerCtrl(this, wxID_ANY, m_filepicker = new wxFilePickerCtrl(this, wxID_ANY,
from_u8(wxGetApp().app_config->get_last_dir()), _(L("Choose SLA archive:")), from_u8(wxGetApp().app_config->get_last_dir()), _(L("Choose SLA archive:")),
"SL1 / SL1S archive files (*.sl1, *.sl1s, *.zip)|*.sl1;*.SL1;*.sl1s;*.SL1S;*.zip;*.ZIP", "SL1 / SL1S archive files (*.sl1, *.sl1s, *.zip)|*.sl1;*.SL1;*.sl1s;*.SL1S;*.zip;*.ZIP",
wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE | wxFD_OPEN | wxFD_FILE_MUST_EXIST); wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE | wxFD_OPEN | wxFD_FILE_MUST_EXIST);
szfilepck->Add(new wxStaticText(this, wxID_ANY, _L("Import file") + ": "), 0, wxALIGN_CENTER); szfilepck->Add(new wxStaticText(this, wxID_ANY, _L("Import file") + ": "), 0, wxALIGN_CENTER);
szfilepck->Add(m_filepicker, 1); szfilepck->Add(m_filepicker, 1);
szvert->Add(szfilepck, 0, wxALL | wxEXPAND, 5); szvert->Add(szfilepck, 0, wxALL | wxEXPAND, 5);
auto szchoices = new wxBoxSizer{wxHORIZONTAL}; auto szchoices = new wxBoxSizer{wxHORIZONTAL};
static const std::vector<wxString> inp_choices = { static const std::vector<wxString> inp_choices = {
_(L("Import model and profile")), _(L("Import model and profile")),
_(L("Import profile only")), _(L("Import profile only")),
_(L("Import model only")) _(L("Import model only"))
}; };
m_import_dropdown = new wxComboBox( m_import_dropdown = new wxComboBox(
this, wxID_ANY, inp_choices[0], wxDefaultPosition, wxDefaultSize, this, wxID_ANY, inp_choices[0], wxDefaultPosition, wxDefaultSize,
inp_choices.size(), inp_choices.data(), wxCB_READONLY | wxCB_DROPDOWN); inp_choices.size(), inp_choices.data(), wxCB_READONLY | wxCB_DROPDOWN);
szchoices->Add(m_import_dropdown); szchoices->Add(m_import_dropdown);
szchoices->Add(new wxStaticText(this, wxID_ANY, _L("Quality") + ": "), 0, wxALIGN_CENTER | wxALL, 5); szchoices->Add(new wxStaticText(this, wxID_ANY, _L("Quality") + ": "), 0, wxALIGN_CENTER | wxALL, 5);
static const std::vector<wxString> qual_choices = { static const std::vector<wxString> qual_choices = {
_(L("Accurate")), _(L("Accurate")),
_(L("Balanced")), _(L("Balanced")),
_(L("Quick")) _(L("Quick"))
}; };
m_quality_dropdown = new wxComboBox( m_quality_dropdown = new wxComboBox(
this, wxID_ANY, qual_choices[0], wxDefaultPosition, wxDefaultSize, this, wxID_ANY, qual_choices[0], wxDefaultPosition, wxDefaultSize,
qual_choices.size(), qual_choices.data(), wxCB_READONLY | wxCB_DROPDOWN); qual_choices.size(), qual_choices.data(), wxCB_READONLY | wxCB_DROPDOWN);
szchoices->Add(m_quality_dropdown); szchoices->Add(m_quality_dropdown);
m_import_dropdown->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &) { m_import_dropdown->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &) {
if (get_selection() == Sel::profileOnly) if (get_selection() == Sel::profileOnly)
m_quality_dropdown->Disable(); m_quality_dropdown->Disable();
else m_quality_dropdown->Enable(); else m_quality_dropdown->Enable();
}); });
szvert->Add(szchoices, 0, wxALL, 5); szvert->Add(szchoices, 0, wxALL, 5);
szvert->AddStretchSpacer(1); szvert->AddStretchSpacer(1);
auto szbtn = new wxBoxSizer(wxHORIZONTAL); auto szbtn = new wxBoxSizer(wxHORIZONTAL);
szbtn->Add(new wxButton{this, wxID_CANCEL}); szbtn->Add(new wxButton{this, wxID_CANCEL});
szbtn->Add(new wxButton{this, wxID_OK}); szbtn->Add(new wxButton{this, wxID_OK});
szvert->Add(szbtn, 0, wxALIGN_RIGHT | wxALL, 5); szvert->Add(szbtn, 0, wxALIGN_RIGHT | wxALL, 5);
SetSizerAndFit(szvert); SetSizerAndFit(szvert);
} }
Sel get_selection() const Sel get_selection() const
{ {
int sel = m_import_dropdown->GetSelection(); int sel = m_import_dropdown->GetSelection();
return Sel(std::min(int(Sel::modelOnly), std::max(0, sel))); return Sel(std::min(int(Sel::modelOnly), std::max(0, sel)));
} }
Vec2i get_marchsq_windowsize() const Vec2i get_marchsq_windowsize() const
{ {
enum { Accurate, Balanced, Fast}; enum { Accurate, Balanced, Fast};
switch(m_quality_dropdown->GetSelection()) switch(m_quality_dropdown->GetSelection())
{ {
case Fast: return {8, 8}; case Fast: return {8, 8};
@ -102,7 +101,7 @@ public:
return {2, 2}; return {2, 2};
} }
} }
wxString get_path() const wxString get_path() const
{ {
return m_filepicker->GetPath(); return m_filepicker->GetPath();
@ -112,7 +111,7 @@ public:
class SLAImportJob::priv { class SLAImportJob::priv {
public: public:
Plater *plater; Plater *plater;
Sel sel = Sel::modelAndProfile; Sel sel = Sel::modelAndProfile;
indexed_triangle_set mesh; indexed_triangle_set mesh;
@ -125,8 +124,8 @@ public:
priv(Plater *plt) : plater{plt} {} priv(Plater *plt) : plater{plt} {}
}; };
SLAImportJob::SLAImportJob(std::shared_ptr<NotificationManager> nm, Plater *plater) SLAImportJob::SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: PlaterJob{nm, plater}, p{std::make_unique<priv>(plater)} : PlaterJob{std::move(pri), plater}, p{std::make_unique<priv>(plater)}
{} {}
SLAImportJob::~SLAImportJob() = default; SLAImportJob::~SLAImportJob() = default;
@ -138,9 +137,9 @@ void SLAImportJob::process()
update_status(int(s), _(L("Importing SLA archive"))); update_status(int(s), _(L("Importing SLA archive")));
return !was_canceled(); return !was_canceled();
}; };
if (p->path.empty()) return; if (p->path.empty()) return;
std::string path = p->path.ToUTF8().data(); std::string path = p->path.ToUTF8().data();
try { try {
switch (p->sel) { switch (p->sel) {
@ -154,11 +153,11 @@ void SLAImportJob::process()
p->config_substitutions = import_sla_archive(path, p->profile); p->config_substitutions = import_sla_archive(path, p->profile);
break; break;
} }
} catch (std::exception &ex) { } catch (std::exception &ex) {
p->err = ex.what(); p->err = ex.what();
} }
update_status(100, was_canceled() ? _(L("Importing canceled.")) : update_status(100, was_canceled() ? _(L("Importing canceled.")) :
_(L("Importing done."))); _(L("Importing done.")));
} }
@ -175,9 +174,9 @@ void SLAImportJob::reset()
void SLAImportJob::prepare() void SLAImportJob::prepare()
{ {
reset(); reset();
ImportDlg dlg{p->plater}; ImportDlg dlg{p->plater};
if (dlg.ShowModal() == wxID_OK) { if (dlg.ShowModal() == wxID_OK) {
auto path = dlg.get_path(); auto path = dlg.get_path();
auto nm = wxFileName(path); auto nm = wxFileName(path);
@ -194,15 +193,15 @@ void SLAImportJob::finalize()
{ {
// Ignore the arrange result if aborted. // Ignore the arrange result if aborted.
if (was_canceled()) return; if (was_canceled()) return;
if (!p->err.empty()) { if (!p->err.empty()) {
show_error(p->plater, p->err); show_error(p->plater, p->err);
p->err = ""; p->err = "";
return; return;
} }
std::string name = wxFileName(p->path).GetName().ToUTF8().data(); std::string name = wxFileName(p->path).GetName().ToUTF8().data();
if (!p->profile.empty()) { if (!p->profile.empty()) {
const ModelObjectPtrs& objects = p->plater->model().objects; const ModelObjectPtrs& objects = p->plater->model().objects;
for (auto object : objects) for (auto object : objects)
@ -214,15 +213,15 @@ void SLAImportJob::finalize()
_(L("Attention!")) ); _(L("Attention!")) );
return; return;
} }
DynamicPrintConfig config = {}; DynamicPrintConfig config = {};
config.apply(SLAFullPrintConfig::defaults()); config.apply(SLAFullPrintConfig::defaults());
config += std::move(p->profile); config += std::move(p->profile);
wxGetApp().preset_bundle->load_config_model(name, std::move(config)); wxGetApp().preset_bundle->load_config_model(name, std::move(config));
wxGetApp().load_current_presets(); wxGetApp().load_current_presets();
} }
if (!p->mesh.empty()) { if (!p->mesh.empty()) {
bool is_centered = false; bool is_centered = false;
p->plater->sidebar().obj_list()->load_mesh_object(TriangleMesh{p->mesh}, p->plater->sidebar().obj_list()->load_mesh_object(TriangleMesh{p->mesh},

View File

@ -5,20 +5,18 @@
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {
class NotificationManager;
class SLAImportJob : public PlaterJob { class SLAImportJob : public PlaterJob {
class priv; class priv;
std::unique_ptr<priv> p; std::unique_ptr<priv> p;
protected: protected:
void prepare() override; void prepare() override;
void process() override; void process() override;
void finalize() override; void finalize() override;
public: public:
SLAImportJob(std::shared_ptr<NotificationManager> nm, Plater *plater); SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater);
~SLAImportJob(); ~SLAImportJob();
void reset(); void reset();

View File

@ -67,8 +67,8 @@
#include "Jobs/FillBedJob.hpp" #include "Jobs/FillBedJob.hpp"
#include "Jobs/RotoptimizeJob.hpp" #include "Jobs/RotoptimizeJob.hpp"
#include "Jobs/SLAImportJob.hpp" #include "Jobs/SLAImportJob.hpp"
#include "Jobs/NotificationProgressIndicator.hpp"
#include "BackgroundSlicingProcess.hpp" #include "BackgroundSlicingProcess.hpp"
#include "ProgressStatusBar.hpp"
#include "PrintHostDialogs.hpp" #include "PrintHostDialogs.hpp"
#include "ConfigWizard.hpp" #include "ConfigWizard.hpp"
#include "../Utils/ASCIIFolding.hpp" #include "../Utils/ASCIIFolding.hpp"
@ -1499,7 +1499,7 @@ struct Plater::priv
GLToolbar view_toolbar; GLToolbar view_toolbar;
GLToolbar collapse_toolbar; GLToolbar collapse_toolbar;
Preview *preview; Preview *preview;
std::shared_ptr<NotificationManager> notification_manager; std::unique_ptr<NotificationManager> notification_manager;
ProjectDirtyStateManager dirty_state; ProjectDirtyStateManager dirty_state;
@ -1514,16 +1514,19 @@ struct Plater::priv
{ {
priv *m; priv *m;
size_t m_arrange_id, m_fill_bed_id, m_rotoptimize_id, m_sla_import_id; size_t m_arrange_id, m_fill_bed_id, m_rotoptimize_id, m_sla_import_id;
std::shared_ptr<NotificationProgressIndicator> m_pri;
void before_start() override { m->background_process.stop(); } void before_start() override { m->background_process.stop(); }
public: public:
Jobs(priv *_m) : m(_m) Jobs(priv *_m) :
m(_m),
m_pri{std::make_shared<NotificationProgressIndicator>(m->notification_manager.get())}
{ {
m_arrange_id = add_job(std::make_unique<ArrangeJob>(m->notification_manager, m->q)); m_arrange_id = add_job(std::make_unique<ArrangeJob>(m_pri, m->q));
m_fill_bed_id = add_job(std::make_unique<FillBedJob>(m->notification_manager, m->q)); m_fill_bed_id = add_job(std::make_unique<FillBedJob>(m_pri, m->q));
m_rotoptimize_id = add_job(std::make_unique<RotoptimizeJob>(m->notification_manager, m->q)); m_rotoptimize_id = add_job(std::make_unique<RotoptimizeJob>(m_pri, m->q));
m_sla_import_id = add_job(std::make_unique<SLAImportJob>(m->notification_manager, m->q)); m_sla_import_id = add_job(std::make_unique<SLAImportJob>(m_pri, m->q));
} }
void arrange() void arrange()
@ -1847,7 +1850,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
"support_material_contact_distance", "support_material_bottom_contact_distance", "raft_layers" "support_material_contact_distance", "support_material_bottom_contact_distance", "raft_layers"
})) }))
, sidebar(new Sidebar(q)) , sidebar(new Sidebar(q))
, notification_manager(std::make_shared<NotificationManager>(q)) , notification_manager(std::make_unique<NotificationManager>(q))
, m_ui_jobs(this) , m_ui_jobs(this)
, delayed_scene_refresh(false) , delayed_scene_refresh(false)
, view_toolbar(GLToolbar::Radio, "View") , view_toolbar(GLToolbar::Radio, "View")
@ -6640,9 +6643,14 @@ Mouse3DController& Plater::get_mouse3d_controller()
return p->mouse3d_controller; return p->mouse3d_controller;
} }
std::shared_ptr<NotificationManager> Plater::get_notification_manager() NotificationManager * Plater::get_notification_manager()
{ {
return p->notification_manager; return p->notification_manager.get();
}
const NotificationManager * Plater::get_notification_manager() const
{
return p->notification_manager.get();
} }
void Plater::init_notification_manager() void Plater::init_notification_manager()

View File

@ -358,7 +358,9 @@ public:
void set_bed_shape() const; void set_bed_shape() const;
void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const; void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const;
std::shared_ptr<NotificationManager> get_notification_manager(); NotificationManager * get_notification_manager();
const NotificationManager * get_notification_manager() const;
void init_notification_manager(); void init_notification_manager();
void bring_instance_forward(); void bring_instance_forward();