Merge branch 'tm_opencsg' into lm_tm_hollowing
This commit is contained in:
commit
9a0a4a5327
@ -117,8 +117,6 @@ add_library(libslic3r STATIC
|
|||||||
"${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h"
|
||||||
Line.cpp
|
Line.cpp
|
||||||
Line.hpp
|
Line.hpp
|
||||||
MeshBoolean.cpp
|
|
||||||
MeshBoolean.hpp
|
|
||||||
Model.cpp
|
Model.cpp
|
||||||
Model.hpp
|
Model.hpp
|
||||||
Arrange.hpp
|
Arrange.hpp
|
||||||
@ -220,6 +218,24 @@ add_library(libslic3r STATIC
|
|||||||
SLA/Clustering.hpp
|
SLA/Clustering.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (SLIC3R_STATIC)
|
||||||
|
set(CGAL_Boost_USE_STATIC_LIBS ON)
|
||||||
|
set(CGAL_DO_NOT_WARN_ABOUT_CMAKE_BUILD_TYPE TRUE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
find_package(CGAL REQUIRED)
|
||||||
|
|
||||||
|
add_library(libslic3r_cgal OBJECT MeshBoolean.cpp MeshBoolean.hpp)
|
||||||
|
target_include_directories(libslic3r_cgal PRIVATE
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
$<TARGET_PROPERTY:libigl,INTERFACE_INCLUDE_DIRECTORIES>
|
||||||
|
$<TARGET_PROPERTY:CGAL::CGAL,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||||
|
target_compile_definitions(libslic3r_cgal PRIVATE
|
||||||
|
$<TARGET_PROPERTY:CGAL::CGAL,INTERFACE_COMPILE_DEFINITIONS>)
|
||||||
|
target_compile_options(libslic3r_cgal PRIVATE
|
||||||
|
$<TARGET_PROPERTY:CGAL::CGAL,INTERFACE_COMPILE_OPTIONS>)
|
||||||
|
target_sources(libslic3r PRIVATE $<TARGET_OBJECTS:libslic3r_cgal>)
|
||||||
|
|
||||||
encoding_check(libslic3r)
|
encoding_check(libslic3r)
|
||||||
|
|
||||||
target_compile_definitions(libslic3r PUBLIC -DUSE_TBB -DTBB_USE_CAPTURED_EXCEPTION=0)
|
target_compile_definitions(libslic3r PUBLIC -DUSE_TBB -DTBB_USE_CAPTURED_EXCEPTION=0)
|
||||||
@ -240,6 +256,7 @@ target_link_libraries(libslic3r
|
|||||||
qhull
|
qhull
|
||||||
semver
|
semver
|
||||||
TBB::tbb
|
TBB::tbb
|
||||||
|
$<TARGET_PROPERTY:CGAL::CGAL,INTERFACE_LINK_LIBRARIES>
|
||||||
${CMAKE_DL_LIBS}
|
${CMAKE_DL_LIBS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ set(SLIC3R_GUI_SOURCES
|
|||||||
GUI/ProgressStatusBar.cpp
|
GUI/ProgressStatusBar.cpp
|
||||||
GUI/PrintHostDialogs.cpp
|
GUI/PrintHostDialogs.cpp
|
||||||
GUI/PrintHostDialogs.hpp
|
GUI/PrintHostDialogs.hpp
|
||||||
|
GUI/Job.hpp
|
||||||
GUI/Mouse3DController.cpp
|
GUI/Mouse3DController.cpp
|
||||||
GUI/Mouse3DController.hpp
|
GUI/Mouse3DController.hpp
|
||||||
Utils/Http.cpp
|
Utils/Http.cpp
|
||||||
@ -176,7 +177,7 @@ add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
|||||||
|
|
||||||
encoding_check(libslic3r_gui)
|
encoding_check(libslic3r_gui)
|
||||||
|
|
||||||
target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL OpenGL::GLU hidapi CGAL::CGAL)
|
target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL OpenGL::GLU hidapi)
|
||||||
if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
|
if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
|
||||||
add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
|
add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
|
||||||
endif ()
|
endif ()
|
||||||
|
154
src/slic3r/GUI/Job.hpp
Normal file
154
src/slic3r/GUI/Job.hpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
#ifndef JOB_HPP
|
||||||
|
#define JOB_HPP
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
#include <slic3r/Utils/Thread.hpp>
|
||||||
|
#include <slic3r/GUI/I18N.hpp>
|
||||||
|
#include <slic3r/GUI/ProgressIndicator.hpp>
|
||||||
|
|
||||||
|
#include <wx/event.h>
|
||||||
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
|
// A class to handle UI jobs like arranging and optimizing rotation.
|
||||||
|
// 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
|
||||||
|
// separated from the background slicing process. Ideally, these jobs should
|
||||||
|
// run when the background process is not running.
|
||||||
|
//
|
||||||
|
// TODO: A mechanism would be useful for blocking the plater interactions:
|
||||||
|
// objects would be frozen for the user. In case of arrange, an animation
|
||||||
|
// could be shown, or with the optimize orientations, partial results
|
||||||
|
// could be displayed.
|
||||||
|
class Job : public wxEvtHandler
|
||||||
|
{
|
||||||
|
int m_range = 100;
|
||||||
|
boost::thread m_thread;
|
||||||
|
std::atomic<bool> m_running{false}, m_canceled{false};
|
||||||
|
bool m_finalized = false;
|
||||||
|
std::shared_ptr<ProgressIndicator> m_progress;
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
m_running.store(true);
|
||||||
|
process();
|
||||||
|
m_running.store(false);
|
||||||
|
|
||||||
|
// ensure to call the last status to finalize the job
|
||||||
|
update_status(status_range(), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// status range for a particular job
|
||||||
|
virtual int status_range() const { return 100; }
|
||||||
|
|
||||||
|
// status update, to be used from the work thread (process() method)
|
||||||
|
void update_status(int st, const wxString &msg = "")
|
||||||
|
{
|
||||||
|
auto evt = new wxThreadEvent();
|
||||||
|
evt->SetInt(st);
|
||||||
|
evt->SetString(msg);
|
||||||
|
wxQueueEvent(this, evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool was_canceled() const { return m_canceled.load(); }
|
||||||
|
|
||||||
|
// Launched just before start(), a job can use it to prepare internals
|
||||||
|
virtual void prepare() {}
|
||||||
|
|
||||||
|
// Launched when the job is finished. It refreshes the 3Dscene by def.
|
||||||
|
virtual void finalize() { m_finalized = true; }
|
||||||
|
|
||||||
|
bool is_finalized() const { return m_finalized; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
Job(std::shared_ptr<ProgressIndicator> pri) : m_progress(pri)
|
||||||
|
{
|
||||||
|
Bind(wxEVT_THREAD, [this](const wxThreadEvent &evt) {
|
||||||
|
auto msg = evt.GetString();
|
||||||
|
if (!msg.empty())
|
||||||
|
m_progress->set_status_text(msg.ToUTF8().data());
|
||||||
|
|
||||||
|
if (m_finalized) return;
|
||||||
|
|
||||||
|
m_progress->set_progress(evt.GetInt());
|
||||||
|
if (evt.GetInt() == status_range()) {
|
||||||
|
// set back the original range and cancel callback
|
||||||
|
m_progress->set_range(m_range);
|
||||||
|
m_progress->set_cancel_callback();
|
||||||
|
wxEndBusyCursor();
|
||||||
|
|
||||||
|
finalize();
|
||||||
|
|
||||||
|
// dont do finalization again for the same process
|
||||||
|
m_finalized = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Job(const Job &) = delete;
|
||||||
|
Job(Job &&) = delete;
|
||||||
|
Job &operator=(const Job &) = delete;
|
||||||
|
Job &operator=(Job &&) = delete;
|
||||||
|
|
||||||
|
virtual void process() = 0;
|
||||||
|
|
||||||
|
void start()
|
||||||
|
{ // Start the job. No effect if the job is already running
|
||||||
|
if (!m_running.load()) {
|
||||||
|
prepare();
|
||||||
|
|
||||||
|
// Save the current status indicatior range and push the new one
|
||||||
|
m_range = m_progress->get_range();
|
||||||
|
m_progress->set_range(status_range());
|
||||||
|
|
||||||
|
// init cancellation flag and set the cancel callback
|
||||||
|
m_canceled.store(false);
|
||||||
|
m_progress->set_cancel_callback(
|
||||||
|
[this]() { m_canceled.store(true); });
|
||||||
|
|
||||||
|
m_finalized = false;
|
||||||
|
|
||||||
|
// Changing cursor to busy
|
||||||
|
wxBeginBusyCursor();
|
||||||
|
|
||||||
|
try { // Execute the job
|
||||||
|
m_thread = create_thread([this] { this->run(); });
|
||||||
|
} catch (std::exception &) {
|
||||||
|
update_status(status_range(),
|
||||||
|
_(L("ERROR: not enough resources to "
|
||||||
|
"execute a new job.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The state changes will be undone when the process hits the
|
||||||
|
// last status value, in the status update handler (see ctor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// To wait for the running job and join the threads. False is
|
||||||
|
// returned if the timeout has been reached and the job is still
|
||||||
|
// running. Call cancel() before this fn if you want to explicitly
|
||||||
|
// end the job.
|
||||||
|
bool join(int timeout_ms = 0)
|
||||||
|
{
|
||||||
|
if (!m_thread.joinable()) return true;
|
||||||
|
|
||||||
|
if (timeout_ms <= 0)
|
||||||
|
m_thread.join();
|
||||||
|
else if (!m_thread.try_join_for(boost::chrono::milliseconds(timeout_ms)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_running() const { return m_running.load(); }
|
||||||
|
void cancel() { m_canceled.store(true); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // JOB_HPP
|
@ -58,7 +58,8 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
|||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
// initialize status bar
|
// initialize status bar
|
||||||
m_statusbar.reset(new ProgressStatusBar(this));
|
m_statusbar = std::make_shared<ProgressStatusBar>(this);
|
||||||
|
m_statusbar->set_font(GUI::wxGetApp().normal_font());
|
||||||
m_statusbar->embed(this);
|
m_statusbar->embed(this);
|
||||||
m_statusbar->set_status_text(_(L("Version")) + " " +
|
m_statusbar->set_status_text(_(L("Version")) + " " +
|
||||||
SLIC3R_VERSION +
|
SLIC3R_VERSION +
|
||||||
|
@ -135,7 +135,7 @@ public:
|
|||||||
Plater* m_plater { nullptr };
|
Plater* m_plater { nullptr };
|
||||||
wxNotebook* m_tabpanel { nullptr };
|
wxNotebook* m_tabpanel { nullptr };
|
||||||
wxProgressDialog* m_progress_dialog { nullptr };
|
wxProgressDialog* m_progress_dialog { nullptr };
|
||||||
std::unique_ptr<ProgressStatusBar> m_statusbar;
|
std::shared_ptr<ProgressStatusBar> m_statusbar;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // GUI
|
} // GUI
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
#include "Camera.hpp"
|
#include "Camera.hpp"
|
||||||
#include "Mouse3DController.hpp"
|
#include "Mouse3DController.hpp"
|
||||||
#include "Tab.hpp"
|
#include "Tab.hpp"
|
||||||
|
#include "Job.hpp"
|
||||||
#include "PresetBundle.hpp"
|
#include "PresetBundle.hpp"
|
||||||
#include "BackgroundSlicingProcess.hpp"
|
#include "BackgroundSlicingProcess.hpp"
|
||||||
#include "ProgressStatusBar.hpp"
|
#include "ProgressStatusBar.hpp"
|
||||||
@ -1457,136 +1458,30 @@ struct Plater::priv
|
|||||||
// objects would be frozen for the user. In case of arrange, an animation
|
// objects would be frozen for the user. In case of arrange, an animation
|
||||||
// could be shown, or with the optimize orientations, partial results
|
// could be shown, or with the optimize orientations, partial results
|
||||||
// could be displayed.
|
// could be displayed.
|
||||||
class Job : public wxEvtHandler
|
class PlaterJob: public Job
|
||||||
{
|
{
|
||||||
int m_range = 100;
|
priv *m_plater;
|
||||||
boost::thread m_thread;
|
|
||||||
priv * m_plater = nullptr;
|
|
||||||
std::atomic<bool> m_running{false}, m_canceled{false};
|
|
||||||
bool m_finalized = false;
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
m_running.store(true);
|
|
||||||
process();
|
|
||||||
m_running.store(false);
|
|
||||||
|
|
||||||
// ensure to call the last status to finalize the job
|
|
||||||
update_status(status_range(), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// status range for a particular job
|
|
||||||
virtual int status_range() const { return 100; }
|
|
||||||
|
|
||||||
// status update, to be used from the work thread (process() method)
|
|
||||||
void update_status(int st, const wxString &msg = "")
|
|
||||||
{
|
|
||||||
auto evt = new wxThreadEvent();
|
|
||||||
evt->SetInt(st);
|
|
||||||
evt->SetString(msg);
|
|
||||||
wxQueueEvent(this, evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
priv & plater() { return *m_plater; }
|
priv & plater() { return *m_plater; }
|
||||||
const priv &plater() const { return *m_plater; }
|
const priv &plater() const { return *m_plater; }
|
||||||
bool was_canceled() const { return m_canceled.load(); }
|
|
||||||
|
|
||||||
// Launched just before start(), a job can use it to prepare internals
|
|
||||||
virtual void prepare() {}
|
|
||||||
|
|
||||||
// Launched when the job is finished. It refreshes the 3Dscene by def.
|
// Launched when the job is finished. It refreshes the 3Dscene by def.
|
||||||
virtual void finalize()
|
void finalize() override
|
||||||
{
|
{
|
||||||
// Do a full refresh of scene tree, including regenerating
|
// Do a full refresh of scene tree, including regenerating
|
||||||
// all the GLVolumes. FIXME The update function shall just
|
// all the GLVolumes. FIXME The update function shall just
|
||||||
// reload the modified matrices.
|
// reload the modified matrices.
|
||||||
if (!was_canceled())
|
if (!Job::was_canceled())
|
||||||
plater().update(unsigned(UpdateParams::FORCE_FULL_SCREEN_REFRESH));
|
plater().update(unsigned(UpdateParams::FORCE_FULL_SCREEN_REFRESH));
|
||||||
|
|
||||||
|
Job::finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Job(priv *_plater) : m_plater(_plater)
|
PlaterJob(priv *_plater)
|
||||||
{
|
: Job(_plater->statusbar()), m_plater(_plater)
|
||||||
Bind(wxEVT_THREAD, [this](const wxThreadEvent &evt) {
|
{}
|
||||||
auto msg = evt.GetString();
|
|
||||||
if (!msg.empty())
|
|
||||||
plater().statusbar()->set_status_text(msg);
|
|
||||||
|
|
||||||
if (m_finalized) return;
|
|
||||||
|
|
||||||
plater().statusbar()->set_progress(evt.GetInt());
|
|
||||||
if (evt.GetInt() == status_range()) {
|
|
||||||
// set back the original range and cancel callback
|
|
||||||
plater().statusbar()->set_range(m_range);
|
|
||||||
plater().statusbar()->set_cancel_callback();
|
|
||||||
wxEndBusyCursor();
|
|
||||||
|
|
||||||
finalize();
|
|
||||||
|
|
||||||
// dont do finalization again for the same process
|
|
||||||
m_finalized = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Job(const Job &) = delete;
|
|
||||||
Job(Job &&) = delete;
|
|
||||||
Job &operator=(const Job &) = delete;
|
|
||||||
Job &operator=(Job &&) = delete;
|
|
||||||
|
|
||||||
virtual void process() = 0;
|
|
||||||
|
|
||||||
void start()
|
|
||||||
{ // Start the job. No effect if the job is already running
|
|
||||||
if (!m_running.load()) {
|
|
||||||
prepare();
|
|
||||||
|
|
||||||
// Save the current status indicatior range and push the new one
|
|
||||||
m_range = plater().statusbar()->get_range();
|
|
||||||
plater().statusbar()->set_range(status_range());
|
|
||||||
|
|
||||||
// init cancellation flag and set the cancel callback
|
|
||||||
m_canceled.store(false);
|
|
||||||
plater().statusbar()->set_cancel_callback(
|
|
||||||
[this]() { m_canceled.store(true); });
|
|
||||||
|
|
||||||
m_finalized = false;
|
|
||||||
|
|
||||||
// Changing cursor to busy
|
|
||||||
wxBeginBusyCursor();
|
|
||||||
|
|
||||||
try { // Execute the job
|
|
||||||
m_thread = create_thread([this] { this->run(); });
|
|
||||||
} catch (std::exception &) {
|
|
||||||
update_status(status_range(),
|
|
||||||
_(L("ERROR: not enough resources to "
|
|
||||||
"execute a new job.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// The state changes will be undone when the process hits the
|
|
||||||
// last status value, in the status update handler (see ctor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// To wait for the running job and join the threads. False is
|
|
||||||
// returned if the timeout has been reached and the job is still
|
|
||||||
// running. Call cancel() before this fn if you want to explicitly
|
|
||||||
// end the job.
|
|
||||||
bool join(int timeout_ms = 0)
|
|
||||||
{
|
|
||||||
if (!m_thread.joinable()) return true;
|
|
||||||
|
|
||||||
if (timeout_ms <= 0)
|
|
||||||
m_thread.join();
|
|
||||||
else if (!m_thread.try_join_for(boost::chrono::milliseconds(timeout_ms)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_running() const { return m_running.load(); }
|
|
||||||
void cancel() { m_canceled.store(true); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Jobs : size_t {
|
enum class Jobs : size_t {
|
||||||
@ -1595,7 +1490,7 @@ struct Plater::priv
|
|||||||
Hollow
|
Hollow
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrangeJob : public Job
|
class ArrangeJob : public PlaterJob
|
||||||
{
|
{
|
||||||
using ArrangePolygon = arrangement::ArrangePolygon;
|
using ArrangePolygon = arrangement::ArrangePolygon;
|
||||||
using ArrangePolygons = arrangement::ArrangePolygons;
|
using ArrangePolygons = arrangement::ArrangePolygons;
|
||||||
@ -1712,7 +1607,7 @@ struct Plater::priv
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Job::Job;
|
using PlaterJob::PlaterJob;
|
||||||
|
|
||||||
int status_range() const override { return int(m_selected.size()); }
|
int status_range() const override { return int(m_selected.size()); }
|
||||||
|
|
||||||
@ -1729,17 +1624,17 @@ struct Plater::priv
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RotoptimizeJob : public Job
|
class RotoptimizeJob : public PlaterJob
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Job::Job;
|
using PlaterJob::PlaterJob;
|
||||||
void process() override;
|
void process() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HollowJob : public Job
|
class HollowJob : public PlaterJob
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Job::Job;
|
using PlaterJob::PlaterJob;
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
void process() override;
|
void process() override;
|
||||||
void finalize() override;
|
void finalize() override;
|
||||||
@ -1847,7 +1742,7 @@ struct Plater::priv
|
|||||||
|
|
||||||
void reset_all_gizmos();
|
void reset_all_gizmos();
|
||||||
void update_ui_from_settings();
|
void update_ui_from_settings();
|
||||||
ProgressStatusBar* statusbar();
|
std::shared_ptr<ProgressStatusBar> statusbar();
|
||||||
std::string get_config(const std::string &key) const;
|
std::string get_config(const std::string &key) const;
|
||||||
BoundingBoxf bed_shape_bb() const;
|
BoundingBoxf bed_shape_bb() const;
|
||||||
BoundingBox scaled_bed_shape_bb() const;
|
BoundingBox scaled_bed_shape_bb() const;
|
||||||
@ -2266,9 +2161,9 @@ void Plater::priv::update_ui_from_settings()
|
|||||||
preview->get_canvas3d()->update_ui_from_settings();
|
preview->get_canvas3d()->update_ui_from_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressStatusBar* Plater::priv::statusbar()
|
std::shared_ptr<ProgressStatusBar> Plater::priv::statusbar()
|
||||||
{
|
{
|
||||||
return main_frame->m_statusbar.get();
|
return main_frame->m_statusbar;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Plater::priv::get_config(const std::string &key) const
|
std::string Plater::priv::get_config(const std::string &key) const
|
||||||
|
@ -11,58 +11,17 @@ namespace Slic3r {
|
|||||||
*/
|
*/
|
||||||
class ProgressIndicator {
|
class ProgressIndicator {
|
||||||
public:
|
public:
|
||||||
using CancelFn = std::function<void(void)>; // Cancel function signature.
|
|
||||||
|
/// Cancel callback function type
|
||||||
private:
|
using CancelFn = std::function<void()>;
|
||||||
float m_state = .0f, m_max = 1.f, m_step;
|
|
||||||
CancelFn m_cancelfunc = [](){};
|
virtual ~ProgressIndicator() = default;
|
||||||
|
|
||||||
public:
|
virtual void set_range(int range) = 0;
|
||||||
|
virtual void set_cancel_callback(CancelFn = CancelFn()) = 0;
|
||||||
inline virtual ~ProgressIndicator() {}
|
virtual void set_progress(int pr) = 0;
|
||||||
|
virtual void set_status_text(const char *) = 0; // utf8 char array
|
||||||
/// Get the maximum of the progress range.
|
virtual int get_range() const = 0;
|
||||||
float max() const { return m_max; }
|
|
||||||
|
|
||||||
/// Get the current progress state
|
|
||||||
float state() const { return m_state; }
|
|
||||||
|
|
||||||
/// Set the maximum of the progress range
|
|
||||||
virtual void max(float maxval) { m_max = maxval; }
|
|
||||||
|
|
||||||
/// Set the current state of the progress.
|
|
||||||
virtual void state(float val) { m_state = val; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Number of states int the progress. Can be used instead of giving a
|
|
||||||
* maximum value.
|
|
||||||
*/
|
|
||||||
virtual void states(unsigned statenum) {
|
|
||||||
m_step = m_max / statenum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Message shown on the next status update.
|
|
||||||
virtual void message(const std::string&) = 0;
|
|
||||||
|
|
||||||
/// Title of the operation.
|
|
||||||
virtual void title(const std::string&) = 0;
|
|
||||||
|
|
||||||
/// Formatted message for the next status update. Works just like sprintf.
|
|
||||||
virtual void message_fmt(const std::string& fmt, ...);
|
|
||||||
|
|
||||||
/// Set up a cancel callback for the operation if feasible.
|
|
||||||
virtual void on_cancel(CancelFn func = CancelFn()) { m_cancelfunc = func; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Explicitly shut down the progress indicator and call the associated
|
|
||||||
* callback.
|
|
||||||
*/
|
|
||||||
virtual void cancel() { m_cancelfunc(); }
|
|
||||||
|
|
||||||
/// Convenience function to call message and status update in one function.
|
|
||||||
void update(float st, const std::string& msg) {
|
|
||||||
message(msg); state(st);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
ProgressStatusBar::ProgressStatusBar(wxWindow *parent, int id)
|
ProgressStatusBar::ProgressStatusBar(wxWindow *parent, int id)
|
||||||
: self{new wxStatusBar(parent ? parent : GUI::wxGetApp().mainframe,
|
: self{new wxStatusBar(parent, id == -1 ? wxID_ANY : id)}
|
||||||
id == -1 ? wxID_ANY : id)}
|
|
||||||
, m_prog{new wxGauge(self,
|
, m_prog{new wxGauge(self,
|
||||||
wxGA_HORIZONTAL,
|
wxGA_HORIZONTAL,
|
||||||
100,
|
100,
|
||||||
@ -32,7 +31,6 @@ ProgressStatusBar::ProgressStatusBar(wxWindow *parent, int id)
|
|||||||
m_prog->Hide();
|
m_prog->Hide();
|
||||||
m_cancelbutton->Hide();
|
m_cancelbutton->Hide();
|
||||||
|
|
||||||
self->SetFont(GUI::wxGetApp().normal_font());
|
|
||||||
self->SetFieldsCount(3);
|
self->SetFieldsCount(3);
|
||||||
int w[] = {-1, 150, 155};
|
int w[] = {-1, 150, 155};
|
||||||
self->SetStatusWidths(3, w);
|
self->SetStatusWidths(3, w);
|
||||||
@ -149,8 +147,7 @@ void ProgressStatusBar::run(int rate)
|
|||||||
|
|
||||||
void ProgressStatusBar::embed(wxFrame *frame)
|
void ProgressStatusBar::embed(wxFrame *frame)
|
||||||
{
|
{
|
||||||
wxFrame* mf = frame ? frame : GUI::wxGetApp().mainframe;
|
if(frame) frame->SetStatusBar(self);
|
||||||
if(mf) mf->SetStatusBar(self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgressStatusBar::set_status_text(const wxString& txt)
|
void ProgressStatusBar::set_status_text(const wxString& txt)
|
||||||
@ -173,6 +170,11 @@ wxString ProgressStatusBar::get_status_text() const
|
|||||||
return self->GetStatusText();
|
return self->GetStatusText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProgressStatusBar::set_font(const wxFont &font)
|
||||||
|
{
|
||||||
|
self->SetFont(font);
|
||||||
|
}
|
||||||
|
|
||||||
void ProgressStatusBar::show_cancel_button()
|
void ProgressStatusBar::show_cancel_button()
|
||||||
{
|
{
|
||||||
if(m_cancelbutton) m_cancelbutton->Show();
|
if(m_cancelbutton) m_cancelbutton->Show();
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "ProgressIndicator.hpp"
|
||||||
|
|
||||||
class wxTimer;
|
class wxTimer;
|
||||||
class wxGauge;
|
class wxGauge;
|
||||||
class wxButton;
|
class wxButton;
|
||||||
@ -14,6 +16,7 @@ class wxStatusBar;
|
|||||||
class wxWindow;
|
class wxWindow;
|
||||||
class wxFrame;
|
class wxFrame;
|
||||||
class wxString;
|
class wxString;
|
||||||
|
class wxFont;
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
@ -22,7 +25,7 @@ namespace Slic3r {
|
|||||||
* of the Slicer main window. It consists of a message area to the left and a
|
* of the Slicer main window. It consists of a message area to the left and a
|
||||||
* progress indication area to the right with an optional cancel button.
|
* progress indication area to the right with an optional cancel button.
|
||||||
*/
|
*/
|
||||||
class ProgressStatusBar
|
class ProgressStatusBar : public ProgressIndicator
|
||||||
{
|
{
|
||||||
wxStatusBar *self; // we cheat! It should be the base class but: perl!
|
wxStatusBar *self; // we cheat! It should be the base class but: perl!
|
||||||
wxGauge *m_prog;
|
wxGauge *m_prog;
|
||||||
@ -30,30 +33,29 @@ class ProgressStatusBar
|
|||||||
std::unique_ptr<wxTimer> m_timer;
|
std::unique_ptr<wxTimer> m_timer;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Cancel callback function type
|
|
||||||
using CancelFn = std::function<void()>;
|
|
||||||
|
|
||||||
ProgressStatusBar(wxWindow *parent = nullptr, int id = -1);
|
ProgressStatusBar(wxWindow *parent = nullptr, int id = -1);
|
||||||
~ProgressStatusBar();
|
~ProgressStatusBar() override;
|
||||||
|
|
||||||
int get_progress() const;
|
int get_progress() const;
|
||||||
// if the argument is less than 0 it shows the last state or
|
// if the argument is less than 0 it shows the last state or
|
||||||
// pulses if no state was set before.
|
// pulses if no state was set before.
|
||||||
void set_progress(int);
|
void set_progress(int) override;
|
||||||
int get_range() const;
|
int get_range() const override;
|
||||||
void set_range(int = 100);
|
void set_range(int = 100) override;
|
||||||
void show_progress(bool);
|
void show_progress(bool);
|
||||||
void start_busy(int = 100);
|
void start_busy(int = 100);
|
||||||
void stop_busy();
|
void stop_busy();
|
||||||
inline bool is_busy() const { return m_busy; }
|
inline bool is_busy() const { return m_busy; }
|
||||||
void set_cancel_callback(CancelFn = CancelFn());
|
void set_cancel_callback(CancelFn = CancelFn()) override;
|
||||||
inline void reset_cancel_callback() { set_cancel_callback(); }
|
inline void reset_cancel_callback() { set_cancel_callback(); }
|
||||||
void run(int rate);
|
void run(int rate);
|
||||||
void embed(wxFrame *frame = nullptr);
|
void embed(wxFrame *frame = nullptr);
|
||||||
void set_status_text(const wxString& txt);
|
void set_status_text(const wxString& txt);
|
||||||
void set_status_text(const std::string& txt);
|
void set_status_text(const std::string& txt);
|
||||||
void set_status_text(const char *txt);
|
void set_status_text(const char *txt) override;
|
||||||
wxString get_status_text() const;
|
wxString get_status_text() const;
|
||||||
|
void set_font(const wxFont &font);
|
||||||
|
|
||||||
// Temporary methods to satisfy Perl side
|
// Temporary methods to satisfy Perl side
|
||||||
void show_cancel_button();
|
void show_cancel_button();
|
||||||
|
Loading…
Reference in New Issue
Block a user