Polymorphic AppController for cli and gui modes.
This commit is contained in:
parent
c9acd1252a
commit
2306c1589a
@ -109,6 +109,7 @@ if ((!@ARGV || $opt{gui}) && !$opt{no_gui} && !$opt{save} && eval "require Slic3
|
|||||||
$Slic3r::GUI::no_plater = $opt{no_plater};
|
$Slic3r::GUI::no_plater = $opt{no_plater};
|
||||||
$Slic3r::GUI::autosave = $opt{autosave};
|
$Slic3r::GUI::autosave = $opt{autosave};
|
||||||
}
|
}
|
||||||
|
Slic3r::GUI::set_gui_appctl();
|
||||||
$gui = Slic3r::GUI->new;
|
$gui = Slic3r::GUI->new;
|
||||||
#setlocale(LC_NUMERIC, 'C');
|
#setlocale(LC_NUMERIC, 'C');
|
||||||
$gui->{mainframe}->load_config_file($_) for @{$opt{load}};
|
$gui->{mainframe}->load_config_file($_) for @{$opt{load}};
|
||||||
@ -121,6 +122,9 @@ if ((!@ARGV || $opt{gui}) && !$opt{no_gui} && !$opt{save} && eval "require Slic3
|
|||||||
die $@ if $@ && $opt{gui};
|
die $@ if $@ && $opt{gui};
|
||||||
|
|
||||||
if (@ARGV) { # slicing from command line
|
if (@ARGV) { # slicing from command line
|
||||||
|
Slic3r::GUI::set_cli_appctl();
|
||||||
|
my $appctl = Slic3r::AppController->new();
|
||||||
|
|
||||||
$config->validate;
|
$config->validate;
|
||||||
|
|
||||||
if ($opt{repair}) {
|
if ($opt{repair}) {
|
||||||
@ -210,7 +214,10 @@ if (@ARGV) { # slicing from command line
|
|||||||
$sprint->apply_config($config);
|
$sprint->apply_config($config);
|
||||||
|
|
||||||
if ($opt{export_png}) {
|
if ($opt{export_png}) {
|
||||||
$sprint->export_png;
|
# $sprint->export_png;
|
||||||
|
$appctl->set_model($model);
|
||||||
|
$appctl->set_print($sprint->_print);
|
||||||
|
$appctl->print_ctl()->slice_to_png();
|
||||||
} else {
|
} else {
|
||||||
my $t0 = [gettimeofday];
|
my $t0 = [gettimeofday];
|
||||||
# The following call may die if the output_filename_format template substitution fails,
|
# The following call may die if the output_filename_format template substitution fails,
|
||||||
|
@ -292,59 +292,59 @@ protected:
|
|||||||
using Distance = TCoord<PointImpl>;
|
using Distance = TCoord<PointImpl>;
|
||||||
using Pile = sl::Shapes<PolygonImpl>;
|
using Pile = sl::Shapes<PolygonImpl>;
|
||||||
|
|
||||||
Packer pck_;
|
Packer m_pck;
|
||||||
PConfig pconf_; // Placement configuration
|
PConfig m_pconf; // Placement configuration
|
||||||
double bin_area_;
|
double m_bin_area;
|
||||||
SpatIndex rtree_;
|
SpatIndex m_rtree;
|
||||||
SpatIndex smallsrtree_;
|
SpatIndex m_smallsrtree;
|
||||||
double norm_;
|
double m_norm;
|
||||||
Pile merged_pile_;
|
Pile m_merged_pile;
|
||||||
Box pilebb_;
|
Box m_pilebb;
|
||||||
ItemGroup remaining_;
|
ItemGroup m_remaining;
|
||||||
ItemGroup items_;
|
ItemGroup m_items;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
_ArrBase(const TBin& bin, Distance dist,
|
_ArrBase(const TBin& bin, Distance dist,
|
||||||
std::function<void(unsigned)> progressind,
|
std::function<void(unsigned)> progressind,
|
||||||
std::function<bool(void)> stopcond):
|
std::function<bool(void)> stopcond):
|
||||||
pck_(bin, dist), bin_area_(sl::area(bin)),
|
m_pck(bin, dist), m_bin_area(sl::area(bin)),
|
||||||
norm_(std::sqrt(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
|
[this](const Pile& merged_pile, // merged pile
|
||||||
const ItemGroup& items, // packed items
|
const ItemGroup& items, // packed items
|
||||||
const ItemGroup& remaining) // future items to be packed
|
const ItemGroup& remaining) // future items to be packed
|
||||||
{
|
{
|
||||||
items_ = items;
|
m_items = items;
|
||||||
merged_pile_ = merged_pile;
|
m_merged_pile = merged_pile;
|
||||||
remaining_ = remaining;
|
m_remaining = remaining;
|
||||||
|
|
||||||
pilebb_ = sl::boundingBox(merged_pile);
|
m_pilebb = sl::boundingBox(merged_pile);
|
||||||
|
|
||||||
rtree_.clear();
|
m_rtree.clear();
|
||||||
smallsrtree_.clear();
|
m_smallsrtree.clear();
|
||||||
|
|
||||||
// We will treat big items (compared to the print bed) differently
|
// We will treat big items (compared to the print bed) differently
|
||||||
auto isBig = [this](double a) {
|
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) {
|
for(unsigned idx = 0; idx < items.size(); ++idx) {
|
||||||
Item& itm = items[idx];
|
Item& itm = items[idx];
|
||||||
if(isBig(itm.area())) rtree_.insert({itm.boundingBox(), idx});
|
if(isBig(itm.area())) m_rtree.insert({itm.boundingBox(), idx});
|
||||||
smallsrtree_.insert({itm.boundingBox(), idx});
|
m_smallsrtree.insert({itm.boundingBox(), idx});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pck_.progressIndicator(progressind);
|
m_pck.progressIndicator(progressind);
|
||||||
pck_.stopCondition(stopcond);
|
m_pck.stopCondition(stopcond);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class...Args> inline IndexedPackGroup operator()(Args&&...args) {
|
template<class...Args> inline IndexedPackGroup operator()(Args&&...args) {
|
||||||
rtree_.clear();
|
m_rtree.clear();
|
||||||
return pck_.executeIndexed(std::forward<Args>(args)...);
|
return m_pck.executeIndexed(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -358,18 +358,18 @@ public:
|
|||||||
_ArrBase<Box>(bin, dist, progressind, stopcond)
|
_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(),
|
auto result = objfunc(bin.center(),
|
||||||
merged_pile_,
|
m_merged_pile,
|
||||||
pilebb_,
|
m_pilebb,
|
||||||
items_,
|
m_items,
|
||||||
item,
|
item,
|
||||||
bin_area_,
|
m_bin_area,
|
||||||
norm_,
|
m_norm,
|
||||||
rtree_,
|
m_rtree,
|
||||||
smallsrtree_,
|
m_smallsrtree,
|
||||||
remaining_);
|
m_remaining);
|
||||||
|
|
||||||
double score = std::get<0>(result);
|
double score = std::get<0>(result);
|
||||||
auto& fullbb = std::get<1>(result);
|
auto& fullbb = std::get<1>(result);
|
||||||
@ -381,7 +381,7 @@ public:
|
|||||||
return score;
|
return score;
|
||||||
};
|
};
|
||||||
|
|
||||||
pck_.configure(pconf_);
|
m_pck.configure(m_pconf);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -396,27 +396,27 @@ public:
|
|||||||
std::function<bool(void)> stopcond):
|
std::function<bool(void)> stopcond):
|
||||||
_ArrBase<lnCircle>(bin, dist, progressind, 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(),
|
auto result = objfunc(bin.center(),
|
||||||
merged_pile_,
|
m_merged_pile,
|
||||||
pilebb_,
|
m_pilebb,
|
||||||
items_,
|
m_items,
|
||||||
item,
|
item,
|
||||||
bin_area_,
|
m_bin_area,
|
||||||
norm_,
|
m_norm,
|
||||||
rtree_,
|
m_rtree,
|
||||||
smallsrtree_,
|
m_smallsrtree,
|
||||||
remaining_);
|
m_remaining);
|
||||||
|
|
||||||
double score = std::get<0>(result);
|
double score = std::get<0>(result);
|
||||||
|
|
||||||
auto isBig = [this](const Item& itm) {
|
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)) {
|
if(isBig(item)) {
|
||||||
auto mp = merged_pile_;
|
auto mp = m_merged_pile;
|
||||||
mp.push_back(item.transformedShape());
|
mp.push_back(item.transformedShape());
|
||||||
auto chull = sl::convexHull(mp);
|
auto chull = sl::convexHull(mp);
|
||||||
double miss = Placer::overfit(chull, bin);
|
double miss = Placer::overfit(chull, bin);
|
||||||
@ -427,7 +427,7 @@ public:
|
|||||||
return score;
|
return score;
|
||||||
};
|
};
|
||||||
|
|
||||||
pck_.configure(pconf_);
|
m_pck.configure(m_pconf);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -439,25 +439,25 @@ public:
|
|||||||
std::function<bool(void)> stopcond):
|
std::function<bool(void)> stopcond):
|
||||||
_ArrBase<PolygonImpl>(bin, dist, progressind, 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 binbb = sl::boundingBox(bin);
|
||||||
auto result = objfunc(binbb.center(),
|
auto result = objfunc(binbb.center(),
|
||||||
merged_pile_,
|
m_merged_pile,
|
||||||
pilebb_,
|
m_pilebb,
|
||||||
items_,
|
m_items,
|
||||||
item,
|
item,
|
||||||
bin_area_,
|
m_bin_area,
|
||||||
norm_,
|
m_norm,
|
||||||
rtree_,
|
m_rtree,
|
||||||
smallsrtree_,
|
m_smallsrtree,
|
||||||
remaining_);
|
m_remaining);
|
||||||
double score = std::get<0>(result);
|
double score = std::get<0>(result);
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
};
|
};
|
||||||
|
|
||||||
pck_.configure(pconf_);
|
m_pck.configure(m_pconf);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -469,22 +469,22 @@ public:
|
|||||||
std::function<bool(void)> stopcond):
|
std::function<bool(void)> stopcond):
|
||||||
_ArrBase<Box>(Box(0, 0), dist, progressind, 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},
|
auto result = objfunc({0, 0},
|
||||||
merged_pile_,
|
m_merged_pile,
|
||||||
pilebb_,
|
m_pilebb,
|
||||||
items_,
|
m_items,
|
||||||
item,
|
item,
|
||||||
0,
|
0,
|
||||||
norm_,
|
m_norm,
|
||||||
rtree_,
|
m_rtree,
|
||||||
smallsrtree_,
|
m_smallsrtree,
|
||||||
remaining_);
|
m_remaining);
|
||||||
return std::get<0>(result);
|
return std::get<0>(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
this->pck_.configure(pconf_);
|
this->m_pck.configure(m_pconf);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -668,17 +668,19 @@ void applyResult(
|
|||||||
// Get the model instance from the shapemap using the index
|
// Get the model instance from the shapemap using the index
|
||||||
ModelInstance *inst_ptr = shapemap[idx].first;
|
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
|
// appropriately
|
||||||
auto off = item.translation();
|
auto off = item.translation();
|
||||||
Radians rot = item.rotation();
|
Radians rot = item.rotation();
|
||||||
#if ENABLE_MODELINSTANCE_3D_OFFSET
|
#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
|
#else
|
||||||
Vec2d foff(off.X*SCALING_FACTOR + batch_offset, off.Y*SCALING_FACTOR);
|
Vec2d foff(off.X*SCALING_FACTOR + batch_offset, off.Y*SCALING_FACTOR);
|
||||||
#endif // ENABLE_MODELINSTANCE_3D_OFFSET
|
#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;
|
inst_ptr->rotation = rot;
|
||||||
#if ENABLE_MODELINSTANCE_3D_OFFSET
|
#if ENABLE_MODELINSTANCE_3D_OFFSET
|
||||||
inst_ptr->set_offset(foff);
|
inst_ptr->set_offset(foff);
|
||||||
@ -695,7 +697,7 @@ void applyResult(
|
|||||||
* The arrangement considers multiple bins (aka. print beds) for placing all
|
* 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
|
* 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.
|
* 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
|
* 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
|
* 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
|
* 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;
|
IndexedPackGroup result;
|
||||||
|
|
||||||
|
// If there is no hint about the shape, we will try to guess
|
||||||
if(bedhint.type == BedShapeType::WHO_KNOWS) bedhint = bedShape(bed);
|
if(bedhint.type == BedShapeType::WHO_KNOWS) bedhint = bedShape(bed);
|
||||||
|
|
||||||
BoundingBox bbb(bed);
|
BoundingBox bbb(bed);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class AppControllerBoilerplate::PriData {
|
class AppControllerGui::PriData {
|
||||||
public:
|
public:
|
||||||
std::mutex m;
|
std::mutex m;
|
||||||
std::thread::id ui_thread;
|
std::thread::id ui_thread;
|
||||||
@ -29,14 +29,14 @@ public:
|
|||||||
inline explicit PriData(std::thread::id uit): ui_thread(uit) {}
|
inline explicit PriData(std::thread::id uit): ui_thread(uit) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
AppControllerBoilerplate::AppControllerBoilerplate()
|
AppControllerGui::AppControllerGui()
|
||||||
:m_pri_data(new PriData(std::this_thread::get_id())) {}
|
:m_pri_data(new PriData(std::this_thread::get_id())) {}
|
||||||
|
|
||||||
AppControllerBoilerplate::~AppControllerBoilerplate() {
|
AppControllerGui::~AppControllerGui() {
|
||||||
m_pri_data.reset();
|
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();
|
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_BRIM = psBrim;
|
||||||
static const PrintStep STEP_WIPE_TOWER = psWipeTower;
|
static const PrintStep STEP_WIPE_TOWER = psWipeTower;
|
||||||
|
|
||||||
AppControllerBoilerplate::ProgresIndicatorPtr
|
ProgresIndicatorPtr AppControllerGui::global_progress_indicator() {
|
||||||
AppControllerBoilerplate::global_progress_indicator() {
|
|
||||||
ProgresIndicatorPtr ret;
|
ProgresIndicatorPtr ret;
|
||||||
|
|
||||||
m_pri_data->m.lock();
|
m_pri_data->m.lock();
|
||||||
@ -65,8 +64,7 @@ AppControllerBoilerplate::global_progress_indicator() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppControllerBoilerplate::global_progress_indicator(
|
void AppControllerGui::global_progress_indicator(ProgresIndicatorPtr gpri)
|
||||||
AppControllerBoilerplate::ProgresIndicatorPtr gpri)
|
|
||||||
{
|
{
|
||||||
m_pri_data->m.lock();
|
m_pri_data->m.lock();
|
||||||
m_global_progressind = gpri;
|
m_global_progressind = gpri;
|
||||||
@ -78,7 +76,10 @@ PrintController::query_png_export_data(const DynamicPrintConfig& conf)
|
|||||||
{
|
{
|
||||||
PngExportData ret;
|
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;
|
ret.zippath = zippath;
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ PrintController::query_png_export_data(const DynamicPrintConfig& conf)
|
|||||||
return ret;
|
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){
|
m_print->set_status_callback([pri](int st, const std::string& msg){
|
||||||
pri->update(unsigned(st), msg);
|
pri->update(unsigned(st), msg);
|
||||||
@ -113,8 +114,9 @@ void PrintController::slice(AppControllerBoilerplate::ProgresIndicatorPtr pri)
|
|||||||
|
|
||||||
void PrintController::slice()
|
void PrintController::slice()
|
||||||
{
|
{
|
||||||
auto pri = global_progress_indicator();
|
auto ctl = GUI::get_appctl();
|
||||||
if(!pri) pri = create_progress_indicator(100, L("Slicing"));
|
auto pri = ctl->global_progress_indicator();
|
||||||
|
if(!pri) pri = ctl->create_progress_indicator(100, L("Slicing"));
|
||||||
slice(pri);
|
slice(pri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,13 +141,15 @@ void PrintController::slice_to_png()
|
|||||||
{
|
{
|
||||||
using Pointf3 = Vec3d;
|
using Pointf3 = Vec3d;
|
||||||
|
|
||||||
|
auto ctl = GUI::get_appctl();
|
||||||
auto presetbundle = GUI::get_preset_bundle();
|
auto presetbundle = GUI::get_preset_bundle();
|
||||||
|
|
||||||
assert(presetbundle);
|
assert(presetbundle);
|
||||||
|
|
||||||
|
// FIXME: this crashes in command line mode
|
||||||
auto pt = presetbundle->printers.get_selected_preset().printer_technology();
|
auto pt = presetbundle->printers.get_selected_preset().printer_technology();
|
||||||
if(pt != ptSLA) {
|
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"));
|
L("Error"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -162,7 +166,7 @@ void PrintController::slice_to_png()
|
|||||||
print->apply_config(conf);
|
print->apply_config(conf);
|
||||||
print->validate();
|
print->validate();
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
report_issue(IssueType::ERR, e.what(), "Error");
|
ctl->report_issue(IssueType::ERR, e.what(), "Error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,13 +212,13 @@ void PrintController::slice_to_png()
|
|||||||
<< L("Width needed: ") << px(punsc) << " mm\n"
|
<< L("Width needed: ") << px(punsc) << " mm\n"
|
||||||
<< L("Height needed: ") << py(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();
|
scale_back();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pri = create_progress_indicator(
|
auto pri = ctl->create_progress_indicator(
|
||||||
200, L("Slicing to zipped png files..."));
|
200, L("Slicing to zipped png files..."));
|
||||||
|
|
||||||
pri->on_cancel([&print](){ print->cancel(); });
|
pri->on_cancel([&print](){ print->cancel(); });
|
||||||
@ -223,7 +227,7 @@ void PrintController::slice_to_png()
|
|||||||
pri->update(0, L("Slicing..."));
|
pri->update(0, L("Slicing..."));
|
||||||
slice(pri);
|
slice(pri);
|
||||||
} catch (std::exception& e) {
|
} 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();
|
scale_back();
|
||||||
if(print->canceled()) print->restart();
|
if(print->canceled()) print->restart();
|
||||||
return;
|
return;
|
||||||
@ -242,7 +246,7 @@ void PrintController::slice_to_png()
|
|||||||
exd.exp_time_s, exd.exp_time_first_s);
|
exd.exp_time_s, exd.exp_time_first_s);
|
||||||
|
|
||||||
} catch (std::exception& e) {
|
} 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();
|
scale_back();
|
||||||
@ -286,6 +290,8 @@ void AppController::arrange_model()
|
|||||||
{
|
{
|
||||||
using Coord = libnest2d::TCoord<libnest2d::PointImpl>;
|
using Coord = libnest2d::TCoord<libnest2d::PointImpl>;
|
||||||
|
|
||||||
|
auto ctl = GUI::get_appctl();
|
||||||
|
|
||||||
if(m_arranging.load()) return;
|
if(m_arranging.load()) return;
|
||||||
|
|
||||||
// to prevent UI reentrancies
|
// to prevent UI reentrancies
|
||||||
@ -294,7 +300,7 @@ void AppController::arrange_model()
|
|||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
for(auto obj : m_model->objects) count += obj->instances.size();
|
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;
|
float pmax = 1.0;
|
||||||
|
|
||||||
@ -331,15 +337,15 @@ void AppController::arrange_model()
|
|||||||
bed,
|
bed,
|
||||||
hint,
|
hint,
|
||||||
false, // create many piles not just one pile
|
false, // create many piles not just one pile
|
||||||
[this, pind, count](unsigned rem) {
|
[this, pind, &ctl, count](unsigned rem) {
|
||||||
if(pind)
|
if(pind)
|
||||||
pind->update(count - rem, L("Arranging objects..."));
|
pind->update(count - rem, L("Arranging objects..."));
|
||||||
|
|
||||||
process_events();
|
ctl->process_events();
|
||||||
}, [this] () { return !m_arranging.load(); });
|
}, [this] () { return !m_arranging.load(); });
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
report_issue(IssueType::ERR,
|
ctl->report_issue(IssueType::ERR,
|
||||||
L("Could not arrange model objects! "
|
L("Could not arrange model objects! "
|
||||||
"Some geometries may be invalid."),
|
"Some geometries may be invalid."),
|
||||||
L("Exception occurred"));
|
L("Exception occurred"));
|
||||||
|
@ -20,6 +20,21 @@ class PrintConfig;
|
|||||||
class ProgressStatusBar;
|
class ProgressStatusBar;
|
||||||
class DynamicPrintConfig;
|
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
|
* @brief A boilerplate class for creating application logic. It should provide
|
||||||
* features as issue reporting and progress indication, etc...
|
* 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
|
* UI toolkit dependencies. We can implement it with any UI framework or make it
|
||||||
* a cli client.
|
* a cli client.
|
||||||
*/
|
*/
|
||||||
class AppControllerBoilerplate {
|
class AppControllerBase {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// A Progress indicator object smart pointer
|
using Ptr = std::shared_ptr<AppControllerBase>;
|
||||||
using ProgresIndicatorPtr = std::shared_ptr<ProgressIndicator>;
|
|
||||||
|
|
||||||
private:
|
inline virtual ~AppControllerBase() {}
|
||||||
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:
|
|
||||||
|
|
||||||
AppControllerBoilerplate();
|
|
||||||
~AppControllerBoilerplate();
|
|
||||||
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Query some paths from the user.
|
* @brief Query some paths from the user.
|
||||||
@ -69,23 +62,28 @@ public:
|
|||||||
* @param extensions Recognized file extensions.
|
* @param extensions Recognized file extensions.
|
||||||
* @return Returns a list of paths chosen by the user.
|
* @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& 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.
|
* @brief Same as query_destination_paths but works for directories only.
|
||||||
*/
|
*/
|
||||||
PathList query_destination_dirs(
|
virtual FilePathList query_destination_dirs(
|
||||||
const std::string& title) const;
|
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.
|
* @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& title,
|
||||||
const std::string& extensions,
|
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.
|
* @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
|
* @param brief A very brief description. Can be used for message dialog
|
||||||
* title.
|
* title.
|
||||||
*/
|
*/
|
||||||
bool report_issue(IssueType issuetype,
|
virtual bool report_issue(IssueType issuetype,
|
||||||
const std::string& description,
|
const std::string& description,
|
||||||
const std::string& brief);
|
const std::string& brief) = 0;
|
||||||
|
|
||||||
bool report_issue(IssueType issuetype,
|
|
||||||
const std::string& description);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the global progress indicator for the current controller.
|
* @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.
|
* 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
|
* @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
|
* @return Return true for the same caller thread that created this
|
||||||
* object and false for every other.
|
* object and false for every other.
|
||||||
*/
|
*/
|
||||||
bool is_main_thread() const;
|
virtual bool is_main_thread() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The frontend supports asynch execution.
|
* @brief The frontend supports asynch execution.
|
||||||
@ -138,11 +133,9 @@ public:
|
|||||||
* @return true if a job or method can be executed asynchronously, false
|
* @return true if a job or method can be executed asynchronously, false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
bool supports_asynch() const;
|
virtual bool supports_asynch() const = 0;
|
||||||
|
|
||||||
void process_events();
|
virtual void process_events() = 0;
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new progress indicator and return a smart pointer to it.
|
* @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.
|
* @param firstmsg The message for the first subtask to be displayed.
|
||||||
* @return Smart pointer to the created object.
|
* @return Smart pointer to the created object.
|
||||||
*/
|
*/
|
||||||
ProgresIndicatorPtr create_progress_indicator(
|
virtual ProgresIndicatorPtr create_progress_indicator(
|
||||||
unsigned statenum,
|
unsigned statenum,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& firstmsg) const;
|
const std::string& firstmsg = "") const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
ProgresIndicatorPtr create_progress_indicator(
|
/**
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
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,
|
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
|
// This is a global progress indicator placeholder. In the Slic3r UI it can
|
||||||
// contain the progress indicator on the statusbar.
|
// contain the progress indicator on the statusbar.
|
||||||
@ -185,7 +302,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Implementation of the printing logic.
|
* @brief Implementation of the printing logic.
|
||||||
*/
|
*/
|
||||||
class PrintController: public AppControllerBoilerplate {
|
class PrintController {
|
||||||
Print *m_print = nullptr;
|
Print *m_print = nullptr;
|
||||||
std::function<void()> m_rempools;
|
std::function<void()> m_rempools;
|
||||||
protected:
|
protected:
|
||||||
@ -241,7 +358,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Top level controller.
|
* @brief Top level controller.
|
||||||
*/
|
*/
|
||||||
class AppController: public AppControllerBoilerplate {
|
class AppController {
|
||||||
Model *m_model = nullptr;
|
Model *m_model = nullptr;
|
||||||
PrintController::Ptr printctl;
|
PrintController::Ptr printctl;
|
||||||
std::atomic<bool> m_arranging;
|
std::atomic<bool> m_arranging;
|
||||||
|
@ -25,40 +25,43 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
bool AppControllerBoilerplate::supports_asynch() const
|
bool AppControllerGui::supports_asynch() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppControllerBoilerplate::process_events()
|
void AppControllerGui::process_events()
|
||||||
{
|
{
|
||||||
wxYieldIfNeeded();
|
wxYieldIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
AppControllerBoilerplate::PathList
|
FilePathList AppControllerGui::query_destination_paths(
|
||||||
AppControllerBoilerplate::query_destination_paths(
|
|
||||||
const std::string &title,
|
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) );
|
wxFileDialog dlg(wxTheApp->GetTopWindow(), _(title) );
|
||||||
dlg.SetWildcard(extensions);
|
dlg.SetWildcard(extensions);
|
||||||
|
|
||||||
dlg.ShowModal();
|
dlg.SetFilename(hint);
|
||||||
|
|
||||||
|
FilePathList ret;
|
||||||
|
|
||||||
|
if(dlg.ShowModal() == wxID_OK) {
|
||||||
wxArrayString paths;
|
wxArrayString paths;
|
||||||
dlg.GetPaths(paths);
|
dlg.GetPaths(paths);
|
||||||
|
|
||||||
PathList ret(paths.size(), "");
|
|
||||||
for(auto& p : paths) ret.push_back(p.ToStdString());
|
for(auto& p : paths) ret.push_back(p.ToStdString());
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppControllerBoilerplate::Path
|
FilePath AppControllerGui::query_destination_path(
|
||||||
AppControllerBoilerplate::query_destination_path(
|
|
||||||
const std::string &title,
|
const std::string &title,
|
||||||
const std::string &extensions,
|
const std::string &extensions,
|
||||||
|
const std::string &/*functionid*/,
|
||||||
const std::string& hint) const
|
const std::string& hint) const
|
||||||
{
|
{
|
||||||
wxFileDialog dlg(wxTheApp->GetTopWindow(), _(title) );
|
wxFileDialog dlg(wxTheApp->GetTopWindow(), _(title) );
|
||||||
@ -66,16 +69,16 @@ AppControllerBoilerplate::query_destination_path(
|
|||||||
|
|
||||||
dlg.SetFilename(hint);
|
dlg.SetFilename(hint);
|
||||||
|
|
||||||
Path ret;
|
FilePath ret;
|
||||||
|
|
||||||
if(dlg.ShowModal() == wxID_OK) {
|
if(dlg.ShowModal() == wxID_OK) {
|
||||||
ret = Path(dlg.GetPath());
|
ret = FilePath(dlg.GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppControllerBoilerplate::report_issue(IssueType issuetype,
|
bool AppControllerGui::report_issue(IssueType issuetype,
|
||||||
const std::string &description,
|
const std::string &description,
|
||||||
const std::string &brief)
|
const std::string &brief)
|
||||||
{
|
{
|
||||||
@ -93,13 +96,6 @@ bool AppControllerBoilerplate::report_issue(IssueType issuetype,
|
|||||||
return ret != wxCANCEL;
|
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);
|
wxDEFINE_EVENT(PROGRESS_STATUS_UPDATE_EVENT, wxCommandEvent);
|
||||||
|
|
||||||
struct Zipper::Impl {
|
struct Zipper::Impl {
|
||||||
@ -235,8 +231,7 @@ public:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
AppControllerBoilerplate::ProgresIndicatorPtr
|
ProgresIndicatorPtr AppControllerGui::create_progress_indicator(
|
||||||
AppControllerBoilerplate::create_progress_indicator(
|
|
||||||
unsigned statenum,
|
unsigned statenum,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& firstmsg) const
|
const std::string& firstmsg) const
|
||||||
@ -251,20 +246,13 @@ AppControllerBoilerplate::create_progress_indicator(
|
|||||||
return pri;
|
return pri;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppControllerBoilerplate::ProgresIndicatorPtr
|
|
||||||
AppControllerBoilerplate::create_progress_indicator(
|
|
||||||
unsigned statenum, const std::string &title) const
|
|
||||||
{
|
|
||||||
return create_progress_indicator(statenum, title, std::string());
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class Wrapper: public ProgressIndicator, public wxEvtHandler {
|
class Wrapper: public ProgressIndicator, public wxEvtHandler {
|
||||||
ProgressStatusBar *m_sbar;
|
ProgressStatusBar *m_sbar;
|
||||||
using Base = ProgressIndicator;
|
using Base = ProgressIndicator;
|
||||||
wxString m_message;
|
wxString m_message;
|
||||||
AppControllerBoilerplate& m_ctl;
|
AppControllerBase& m_ctl;
|
||||||
|
|
||||||
void showProgress(bool show = true) {
|
void showProgress(bool show = true) {
|
||||||
m_sbar->show_progress(show);
|
m_sbar->show_progress(show);
|
||||||
@ -288,7 +276,7 @@ class Wrapper: public ProgressIndicator, public wxEvtHandler {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
inline Wrapper(ProgressStatusBar *sbar,
|
inline Wrapper(ProgressStatusBar *sbar,
|
||||||
AppControllerBoilerplate& ctl):
|
AppControllerBase& ctl):
|
||||||
m_sbar(sbar), m_ctl(ctl)
|
m_sbar(sbar), m_ctl(ctl)
|
||||||
{
|
{
|
||||||
Base::max(static_cast<float>(m_sbar->get_range()));
|
Base::max(static_cast<float>(m_sbar->get_range()));
|
||||||
@ -344,7 +332,8 @@ public:
|
|||||||
void AppController::set_global_progress_indicator(ProgressStatusBar *prsb)
|
void AppController::set_global_progress_indicator(ProgressStatusBar *prsb)
|
||||||
{
|
{
|
||||||
if(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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
|
#include "../AppController.hpp"
|
||||||
#include "WipeTowerDialog.hpp"
|
#include "WipeTowerDialog.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -1405,4 +1406,23 @@ void desktop_open_datadir_folder()
|
|||||||
#endif
|
#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>();
|
||||||
|
}
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
@ -42,6 +42,9 @@ class TabIface;
|
|||||||
class PreviewIface;
|
class PreviewIface;
|
||||||
class Print;
|
class Print;
|
||||||
class GCodePreviewData;
|
class GCodePreviewData;
|
||||||
|
class AppControllerBase;
|
||||||
|
|
||||||
|
using AppControllerPtr = std::shared_ptr<AppControllerBase>;
|
||||||
|
|
||||||
#define _(s) Slic3r::GUI::I18N::translate((s))
|
#define _(s) Slic3r::GUI::I18N::translate((s))
|
||||||
|
|
||||||
@ -129,6 +132,10 @@ ProgressStatusBar* get_progress_status_bar();
|
|||||||
wxNotebook * get_tab_panel();
|
wxNotebook * get_tab_panel();
|
||||||
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_modified();
|
||||||
const wxColour& get_label_clr_sys();
|
const wxColour& get_label_clr_sys();
|
||||||
const wxColour& get_label_clr_default();
|
const wxColour& get_label_clr_default();
|
||||||
|
@ -35,6 +35,12 @@ bool is_windows10()
|
|||||||
void set_wxapp(SV *ui)
|
void set_wxapp(SV *ui)
|
||||||
%code%{ Slic3r::GUI::set_wxapp((wxApp*)wxPli_sv_2_object(aTHX_ ui, "Wx::App")); %};
|
%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)
|
void set_progress_status_bar(ProgressStatusBar *prs)
|
||||||
%code%{ Slic3r::GUI::set_progress_status_bar(prs); %};
|
%code%{ Slic3r::GUI::set_progress_status_bar(prs); %};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user