This commit is contained in:
enricoturri1966 2020-12-08 15:56:08 +01:00
commit b7ac74bc42
53 changed files with 1789 additions and 915 deletions

View file

@ -7,6 +7,8 @@
#include "MainFrame.hpp"
#include "format.hpp"
#include <wx/clipbrd.h>
namespace Slic3r {
namespace GUI {
@ -297,6 +299,11 @@ AboutDialog::AboutDialog()
auto copy_rights_btn = new wxButton(this, m_copy_rights_btn_id, _L("Portions copyright")+dots);
buttons->Insert(0, copy_rights_btn, 0, wxLEFT, 5);
copy_rights_btn->Bind(wxEVT_BUTTON, &AboutDialog::onCopyrightBtn, this);
m_copy_version_btn_id = NewControlId();
auto copy_version_btn = new wxButton(this, m_copy_version_btn_id, _L("Copy Version Info"));
buttons->Insert(1, copy_version_btn, 0, wxLEFT, 5);
copy_version_btn->Bind(wxEVT_BUTTON, &AboutDialog::onCopyToClipboard, this);
this->SetEscapeId(wxID_CLOSE);
this->Bind(wxEVT_BUTTON, &AboutDialog::onCloseDialog, this, wxID_CLOSE);
@ -348,5 +355,12 @@ void AboutDialog::onCopyrightBtn(wxEvent &)
dlg.ShowModal();
}
void AboutDialog::onCopyToClipboard(wxEvent&)
{
wxTheClipboard->Open();
wxTheClipboard->SetData(new wxTextDataObject(_L("Version") + " " + std::string(SLIC3R_VERSION)));
wxTheClipboard->Close();
}
} // namespace GUI
} // namespace Slic3r

View file

@ -60,6 +60,7 @@ class AboutDialog : public DPIDialog
wxHtmlWindow* m_html;
wxStaticBitmap* m_logo;
int m_copy_rights_btn_id { wxID_ANY };
int m_copy_version_btn_id { wxID_ANY };
public:
AboutDialog();
@ -70,6 +71,7 @@ private:
void onLinkClicked(wxHtmlLinkEvent &event);
void onCloseDialog(wxEvent &);
void onCopyrightBtn(wxEvent &);
void onCopyToClipboard(wxEvent&);
};
} // namespace GUI

View file

@ -185,7 +185,7 @@ void BackgroundSlicingProcess::process_fff()
break;
}
m_print->set_status(95, _utf8(L("Running post-processing scripts")));
run_post_process_scripts(export_path, m_fff_print->config());
run_post_process_scripts(export_path, m_fff_print->full_print_config());
m_print->set_status(100, (boost::format(_utf8(L("G-code file exported to %1%"))) % export_path).str());
} else if (! m_upload_job.empty()) {
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id));
@ -538,7 +538,7 @@ void BackgroundSlicingProcess::prepare_upload()
if (copy_file(m_temp_output_path, source_path.string(), error_message) != SUCCESS) {
throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed")));
}
run_post_process_scripts(source_path.string(), m_fff_print->config());
run_post_process_scripts(source_path.string(), m_fff_print->full_print_config());
m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
} else {
m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());

View file

@ -2,6 +2,7 @@
#include "ConfigManipulation.hpp"
#include "I18N.hpp"
#include "GUI_App.hpp"
#include "format.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/PresetBundle.hpp"
@ -184,30 +185,21 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
}
if (config->option<ConfigOptionPercent>("fill_density")->value == 100) {
auto fill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->value;
std::string str_fill_pattern = "";
t_config_enum_values map_names = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->get_enum_values();
for (auto it : map_names) {
if (fill_pattern == it.second) {
str_fill_pattern = it.first;
break;
}
}
if (!str_fill_pattern.empty()) {
const std::vector<std::string>& external_fill_pattern = config->def()->get("top_fill_pattern")->enum_values;
bool correct_100p_fill = false;
for (const std::string& fill : external_fill_pattern)
{
if (str_fill_pattern == fill)
correct_100p_fill = true;
}
std::string fill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("fill_pattern")->serialize();
const auto &top_fill_pattern_values = config->def()->get("top_fill_pattern")->enum_values;
bool correct_100p_fill = std::find(top_fill_pattern_values.begin(), top_fill_pattern_values.end(), fill_pattern) != top_fill_pattern_values.end();
if (!correct_100p_fill) {
// get fill_pattern name from enum_labels for using this one at dialog_msg
str_fill_pattern = _utf8(config->def()->get("fill_pattern")->enum_labels[fill_pattern]);
if (!correct_100p_fill) {
wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density."))) % str_fill_pattern).str());
const ConfigOptionDef *fill_pattern_def = config->def()->get("fill_pattern");
assert(fill_pattern_def != nullptr);
auto it_pattern = std::find(fill_pattern_def->enum_values.begin(), fill_pattern_def->enum_values.end(), fill_pattern);
assert(it_pattern != fill_pattern_def->enum_values.end());
if (it_pattern != fill_pattern_def->enum_values.end()) {
wxString msg_text = GUI::format_wxstr(_L("The %1% infill pattern is not supposed to work at 100%% density."),
_(fill_pattern_def->enum_labels[it_pattern - fill_pattern_def->enum_values.begin()]));
if (is_global_config)
msg_text += "\n\n" + _(L("Shall I switch to rectilinear fill pattern?"));
wxMessageDialog dialog(nullptr, msg_text, _(L("Infill")),
msg_text += "\n\n" + _L("Shall I switch to rectilinear fill pattern?");
wxMessageDialog dialog(nullptr, msg_text, _L("Infill"),
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) );
DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal();
@ -315,6 +307,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle",
"wipe_tower_bridging", "wipe_tower_no_sparse_layers", "single_extruder_multi_material_priming" })
toggle_field(el, have_wipe_tower);
bool have_avoid_crossing_perimeters = config->opt_bool("avoid_crossing_perimeters");
toggle_field("avoid_crossing_perimeters_max_detour", have_avoid_crossing_perimeters);
}
void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/)

View file

@ -5,6 +5,7 @@
#include "wxExtensions.hpp"
#include "Plater.hpp"
#include "MainFrame.hpp"
#include "format.hpp"
#include "libslic3r/PrintConfig.hpp"
@ -12,6 +13,7 @@
#include <wx/numformatter.h>
#include <wx/tooltip.h>
#include <wx/notebook.h>
#include <wx/tokenzr.h>
#include <boost/algorithm/string/predicate.hpp>
#include "OG_CustomCtrl.hpp"
@ -52,6 +54,16 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/)
return s;
}
wxString get_thumbnails_string(const std::vector<Vec2d>& values)
{
wxString ret_str;
if (!values.empty())
for (auto el : values)
ret_str += wxString::Format("%ix%i, ", int(el[0]), int(el[1]));
return ret_str;
}
Field::~Field()
{
if (m_on_kill_focus)
@ -304,6 +316,56 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
m_value = std::string(str.ToUTF8().data());
break; }
case coPoints: {
std::vector<Vec2d> out_values;
str.Replace(" ", wxEmptyString, true);
if (!str.IsEmpty()) {
bool invalid_val = false;
bool out_of_range_val = false;
wxStringTokenizer thumbnails(str, ",");
while (thumbnails.HasMoreTokens()) {
wxString token = thumbnails.GetNextToken();
double x, y;
wxStringTokenizer thumbnail(token, "x");
if (thumbnail.HasMoreTokens()) {
wxString x_str = thumbnail.GetNextToken();
if (x_str.ToDouble(&x) && thumbnail.HasMoreTokens()) {
wxString y_str = thumbnail.GetNextToken();
if (y_str.ToDouble(&y) && !thumbnail.HasMoreTokens()) {
if (0 < x && x < 1000 && 0 < y && y < 1000) {
out_values.push_back(Vec2d(x, y));
continue;
}
out_of_range_val = true;
break;
}
}
}
invalid_val = true;
break;
}
if (out_of_range_val) {
wxString text_value;
if (!m_value.empty())
text_value = get_thumbnails_string(boost::any_cast<std::vector<Vec2d>>(m_value));
set_value(text_value, true);
show_error(m_parent, _L("Input value is out of range")
);
}
else if (invalid_val) {
wxString text_value;
if (!m_value.empty())
text_value = get_thumbnails_string(boost::any_cast<std::vector<Vec2d>>(m_value));
set_value(text_value, true);
show_error(m_parent, format_wxstr(_L("Invalid input format. It must be represented like \"%1%\""),"XxY, XxY, ..." ));
}
}
m_value = out_values;
break; }
default:
break;
}
@ -371,6 +433,9 @@ void TextCtrl::BUILD() {
text_value = vec->get_at(m_opt_idx);
break;
}
case coPoints:
text_value = get_thumbnails_string(m_opt.get_default_value<ConfigOptionPoints>()->values);
break;
default:
break;
}

View file

@ -37,6 +37,7 @@ using t_change = std::function<void(const t_config_option_key&, const boost::any
using t_back_to_init = std::function<void(const std::string&)>;
wxString double_to_string(double const value, const int max_precision = 4);
wxString get_thumbnails_string(const std::vector<Vec2d>& values);
class Field {
protected:

View file

@ -1679,22 +1679,20 @@ void GLCanvas3D::render()
if (wxGetApp().plater()->is_render_statistic_dialog_visible()) {
ImGuiWrapper& imgui = *wxGetApp().imgui();
imgui.begin(std::string("Render statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
imgui.text("Last frame: ");
imgui.text("Last frame:");
ImGui::SameLine();
imgui.text(std::to_string(m_render_stats.last_frame));
long long average = m_render_stats.get_average();
imgui.text(std::to_string(average));
ImGui::SameLine();
imgui.text(" ms");
imgui.text("FPS: ");
imgui.text("ms");
imgui.text("FPS:");
ImGui::SameLine();
imgui.text(std::to_string(static_cast<int>(1000.0f / static_cast<float>(m_render_stats.last_frame))));
// imgui.text("Imgui FPS: ");
// ImGui::SameLine();
// imgui.text(std::to_string(static_cast<int>(ImGui::GetIO().Framerate)));
imgui.text(std::to_string((average == 0) ? 0 : static_cast<int>(1000.0f / static_cast<float>(average))));
ImGui::Separator();
imgui.text("Compressed textures: ");
imgui.text("Compressed textures:");
ImGui::SameLine();
imgui.text(OpenGLManager::are_compressed_textures_supported() ? "supported" : "not supported");
imgui.text("Max texture size: ");
imgui.text("Max texture size:");
ImGui::SameLine();
imgui.text(std::to_string(OpenGLManager::get_gl_info().get_max_tex_size()));
imgui.end();
@ -1707,8 +1705,6 @@ void GLCanvas3D::render()
std::string tooltip;
// Negative coordinate means out of the window, likely because the window was deactivated.
// In that case the tooltip should be hidden.
if (m_mouse.position.x() >= 0. && m_mouse.position.y() >= 0.) {
@ -1745,7 +1741,7 @@ void GLCanvas3D::render()
#if ENABLE_RENDER_STATISTICS
auto end_time = std::chrono::high_resolution_clock::now();
m_render_stats.last_frame = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
m_render_stats.add_frame(std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count());
#endif // ENABLE_RENDER_STATISTICS
}
@ -2491,7 +2487,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
break;
#if ENABLE_CTRL_M_ON_WINDOWS
#ifdef __APPLE__
case 'm':
case 'M':
#else /* __APPLE__ */
case WXK_CONTROL_M:
#endif /* __APPLE__ */
{
#ifdef _WIN32
if (wxGetApp().app_config->get("use_legacy_3DConnexion") == "1") {
@ -3779,7 +3780,7 @@ GLCanvas3D::WipeTowerInfo GLCanvas3D::get_wipe_tower_info() const
m_config->opt_float("wipe_tower_y"));
wti.m_rotation = (M_PI/180.) * m_config->opt_float("wipe_tower_rotation_angle");
const BoundingBoxf3& bb = vol->bounding_box();
wti.m_bb_size = Vec2d(bb.size().x(), bb.size().y());
wti.m_bb = BoundingBoxf{to_2d(bb.min), to_2d(bb.max)};
break;
}
}

View file

@ -320,11 +320,22 @@ class GLCanvas3D
};
#if ENABLE_RENDER_STATISTICS
struct RenderStats
class RenderStats
{
long long last_frame;
std::queue<std::pair<long long, long long>> m_frames;
long long m_curr_total{ 0 };
RenderStats() : last_frame(0) {}
public:
void add_frame(long long frame) {
long long now = wxGetLocalTimeMillis().GetValue();
if (!m_frames.empty() && now - m_frames.front().first > 1000) {
m_curr_total -= m_frames.front().second;
m_frames.pop();
}
m_curr_total += frame;
m_frames.push({ now, frame });
}
long long get_average() const { return m_frames.empty() ? 0 : m_curr_total / m_frames.size(); }
};
#endif // ENABLE_RENDER_STATISTICS
@ -665,8 +676,8 @@ public:
class WipeTowerInfo {
protected:
Vec2d m_pos = {std::nan(""), std::nan("")};
Vec2d m_bb_size = {0., 0.};
double m_rotation = 0.;
BoundingBoxf m_bb;
friend class GLCanvas3D;
public:
@ -677,7 +688,7 @@ public:
inline const Vec2d& pos() const { return m_pos; }
inline double rotation() const { return m_rotation; }
inline const Vec2d bb_size() const { return m_bb_size; }
inline const Vec2d bb_size() const { return m_bb.size(); }
void apply_wipe_tower() const;
};

View file

@ -201,7 +201,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
}
break;
case coPoints:{
if (opt_key.compare("bed_shape") == 0) {
if (opt_key == "bed_shape" || opt_key == "thumbnails") {
config.option<ConfigOptionPoints>(opt_key)->values = boost::any_cast<std::vector<Vec2d>>(value);
break;
}

View file

@ -933,13 +933,7 @@ bool GUI_App::on_init_inner()
load_current_presets();
mainframe->Show(true);
/* Temporary workaround for the correct behavior of the Scrolled sidebar panel:
* change min hight of object list to the normal min value (15 * wxGetApp().em_unit())
* after first whole Mainframe updating/layouting
*/
const int list_min_height = 15 * em_unit();
if (obj_list()->GetMinSize().GetY() > list_min_height)
obj_list()->SetMinSize(wxSize(-1, list_min_height));
obj_list()->set_min_height();
update_mode(); // update view mode after fix of the object_list size
@ -1150,13 +1144,8 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
mainframe->Show(true);
dlg.Update(90, _L("Loading of a mode view") + dots);
/* Temporary workaround for the correct behavior of the Scrolled sidebar panel:
* change min hight of object list to the normal min value (15 * wxGetApp().em_unit())
* after first whole Mainframe updating/layouting
*/
const int list_min_height = 15 * em_unit();
if (obj_list()->GetMinSize().GetY() > list_min_height)
obj_list()->SetMinSize(wxSize(-1, list_min_height));
obj_list()->set_min_height();
update_mode();
// #ys_FIXME_delete_after_testing Do we still need this ?
@ -1582,13 +1571,16 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
ConfigSnapshotDialog dlg(Slic3r::GUI::Config::SnapshotDB::singleton(), on_snapshot);
dlg.ShowModal();
if (!dlg.snapshot_to_activate().empty()) {
if (!Config::SnapshotDB::singleton().is_on_snapshot(*app_config))
if (! Config::SnapshotDB::singleton().is_on_snapshot(*app_config))
Config::SnapshotDB::singleton().take_snapshot(*app_config, Config::Snapshot::SNAPSHOT_BEFORE_ROLLBACK);
app_config->set("on_snapshot",
Config::SnapshotDB::singleton().restore_snapshot(dlg.snapshot_to_activate(), *app_config).id);
preset_bundle->load_presets(*app_config);
// Load the currently selected preset into the GUI, update the preset selection box.
load_current_presets();
try {
app_config->set("on_snapshot", Config::SnapshotDB::singleton().restore_snapshot(dlg.snapshot_to_activate(), *app_config).id);
preset_bundle->load_presets(*app_config);
// Load the currently selected preset into the GUI, update the preset selection box.
load_current_presets();
} catch (std::exception &ex) {
GUI::show_error(nullptr, _L("Failed to activate configuration snapshot.") + "\n" + into_u8(ex.what()));
}
}
}
break;

View file

@ -191,7 +191,7 @@ ObjectList::ObjectList(wxWindow* parent) :
// Bind(wxEVT_KEY_DOWN, &ObjectList::OnChar, this);
{
// Accelerators
wxAcceleratorEntry entries[8];
wxAcceleratorEntry entries[10];
entries[0].Set(wxACCEL_CTRL, (int) 'C', wxID_COPY);
entries[1].Set(wxACCEL_CTRL, (int) 'X', wxID_CUT);
entries[2].Set(wxACCEL_CTRL, (int) 'V', wxID_PASTE);
@ -200,7 +200,9 @@ ObjectList::ObjectList(wxWindow* parent) :
entries[5].Set(wxACCEL_CTRL, (int) 'Y', wxID_REDO);
entries[6].Set(wxACCEL_NORMAL, WXK_DELETE, wxID_DELETE);
entries[7].Set(wxACCEL_NORMAL, WXK_BACK, wxID_DELETE);
wxAcceleratorTable accel(8, entries);
entries[8].Set(wxACCEL_NORMAL, int('+'), wxID_ADD);
entries[9].Set(wxACCEL_NORMAL, int('-'), wxID_REMOVE);
wxAcceleratorTable accel(10, entries);
SetAcceleratorTable(accel);
this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->copy(); }, wxID_COPY);
@ -209,6 +211,8 @@ ObjectList::ObjectList(wxWindow* parent) :
this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->remove(); }, wxID_DELETE);
this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->undo(); }, wxID_UNDO);
this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->redo(); }, wxID_REDO);
this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->increase_instances(); }, wxID_ADD);
this->Bind(wxEVT_MENU, [this](wxCommandEvent &evt) { this->decrease_instances(); }, wxID_REMOVE);
}
#else //__WXOSX__
Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX
@ -254,6 +258,18 @@ ObjectList::~ObjectList()
{
}
void ObjectList::set_min_height()
{
/* Temporary workaround for the correct behavior of the Scrolled sidebar panel:
* change min hight of object list to the normal min value (35 * wxGetApp().em_unit())
* after first whole Mainframe updating/layouting
*/
const int list_min_height = 35 * wxGetApp().em_unit();
if (this->GetMinSize().GetY() > list_min_height)
this->SetMinSize(wxSize(-1, list_min_height));
}
void ObjectList::create_objects_ctrl()
{
/* Temporary workaround for the correct behavior of the Scrolled sidebar panel:
@ -1092,6 +1108,16 @@ void ObjectList::redo()
wxGetApp().plater()->redo();
}
void ObjectList::increase_instances()
{
wxGetApp().plater()->increase_instances(1);
}
void ObjectList::decrease_instances()
{
wxGetApp().plater()->decrease_instances(1);
}
#ifndef __WXOSX__
void ObjectList::key_event(wxKeyEvent& event)
{
@ -1116,6 +1142,10 @@ void ObjectList::key_event(wxKeyEvent& event)
redo();
else if (wxGetKeyState(wxKeyCode('Z')) && wxGetKeyState(WXK_CONTROL))
undo();
else if (event.GetUnicodeKey() == '+')
increase_instances();
else if (event.GetUnicodeKey() == '-')
decrease_instances();
else
event.Skip();
}

View file

@ -207,6 +207,7 @@ public:
ObjectList(wxWindow* parent);
~ObjectList();
void set_min_height();
std::map<std::string, wxBitmap> CATEGORY_ICON;
@ -257,6 +258,8 @@ public:
bool paste_from_clipboard();
void undo();
void redo();
void increase_instances();
void decrease_instances();
void get_settings_choice(const wxString& category_name);
void get_freq_settings_choice(const wxString& bundle_name);

View file

@ -30,11 +30,10 @@ public:
ArrangePolygon get_arrange_polygon() const
{
Polygon ap({
{coord_t(0), coord_t(0)},
{scaled(m_bb_size(X)), coord_t(0)},
{scaled(m_bb_size)},
{coord_t(0), scaled(m_bb_size(Y))},
{coord_t(0), coord_t(0)},
{scaled(m_bb.min)},
{scaled(m_bb.max.x()), scaled(m_bb.min.y())},
{scaled(m_bb.max)},
{scaled(m_bb.min.x()), scaled(m_bb.max.y())}
});
ArrangePolygon ret;

View file

@ -132,6 +132,7 @@ void KBShortcutsDialog::fill_shortcuts()
{ ctrl + "5", L("Switch to 3D") },
{ ctrl + "6", L("Switch to Preview") },
{ ctrl + "J", L("Print host upload queue") },
{ ctrl + "Shift+" + "I", L("Open new instance") },
// View
{ "0-6", L("Camera view") },
{ "E", L("Show/Hide object/instance labels") },

View file

@ -1191,9 +1191,8 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue", nullptr, []() {return true; }, this);
windowMenu->AppendSeparator();
append_menu_item(windowMenu, wxID_ANY, _L("Open new instance") + "\tCtrl+I", _L("Open a new PrusaSlicer instance"),
append_menu_item(windowMenu, wxID_ANY, _L("Open new instance") + "\tCtrl+Shift+I", _L("Open a new PrusaSlicer instance"),
[this](wxCommandEvent&) { start_new_slicer(); }, "", nullptr, [this]() {return m_plater != nullptr && wxGetApp().app_config->get("single_instance") != "1"; }, this);
}
// View menu

View file

@ -178,7 +178,7 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
#ifdef __WXMSW__
// when we use 2 monitors with different DPIs, GetTextExtent() return value for the primary display
// so, use dc.GetMultiLineTextExtent on Windows
wxPaintDC dc(this);
wxClientDC dc(this);
dc.SetFont(m_font);
dc.GetMultiLineTextExtent(label, &label_w, &label_h);
#else

View file

@ -25,20 +25,22 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id) {
const t_field& OptionsGroup::build_field(const t_config_option_key& id, const ConfigOptionDef& opt) {
// Check the gui_type field first, fall through
// is the normal type.
if (opt.gui_type.compare("select") == 0) {
} else if (opt.gui_type.compare("select_open") == 0) {
if (opt.gui_type == "select") {
} else if (opt.gui_type == "select_open") {
m_fields.emplace(id, std::move(Choice::Create<Choice>(this->ctrl_parent(), opt, id)));
} else if (opt.gui_type.compare("color") == 0) {
} else if (opt.gui_type == "color") {
m_fields.emplace(id, std::move(ColourPicker::Create<ColourPicker>(this->ctrl_parent(), opt, id)));
} else if (opt.gui_type.compare("f_enum_open") == 0 ||
opt.gui_type.compare("i_enum_open") == 0 ||
opt.gui_type.compare("i_enum_closed") == 0) {
} else if (opt.gui_type == "f_enum_open" ||
opt.gui_type == "i_enum_open" ||
opt.gui_type == "i_enum_closed") {
m_fields.emplace(id, std::move(Choice::Create<Choice>(this->ctrl_parent(), opt, id)));
} else if (opt.gui_type.compare("slider") == 0) {
} else if (opt.gui_type == "slider") {
m_fields.emplace(id, std::move(SliderCtrl::Create<SliderCtrl>(this->ctrl_parent(), opt, id)));
} else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl
} else if (opt.gui_type.compare("legend") == 0) { // StaticText
} else if (opt.gui_type == "i_spin") { // Spinctrl
} else if (opt.gui_type == "legend") { // StaticText
m_fields.emplace(id, std::move(StaticText::Create<StaticText>(this->ctrl_parent(), opt, id)));
} else if (opt.gui_type == "one_string") {
m_fields.emplace(id, std::move(TextCtrl::Create<TextCtrl>(this->ctrl_parent(), opt, id)));
} else {
switch (opt.type) {
case coFloatOrPercent:
@ -837,9 +839,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
}
if (config.option<ConfigOptionStrings>(opt_key)->values.empty())
ret = text_value;
else if (opt->gui_flags.compare("serialized") == 0) {
else if (opt->gui_flags == "serialized") {
std::vector<std::string> values = config.option<ConfigOptionStrings>(opt_key)->values;
if (!values.empty() && values[0].compare("") != 0)
if (!values.empty() && !values[0].empty())
for (auto el : values)
text_value += el + ";";
ret = text_value;
@ -897,6 +899,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
case coPoints:
if (opt_key == "bed_shape")
ret = config.option<ConfigOptionPoints>(opt_key)->values;
if (opt_key == "thumbnails")
ret = get_thumbnails_string(config.option<ConfigOptionPoints>(opt_key)->values);
else
ret = config.option<ConfigOptionPoints>(opt_key)->get_at(idx);
break;

View file

@ -2399,18 +2399,18 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
wxGetApp().sidebar().update_ui_from_settings();
};
if (imperial_units)
convert_from_imperial_units(model);
else if (model.looks_like_imperial_units()) {
wxMessageDialog msg_dlg(q, format_wxstr(_L(
"Some object(s) in file %s looks like saved in inches.\n"
"Should I consider them as a saved in inches and convert them?"), from_path(filename)) + "\n",
_L("The object appears to be saved in inches"), wxICON_WARNING | wxYES | wxNO);
if (msg_dlg.ShowModal() == wxID_YES)
if (!is_project_file) {
if (imperial_units)
convert_from_imperial_units(model);
}
else if (model.looks_like_imperial_units()) {
wxMessageDialog msg_dlg(q, format_wxstr(_L(
"Some object(s) in file %s looks like saved in inches.\n"
"Should I consider them as a saved in inches and convert them?"), from_path(filename)) + "\n",
_L("The object appears to be saved in inches"), wxICON_WARNING | wxYES | wxNO);
if (msg_dlg.ShowModal() == wxID_YES)
convert_from_imperial_units(model);
}
if (! is_project_file) {
if (model.looks_like_multipart_object()) {
wxMessageDialog msg_dlg(q, _L(
"This file contains several objects positioned at multiple heights.\n"

View file

@ -94,7 +94,7 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
int cnt = 0;
if ( (type == Preset::TYPE_SLA_MATERIAL || type == Preset::TYPE_PRINTER) && opt_key != "bed_shape")
if ( (type == Preset::TYPE_SLA_MATERIAL || type == Preset::TYPE_PRINTER) && opt_key != "bed_shape" && opt_key != "thumbnails")
switch (config->option(opt_key)->type())
{
case coInts: change_opt_key<ConfigOptionInts >(opt_key, config, cnt); break;

View file

@ -109,14 +109,14 @@ Tab::Tab(wxNotebook* parent, const wxString& title, Preset::Type type) :
m_compatible_printers.type = Preset::TYPE_PRINTER;
m_compatible_printers.key_list = "compatible_printers";
m_compatible_printers.key_condition = "compatible_printers_condition";
m_compatible_printers.dialog_title = _(L("Compatible printers")).ToUTF8();
m_compatible_printers.dialog_label = _(L("Select the printers this profile is compatible with.")).ToUTF8();
m_compatible_printers.dialog_title = _L("Compatible printers");
m_compatible_printers.dialog_label = _L("Select the printers this profile is compatible with.");
m_compatible_prints.type = Preset::TYPE_PRINT;
m_compatible_prints.key_list = "compatible_prints";
m_compatible_prints.key_condition = "compatible_prints_condition";
m_compatible_prints.dialog_title = _(L("Compatible print profiles")).ToUTF8();
m_compatible_prints.dialog_label = _(L("Select the print profiles this profile is compatible with.")).ToUTF8();
m_compatible_prints.dialog_title = _L("Compatible print profiles");
m_compatible_prints.dialog_label = _L("Select the print profiles this profile is compatible with.");
wxGetApp().tabs_list.push_back(this);
@ -542,7 +542,7 @@ void Tab::decorate()
wxColour* colored_label_clr = nullptr;
if (opt.first == "bed_shape" || opt.first == "filament_ramming_parameters" ||
opt.first == "compatible_prints" || opt.first == "compatible_printers")
opt.first == "compatible_prints" || opt.first == "compatible_printers")
colored_label_clr = (m_colored_Label_colors.find(opt.first) == m_colored_Label_colors.end()) ? nullptr : m_colored_Label_colors.at(opt.first);
if (!colored_label_clr) {
@ -653,7 +653,7 @@ void TabPrinter::init_options_list()
for (const auto opt_key : m_config->keys())
{
if (opt_key == "bed_shape") {
if (opt_key == "bed_shape" || opt_key == "thumbnails") {
m_options_list.emplace(opt_key, m_opt_status_value);
continue;
}
@ -1424,6 +1424,7 @@ void TabPrint::build()
optgroup->append_single_option_line("extra_perimeters", category_path + "extra-perimeters-if-needed");
optgroup->append_single_option_line("ensure_vertical_shell_thickness", category_path + "ensure-vertical-shell-thickness");
optgroup->append_single_option_line("avoid_crossing_perimeters", category_path + "avoid-crossing-perimeters");
optgroup->append_single_option_line("avoid_crossing_perimeters_max_detour", category_path + "avoid_crossing_perimeters_max_detour");
optgroup->append_single_option_line("thin_walls", category_path + "detect-thin-walls");
optgroup->append_single_option_line("overhangs", category_path + "detect-bridging-perimeters");
@ -2173,6 +2174,11 @@ void TabPrinter::build_fff()
optgroup = page->new_optgroup(L("Firmware"));
optgroup->append_single_option_line("gcode_flavor");
option = optgroup->get_option("thumbnails");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
optgroup->append_single_option_line("silent_mode");
optgroup->append_single_option_line("remaining_times");

View file

@ -136,8 +136,8 @@ protected:
ScalableButton *btn = nullptr;
std::string key_list; // "compatible_printers"
std::string key_condition;
std::string dialog_title;
std::string dialog_label;
wxString dialog_title;
wxString dialog_label;
};
PresetDependencies m_compatible_printers;
PresetDependencies m_compatible_prints;

View file

@ -968,6 +968,9 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig&
BedShape shape(*config.option<ConfigOptionPoints>(opt_key));
return shape.get_full_name_with_params();
}
if (opt_key == "thumbnails")
return get_thumbnails_string(config.option<ConfigOptionPoints>(opt_key)->values);
Vec2d val = config.opt<ConfigOptionPoints>(opt_key)->get_at(opt_idx);
return from_u8((boost::format("[%1%]") % ConfigOptionPoint(val).serialize()).str());
}