Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/xs
diff options
context:
space:
mode:
authortamasmeszaros <meszaros.q@gmail.com>2018-09-19 19:02:04 +0300
committertamasmeszaros <meszaros.q@gmail.com>2018-09-19 19:02:04 +0300
commit2306c1589a816dbda8ede8620842f0f6b24c8e8a (patch)
treefc611a6a5246243855aaccc295df4dfb31742635 /xs
parentc9acd1252aa59236ed4a76edc73f29379e5c8e32 (diff)
Polymorphic AppController for cli and gui modes.
Diffstat (limited to 'xs')
-rw-r--r--xs/src/libslic3r/ModelArrange.hpp155
-rw-r--r--xs/src/slic3r/AppController.cpp50
-rw-r--r--xs/src/slic3r/AppController.hpp217
-rw-r--r--xs/src/slic3r/AppControllerWx.cpp57
-rw-r--r--xs/src/slic3r/GUI/GUI.cpp20
-rw-r--r--xs/src/slic3r/GUI/GUI.hpp7
-rw-r--r--xs/xsp/GUI.xsp6
7 files changed, 330 insertions, 182 deletions
diff --git a/xs/src/libslic3r/ModelArrange.hpp b/xs/src/libslic3r/ModelArrange.hpp
index 372689c39..4b91131ed 100644
--- a/xs/src/libslic3r/ModelArrange.hpp
+++ b/xs/src/libslic3r/ModelArrange.hpp
@@ -292,59 +292,59 @@ protected:
using Distance = TCoord<PointImpl>;
using Pile = sl::Shapes<PolygonImpl>;
- Packer pck_;
- PConfig pconf_; // Placement configuration
- double bin_area_;
- SpatIndex rtree_;
- SpatIndex smallsrtree_;
- double norm_;
- Pile merged_pile_;
- Box pilebb_;
- ItemGroup remaining_;
- ItemGroup items_;
+ Packer m_pck;
+ PConfig m_pconf; // Placement configuration
+ double m_bin_area;
+ SpatIndex m_rtree;
+ SpatIndex m_smallsrtree;
+ double m_norm;
+ Pile m_merged_pile;
+ Box m_pilebb;
+ ItemGroup m_remaining;
+ ItemGroup m_items;
public:
_ArrBase(const TBin& bin, Distance dist,
std::function<void(unsigned)> progressind,
std::function<bool(void)> stopcond):
- pck_(bin, dist), bin_area_(sl::area(bin)),
- norm_(std::sqrt(sl::area(bin)))
+ m_pck(bin, dist), m_bin_area(sl::area(bin)),
+ m_norm(std::sqrt(sl::area(bin)))
{
- fillConfig(pconf_);
+ fillConfig(m_pconf);
- pconf_.before_packing =
+ m_pconf.before_packing =
[this](const Pile& merged_pile, // merged pile
const ItemGroup& items, // packed items
const ItemGroup& remaining) // future items to be packed
{
- items_ = items;
- merged_pile_ = merged_pile;
- remaining_ = remaining;
+ m_items = items;
+ m_merged_pile = merged_pile;
+ m_remaining = remaining;
- pilebb_ = sl::boundingBox(merged_pile);
+ m_pilebb = sl::boundingBox(merged_pile);
- rtree_.clear();
- smallsrtree_.clear();
+ m_rtree.clear();
+ m_smallsrtree.clear();
// We will treat big items (compared to the print bed) differently
auto isBig = [this](double a) {
- return a/bin_area_ > BIG_ITEM_TRESHOLD ;
+ return a/m_bin_area > BIG_ITEM_TRESHOLD ;
};
for(unsigned idx = 0; idx < items.size(); ++idx) {
Item& itm = items[idx];
- if(isBig(itm.area())) rtree_.insert({itm.boundingBox(), idx});
- smallsrtree_.insert({itm.boundingBox(), idx});
+ if(isBig(itm.area())) m_rtree.insert({itm.boundingBox(), idx});
+ m_smallsrtree.insert({itm.boundingBox(), idx});
}
};
- pck_.progressIndicator(progressind);
- pck_.stopCondition(stopcond);
+ m_pck.progressIndicator(progressind);
+ m_pck.stopCondition(stopcond);
}
template<class...Args> inline IndexedPackGroup operator()(Args&&...args) {
- rtree_.clear();
- return pck_.executeIndexed(std::forward<Args>(args)...);
+ m_rtree.clear();
+ return m_pck.executeIndexed(std::forward<Args>(args)...);
}
};
@@ -358,18 +358,18 @@ public:
_ArrBase<Box>(bin, dist, progressind, stopcond)
{
- pconf_.object_function = [this, bin] (const Item &item) {
+ m_pconf.object_function = [this, bin] (const Item &item) {
auto result = objfunc(bin.center(),
- merged_pile_,
- pilebb_,
- items_,
+ m_merged_pile,
+ m_pilebb,
+ m_items,
item,
- bin_area_,
- norm_,
- rtree_,
- smallsrtree_,
- remaining_);
+ m_bin_area,
+ m_norm,
+ m_rtree,
+ m_smallsrtree,
+ m_remaining);
double score = std::get<0>(result);
auto& fullbb = std::get<1>(result);
@@ -381,7 +381,7 @@ public:
return score;
};
- pck_.configure(pconf_);
+ m_pck.configure(m_pconf);
}
};
@@ -396,27 +396,27 @@ public:
std::function<bool(void)> stopcond):
_ArrBase<lnCircle>(bin, dist, progressind, stopcond) {
- pconf_.object_function = [this, &bin] (const Item &item) {
+ m_pconf.object_function = [this, &bin] (const Item &item) {
auto result = objfunc(bin.center(),
- merged_pile_,
- pilebb_,
- items_,
+ m_merged_pile,
+ m_pilebb,
+ m_items,
item,
- bin_area_,
- norm_,
- rtree_,
- smallsrtree_,
- remaining_);
+ m_bin_area,
+ m_norm,
+ m_rtree,
+ m_smallsrtree,
+ m_remaining);
double score = std::get<0>(result);
auto isBig = [this](const Item& itm) {
- return itm.area()/bin_area_ > BIG_ITEM_TRESHOLD ;
+ return itm.area()/m_bin_area > BIG_ITEM_TRESHOLD ;
};
if(isBig(item)) {
- auto mp = merged_pile_;
+ auto mp = m_merged_pile;
mp.push_back(item.transformedShape());
auto chull = sl::convexHull(mp);
double miss = Placer::overfit(chull, bin);
@@ -427,7 +427,7 @@ public:
return score;
};
- pck_.configure(pconf_);
+ m_pck.configure(m_pconf);
}
};
@@ -439,25 +439,25 @@ public:
std::function<bool(void)> stopcond):
_ArrBase<PolygonImpl>(bin, dist, progressind, stopcond)
{
- pconf_.object_function = [this, &bin] (const Item &item) {
+ m_pconf.object_function = [this, &bin] (const Item &item) {
auto binbb = sl::boundingBox(bin);
auto result = objfunc(binbb.center(),
- merged_pile_,
- pilebb_,
- items_,
+ m_merged_pile,
+ m_pilebb,
+ m_items,
item,
- bin_area_,
- norm_,
- rtree_,
- smallsrtree_,
- remaining_);
+ m_bin_area,
+ m_norm,
+ m_rtree,
+ m_smallsrtree,
+ m_remaining);
double score = std::get<0>(result);
return score;
};
- pck_.configure(pconf_);
+ m_pck.configure(m_pconf);
}
};
@@ -469,22 +469,22 @@ public:
std::function<bool(void)> stopcond):
_ArrBase<Box>(Box(0, 0), dist, progressind, stopcond)
{
- this->pconf_.object_function = [this] (const Item &item) {
+ this->m_pconf.object_function = [this] (const Item &item) {
auto result = objfunc({0, 0},
- merged_pile_,
- pilebb_,
- items_,
+ m_merged_pile,
+ m_pilebb,
+ m_items,
item,
0,
- norm_,
- rtree_,
- smallsrtree_,
- remaining_);
+ m_norm,
+ m_rtree,
+ m_smallsrtree,
+ m_remaining);
return std::get<0>(result);
};
- this->pck_.configure(pconf_);
+ this->m_pck.configure(m_pconf);
}
};
@@ -530,11 +530,11 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model) {
item.rotation(objinst->rotation);
item.translation( {
#if ENABLE_MODELINSTANCE_3D_OFFSET
- ClipperLib::cInt(objinst->get_offset(X) / SCALING_FACTOR),
- ClipperLib::cInt(objinst->get_offset(Y) / SCALING_FACTOR)
+ ClipperLib::cInt(objinst->get_offset(X)/SCALING_FACTOR),
+ ClipperLib::cInt(objinst->get_offset(Y)/SCALING_FACTOR)
#else
- ClipperLib::cInt(objinst->offset(0)/SCALING_FACTOR),
- ClipperLib::cInt(objinst->offset(1)/SCALING_FACTOR)
+ ClipperLib::cInt(objinst->offset(0)/SCALING_FACTOR),
+ ClipperLib::cInt(objinst->offset(1)/SCALING_FACTOR)
#endif // ENABLE_MODELINSTANCE_3D_OFFSET
});
ret.emplace_back(objinst, item);
@@ -668,17 +668,19 @@ void applyResult(
// Get the model instance from the shapemap using the index
ModelInstance *inst_ptr = shapemap[idx].first;
- // Get the tranformation data from the item object and scale it
+ // Get the transformation data from the item object and scale it
// appropriately
auto off = item.translation();
Radians rot = item.rotation();
#if ENABLE_MODELINSTANCE_3D_OFFSET
- Vec3d foff(off.X*SCALING_FACTOR + batch_offset, off.Y*SCALING_FACTOR, 0.0);
+ Vec3d foff(off.X*SCALING_FACTOR + batch_offset,
+ off.Y*SCALING_FACTOR,
+ 0.0);
#else
Vec2d foff(off.X*SCALING_FACTOR + batch_offset, off.Y*SCALING_FACTOR);
#endif // ENABLE_MODELINSTANCE_3D_OFFSET
- // write the tranformation data into the model instance
+ // write the transformation data into the model instance
inst_ptr->rotation = rot;
#if ENABLE_MODELINSTANCE_3D_OFFSET
inst_ptr->set_offset(foff);
@@ -695,7 +697,7 @@ void applyResult(
* The arrangement considers multiple bins (aka. print beds) for placing all
* the items provided in the model argument. If the items don't fit on one
* print bed, the remaining will be placed onto newly created print beds.
- * The first_bin_only parameter, if set to true, disables this behaviour and
+ * The first_bin_only parameter, if set to true, disables this behavior and
* makes sure that only one print bed is filled and the remaining items will be
* untouched. When set to false, the items which could not fit onto the
* print bed will be placed next to the print bed so the user should see a
@@ -741,6 +743,7 @@ bool arrange(Model &model, coordf_t min_obj_distance,
IndexedPackGroup result;
+ // If there is no hint about the shape, we will try to guess
if(bedhint.type == BedShapeType::WHO_KNOWS) bedhint = bedShape(bed);
BoundingBox bbb(bed);
diff --git a/xs/src/slic3r/AppController.cpp b/xs/src/slic3r/AppController.cpp
index f9c126286..2bb79cec1 100644
--- a/xs/src/slic3r/AppController.cpp
+++ b/xs/src/slic3r/AppController.cpp
@@ -21,7 +21,7 @@
namespace Slic3r {
-class AppControllerBoilerplate::PriData {
+class AppControllerGui::PriData {
public:
std::mutex m;
std::thread::id ui_thread;
@@ -29,14 +29,14 @@ public:
inline explicit PriData(std::thread::id uit): ui_thread(uit) {}
};
-AppControllerBoilerplate::AppControllerBoilerplate()
+AppControllerGui::AppControllerGui()
:m_pri_data(new PriData(std::this_thread::get_id())) {}
-AppControllerBoilerplate::~AppControllerBoilerplate() {
+AppControllerGui::~AppControllerGui() {
m_pri_data.reset();
}
-bool AppControllerBoilerplate::is_main_thread() const
+bool AppControllerGui::is_main_thread() const
{
return m_pri_data->ui_thread == std::this_thread::get_id();
}
@@ -54,8 +54,7 @@ static const PrintStep STEP_SKIRT = psSkirt;
static const PrintStep STEP_BRIM = psBrim;
static const PrintStep STEP_WIPE_TOWER = psWipeTower;
-AppControllerBoilerplate::ProgresIndicatorPtr
-AppControllerBoilerplate::global_progress_indicator() {
+ProgresIndicatorPtr AppControllerGui::global_progress_indicator() {
ProgresIndicatorPtr ret;
m_pri_data->m.lock();
@@ -65,8 +64,7 @@ AppControllerBoilerplate::global_progress_indicator() {
return ret;
}
-void AppControllerBoilerplate::global_progress_indicator(
- AppControllerBoilerplate::ProgresIndicatorPtr gpri)
+void AppControllerGui::global_progress_indicator(ProgresIndicatorPtr gpri)
{
m_pri_data->m.lock();
m_global_progressind = gpri;
@@ -78,7 +76,10 @@ PrintController::query_png_export_data(const DynamicPrintConfig& conf)
{
PngExportData ret;
- auto zippath = query_destination_path("Output zip file", "*.zip", "out");
+ auto c = GUI::get_appctl();
+ auto zippath = c->query_destination_path("Output zip file", "*.zip",
+ "export-png",
+ "out");
ret.zippath = zippath;
@@ -102,7 +103,7 @@ PrintController::query_png_export_data(const DynamicPrintConfig& conf)
return ret;
}
-void PrintController::slice(AppControllerBoilerplate::ProgresIndicatorPtr pri)
+void PrintController::slice(ProgresIndicatorPtr pri)
{
m_print->set_status_callback([pri](int st, const std::string& msg){
pri->update(unsigned(st), msg);
@@ -113,8 +114,9 @@ void PrintController::slice(AppControllerBoilerplate::ProgresIndicatorPtr pri)
void PrintController::slice()
{
- auto pri = global_progress_indicator();
- if(!pri) pri = create_progress_indicator(100, L("Slicing"));
+ auto ctl = GUI::get_appctl();
+ auto pri = ctl->global_progress_indicator();
+ if(!pri) pri = ctl->create_progress_indicator(100, L("Slicing"));
slice(pri);
}
@@ -139,13 +141,15 @@ void PrintController::slice_to_png()
{
using Pointf3 = Vec3d;
+ auto ctl = GUI::get_appctl();
auto presetbundle = GUI::get_preset_bundle();
assert(presetbundle);
+ // FIXME: this crashes in command line mode
auto pt = presetbundle->printers.get_selected_preset().printer_technology();
if(pt != ptSLA) {
- report_issue(IssueType::ERR, L("Printer technology is not SLA!"),
+ ctl->report_issue(IssueType::ERR, L("Printer technology is not SLA!"),
L("Error"));
return;
}
@@ -162,7 +166,7 @@ void PrintController::slice_to_png()
print->apply_config(conf);
print->validate();
} catch(std::exception& e) {
- report_issue(IssueType::ERR, e.what(), "Error");
+ ctl->report_issue(IssueType::ERR, e.what(), "Error");
return;
}
@@ -208,13 +212,13 @@ void PrintController::slice_to_png()
<< L("Width needed: ") << px(punsc) << " mm\n"
<< L("Height needed: ") << py(punsc) << " mm\n";
- if(!report_issue(IssueType::WARN_Q, ss.str(), L("Warning"))) {
+ if(!ctl->report_issue(IssueType::WARN_Q, ss.str(), L("Warning"))) {
scale_back();
return;
}
}
- auto pri = create_progress_indicator(
+ auto pri = ctl->create_progress_indicator(
200, L("Slicing to zipped png files..."));
pri->on_cancel([&print](){ print->cancel(); });
@@ -223,7 +227,7 @@ void PrintController::slice_to_png()
pri->update(0, L("Slicing..."));
slice(pri);
} catch (std::exception& e) {
- report_issue(IssueType::ERR, e.what(), L("Exception occurred"));
+ ctl->report_issue(IssueType::ERR, e.what(), L("Exception occurred"));
scale_back();
if(print->canceled()) print->restart();
return;
@@ -242,7 +246,7 @@ void PrintController::slice_to_png()
exd.exp_time_s, exd.exp_time_first_s);
} catch (std::exception& e) {
- report_issue(IssueType::ERR, e.what(), L("Exception occurred"));
+ ctl->report_issue(IssueType::ERR, e.what(), L("Exception occurred"));
}
scale_back();
@@ -286,6 +290,8 @@ void AppController::arrange_model()
{
using Coord = libnest2d::TCoord<libnest2d::PointImpl>;
+ auto ctl = GUI::get_appctl();
+
if(m_arranging.load()) return;
// to prevent UI reentrancies
@@ -294,7 +300,7 @@ void AppController::arrange_model()
unsigned count = 0;
for(auto obj : m_model->objects) count += obj->instances.size();
- auto pind = global_progress_indicator();
+ auto pind = ctl->global_progress_indicator();
float pmax = 1.0;
@@ -331,15 +337,15 @@ void AppController::arrange_model()
bed,
hint,
false, // create many piles not just one pile
- [this, pind, count](unsigned rem) {
+ [this, pind, &ctl, count](unsigned rem) {
if(pind)
pind->update(count - rem, L("Arranging objects..."));
- process_events();
+ ctl->process_events();
}, [this] () { return !m_arranging.load(); });
} catch(std::exception& e) {
std::cerr << e.what() << std::endl;
- report_issue(IssueType::ERR,
+ ctl->report_issue(IssueType::ERR,
L("Could not arrange model objects! "
"Some geometries may be invalid."),
L("Exception occurred"));
diff --git a/xs/src/slic3r/AppController.hpp b/xs/src/slic3r/AppController.hpp
index df506c05b..a34e5d035 100644
--- a/xs/src/slic3r/AppController.hpp
+++ b/xs/src/slic3r/AppController.hpp
@@ -20,6 +20,21 @@ class PrintConfig;
class ProgressStatusBar;
class DynamicPrintConfig;
+/// A Progress indicator object smart pointer
+using ProgresIndicatorPtr = std::shared_ptr<ProgressIndicator>;
+
+using FilePath = std::string;
+using FilePathList = std::vector<FilePath>;
+
+/// Common runtime issue types
+enum class IssueType {
+ INFO,
+ WARN,
+ WARN_Q, // Warning with a question to continue
+ ERR,
+ FATAL
+};
+
/**
* @brief A boilerplate class for creating application logic. It should provide
* features as issue reporting and progress indication, etc...
@@ -32,34 +47,12 @@ class DynamicPrintConfig;
* UI toolkit dependencies. We can implement it with any UI framework or make it
* a cli client.
*/
-class AppControllerBoilerplate {
-public:
-
- /// A Progress indicator object smart pointer
- using ProgresIndicatorPtr = std::shared_ptr<ProgressIndicator>;
-
-private:
- class PriData; // Some structure to store progress indication data
-
- // Pimpl data for thread safe progress indication features
- std::unique_ptr<PriData> m_pri_data;
-
+class AppControllerBase {
public:
- AppControllerBoilerplate();
- ~AppControllerBoilerplate();
+ using Ptr = std::shared_ptr<AppControllerBase>;
- using Path = std::string;
- using PathList = std::vector<Path>;
-
- /// Common runtime issue types
- enum class IssueType {
- INFO,
- WARN,
- WARN_Q, // Warning with a question to continue
- ERR,
- FATAL
- };
+ inline virtual ~AppControllerBase() {}
/**
* @brief Query some paths from the user.
@@ -69,23 +62,28 @@ public:
* @param extensions Recognized file extensions.
* @return Returns a list of paths chosen by the user.
*/
- PathList query_destination_paths(
+ virtual FilePathList query_destination_paths(
const std::string& title,
- const std::string& extensions) const;
+ const std::string& extensions,
+ const std::string& functionid = "",
+ const std::string& hint = "") const = 0;
/**
* @brief Same as query_destination_paths but works for directories only.
*/
- PathList query_destination_dirs(
- const std::string& title) const;
+ virtual FilePathList query_destination_dirs(
+ const std::string& title,
+ const std::string& functionid = "",
+ const std::string& hint = "") const = 0;
/**
* @brief Same as query_destination_paths but returns only one path.
*/
- Path query_destination_path(
+ virtual FilePath query_destination_path(
const std::string& title,
const std::string& extensions,
- const std::string& hint = "") const;
+ const std::string& functionid = "",
+ const std::string& hint = "") const = 0;
/**
* @brief Report an issue to the user be it fatal or recoverable.
@@ -97,12 +95,9 @@ public:
* @param brief A very brief description. Can be used for message dialog
* title.
*/
- bool report_issue(IssueType issuetype,
- const std::string& description,
- const std::string& brief);
-
- bool report_issue(IssueType issuetype,
- const std::string& description);
+ virtual bool report_issue(IssueType issuetype,
+ const std::string& description,
+ const std::string& brief) = 0;
/**
* @brief Return the global progress indicator for the current controller.
@@ -110,9 +105,9 @@ public:
*
* Only one thread should use the global indicator at a time.
*/
- ProgresIndicatorPtr global_progress_indicator();
+ virtual ProgresIndicatorPtr global_progress_indicator() = 0;
- void global_progress_indicator(ProgresIndicatorPtr gpri);
+ virtual void global_progress_indicator(ProgresIndicatorPtr gpri) = 0;
/**
* @brief A predicate telling the caller whether it is the thread that
@@ -122,7 +117,7 @@ public:
* @return Return true for the same caller thread that created this
* object and false for every other.
*/
- bool is_main_thread() const;
+ virtual bool is_main_thread() const = 0;
/**
* @brief The frontend supports asynch execution.
@@ -138,11 +133,9 @@ public:
* @return true if a job or method can be executed asynchronously, false
* otherwise.
*/
- bool supports_asynch() const;
+ virtual bool supports_asynch() const = 0;
- void process_events();
-
-protected:
+ virtual void process_events() = 0;
/**
* @brief Create a new progress indicator and return a smart pointer to it.
@@ -151,14 +144,138 @@ protected:
* @param firstmsg The message for the first subtask to be displayed.
* @return Smart pointer to the created object.
*/
- ProgresIndicatorPtr create_progress_indicator(
+ virtual ProgresIndicatorPtr create_progress_indicator(
unsigned statenum,
const std::string& title,
- const std::string& firstmsg) const;
+ const std::string& firstmsg = "") const = 0;
+};
+
+/**
+ * @brief Implementation of AppControllerBase for the GUI app
+ */
+class AppControllerGui: public AppControllerBase {
+private:
+ class PriData; // Some structure to store progress indication data
+
+ // Pimpl data for thread safe progress indication features
+ std::unique_ptr<PriData> m_pri_data;
+
+public:
+
+ AppControllerGui();
+
+ virtual ~AppControllerGui();
+
+ virtual FilePathList query_destination_paths(
+ const std::string& title,
+ const std::string& extensions,
+ const std::string& functionid,
+ const std::string& hint) const override;
+
+ virtual FilePathList query_destination_dirs(
+ const std::string& /*title*/,
+ const std::string& /*functionid*/,
+ const std::string& /*hint*/) const override { return {}; }
+
+ virtual FilePath query_destination_path(
+ const std::string& title,
+ const std::string& extensions,
+ const std::string& functionid,
+ const std::string& hint) const override;
+
+ virtual bool report_issue(IssueType issuetype,
+ const std::string& description,
+ const std::string& brief = std::string()) override;
+
+ virtual ProgresIndicatorPtr global_progress_indicator() override;
+
+ virtual void global_progress_indicator(ProgresIndicatorPtr gpri) override;
- ProgresIndicatorPtr create_progress_indicator(
+ virtual bool is_main_thread() const override;
+
+ virtual bool supports_asynch() const override;
+
+ virtual void process_events() override;
+
+ virtual ProgresIndicatorPtr create_progress_indicator(
unsigned statenum,
- const std::string& title) const;
+ const std::string& title,
+ const std::string& firstmsg) const override;
+
+protected:
+
+ // This is a global progress indicator placeholder. In the Slic3r UI it can
+ // contain the progress indicator on the statusbar.
+ ProgresIndicatorPtr m_global_progressind;
+};
+
+class AppControllerCli: public AppControllerBase {
+
+ class CliProgress : public ProgressIndicator {
+ std::string m_msg, m_title;
+ public:
+ virtual void message(const std::string& msg) override {
+ m_msg = msg;
+ }
+
+ virtual void title(const std::string& title) override {
+ m_title = title;
+ }
+ };
+
+public:
+
+ AppControllerCli() {
+ std::cout << "Cli AppController ready..." << std::endl;
+ m_global_progressind = std::make_shared<CliProgress>();
+ }
+
+ virtual ~AppControllerCli() {}
+
+ virtual FilePathList query_destination_paths(
+ const std::string& /*title*/,
+ const std::string& /*extensions*/,
+ const std::string& /*functionid*/,
+ const std::string& /*hint*/) const override { return {}; }
+
+ virtual FilePathList query_destination_dirs(
+ const std::string& /*title*/,
+ const std::string& /*functionid*/,
+ const std::string& /*hint*/) const override { return {}; }
+
+ virtual FilePath query_destination_path(
+ const std::string& /*title*/,
+ const std::string& /*extensions*/,
+ const std::string& /*functionid*/,
+ const std::string& /*hint*/) const override { return "out.zip"; }
+
+ virtual bool report_issue(IssueType /*issuetype*/,
+ const std::string& description,
+ const std::string& brief) override {
+ std::cerr << brief << ": " << description << std::endl;
+ return true;
+ }
+
+ virtual ProgresIndicatorPtr global_progress_indicator() override {
+ return m_global_progressind;
+ }
+
+ virtual void global_progress_indicator(ProgresIndicatorPtr) override {}
+
+ virtual bool is_main_thread() const override { return true; }
+
+ virtual bool supports_asynch() const override { return false; }
+
+ virtual void process_events() override {}
+
+ virtual ProgresIndicatorPtr create_progress_indicator(
+ unsigned /*statenum*/,
+ const std::string& /*title*/,
+ const std::string& /*firstmsg*/) const override {
+ return std::make_shared<CliProgress>();
+ }
+
+protected:
// This is a global progress indicator placeholder. In the Slic3r UI it can
// contain the progress indicator on the statusbar.
@@ -185,7 +302,7 @@ public:
/**
* @brief Implementation of the printing logic.
*/
-class PrintController: public AppControllerBoilerplate {
+class PrintController {
Print *m_print = nullptr;
std::function<void()> m_rempools;
protected:
@@ -241,7 +358,7 @@ public:
/**
* @brief Top level controller.
*/
-class AppController: public AppControllerBoilerplate {
+class AppController {
Model *m_model = nullptr;
PrintController::Ptr printctl;
std::atomic<bool> m_arranging;
diff --git a/xs/src/slic3r/AppControllerWx.cpp b/xs/src/slic3r/AppControllerWx.cpp
index 9f52e52d2..25cd739f3 100644
--- a/xs/src/slic3r/AppControllerWx.cpp
+++ b/xs/src/slic3r/AppControllerWx.cpp
@@ -25,40 +25,43 @@
namespace Slic3r {
-bool AppControllerBoilerplate::supports_asynch() const
+bool AppControllerGui::supports_asynch() const
{
return true;
}
-void AppControllerBoilerplate::process_events()
+void AppControllerGui::process_events()
{
wxYieldIfNeeded();
}
-AppControllerBoilerplate::PathList
-AppControllerBoilerplate::query_destination_paths(
+FilePathList AppControllerGui::query_destination_paths(
const std::string &title,
- const std::string &extensions) const
+ const std::string &extensions,
+ const std::string &/*functionid*/,
+ const std::string& hint) const
{
wxFileDialog dlg(wxTheApp->GetTopWindow(), _(title) );
dlg.SetWildcard(extensions);
- dlg.ShowModal();
+ dlg.SetFilename(hint);
- wxArrayString paths;
- dlg.GetPaths(paths);
+ FilePathList ret;
- PathList ret(paths.size(), "");
- for(auto& p : paths) ret.push_back(p.ToStdString());
+ if(dlg.ShowModal() == wxID_OK) {
+ wxArrayString paths;
+ dlg.GetPaths(paths);
+ for(auto& p : paths) ret.push_back(p.ToStdString());
+ }
return ret;
}
-AppControllerBoilerplate::Path
-AppControllerBoilerplate::query_destination_path(
+FilePath AppControllerGui::query_destination_path(
const std::string &title,
const std::string &extensions,
+ const std::string &/*functionid*/,
const std::string& hint) const
{
wxFileDialog dlg(wxTheApp->GetTopWindow(), _(title) );
@@ -66,16 +69,16 @@ AppControllerBoilerplate::query_destination_path(
dlg.SetFilename(hint);
- Path ret;
+ FilePath ret;
if(dlg.ShowModal() == wxID_OK) {
- ret = Path(dlg.GetPath());
+ ret = FilePath(dlg.GetPath());
}
return ret;
}
-bool AppControllerBoilerplate::report_issue(IssueType issuetype,
+bool AppControllerGui::report_issue(IssueType issuetype,
const std::string &description,
const std::string &brief)
{
@@ -93,13 +96,6 @@ bool AppControllerBoilerplate::report_issue(IssueType issuetype,
return ret != wxCANCEL;
}
-bool AppControllerBoilerplate::report_issue(
- AppControllerBoilerplate::IssueType issuetype,
- const std::string &description)
-{
- return report_issue(issuetype, description, std::string());
-}
-
wxDEFINE_EVENT(PROGRESS_STATUS_UPDATE_EVENT, wxCommandEvent);
struct Zipper::Impl {
@@ -235,8 +231,7 @@ public:
};
}
-AppControllerBoilerplate::ProgresIndicatorPtr
-AppControllerBoilerplate::create_progress_indicator(
+ProgresIndicatorPtr AppControllerGui::create_progress_indicator(
unsigned statenum,
const std::string& title,
const std::string& firstmsg) const
@@ -251,20 +246,13 @@ AppControllerBoilerplate::create_progress_indicator(
return pri;
}
-AppControllerBoilerplate::ProgresIndicatorPtr
-AppControllerBoilerplate::create_progress_indicator(
- unsigned statenum, const std::string &title) const
-{
- return create_progress_indicator(statenum, title, std::string());
-}
-
namespace {
class Wrapper: public ProgressIndicator, public wxEvtHandler {
ProgressStatusBar *m_sbar;
using Base = ProgressIndicator;
wxString m_message;
- AppControllerBoilerplate& m_ctl;
+ AppControllerBase& m_ctl;
void showProgress(bool show = true) {
m_sbar->show_progress(show);
@@ -288,7 +276,7 @@ class Wrapper: public ProgressIndicator, public wxEvtHandler {
public:
inline Wrapper(ProgressStatusBar *sbar,
- AppControllerBoilerplate& ctl):
+ AppControllerBase& ctl):
m_sbar(sbar), m_ctl(ctl)
{
Base::max(static_cast<float>(m_sbar->get_range()));
@@ -344,7 +332,8 @@ public:
void AppController::set_global_progress_indicator(ProgressStatusBar *prsb)
{
if(prsb) {
- global_progress_indicator(std::make_shared<Wrapper>(prsb, *this));
+ auto ctl = GUI::get_appctl();
+ ctl->global_progress_indicator(std::make_shared<Wrapper>(prsb, *ctl));
}
}
diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp
index e5ed917b3..2ad155b7d 100644
--- a/xs/src/slic3r/GUI/GUI.cpp
+++ b/xs/src/slic3r/GUI/GUI.cpp
@@ -1,4 +1,5 @@
#include "GUI.hpp"
+#include "../AppController.hpp"
#include "WipeTowerDialog.hpp"
#include <assert.h>
@@ -1405,4 +1406,23 @@ void desktop_open_datadir_folder()
#endif
}
+namespace {
+AppControllerPtr g_appctl;
+}
+
+AppControllerPtr get_appctl()
+{
+ return g_appctl;
+}
+
+void set_cli_appctl()
+{
+ g_appctl = std::make_shared<AppControllerCli>();
+}
+
+void set_gui_appctl()
+{
+ g_appctl = std::make_shared<AppControllerGui>();
+}
+
} }
diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp
index cbf83aa94..04b4a4217 100644
--- a/xs/src/slic3r/GUI/GUI.hpp
+++ b/xs/src/slic3r/GUI/GUI.hpp
@@ -42,6 +42,9 @@ class TabIface;
class PreviewIface;
class Print;
class GCodePreviewData;
+class AppControllerBase;
+
+using AppControllerPtr = std::shared_ptr<AppControllerBase>;
#define _(s) Slic3r::GUI::I18N::translate((s))
@@ -129,6 +132,10 @@ ProgressStatusBar* get_progress_status_bar();
wxNotebook * get_tab_panel();
wxNotebook* get_tab_panel();
+AppControllerPtr get_appctl();
+void set_cli_appctl();
+void set_gui_appctl();
+
const wxColour& get_label_clr_modified();
const wxColour& get_label_clr_sys();
const wxColour& get_label_clr_default();
diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp
index 22e2ff1d7..a1e3e4670 100644
--- a/xs/xsp/GUI.xsp
+++ b/xs/xsp/GUI.xsp
@@ -35,6 +35,12 @@ bool is_windows10()
void set_wxapp(SV *ui)
%code%{ Slic3r::GUI::set_wxapp((wxApp*)wxPli_sv_2_object(aTHX_ ui, "Wx::App")); %};
+void set_gui_appctl()
+ %code%{ Slic3r::GUI::set_gui_appctl(); %};
+
+void set_cli_appctl()
+ %code%{ Slic3r::GUI::set_cli_appctl(); %};
+
void set_progress_status_bar(ProgressStatusBar *prs)
%code%{ Slic3r::GUI::set_progress_status_bar(prs); %};