Merge branch 'master' of https://github.com/prusa3d/Slic3r into et_canvas_gui_refactoring
This commit is contained in:
commit
aca78cfba2
@ -80,9 +80,8 @@ public:
|
|||||||
// Provokes static_assert in the right way.
|
// Provokes static_assert in the right way.
|
||||||
template<class T = void> struct VeryFalse { static const bool value = false; };
|
template<class T = void> struct VeryFalse { static const bool value = false; };
|
||||||
|
|
||||||
// This has to be explicitly implemented in the gui layer or a default zlib
|
// This can be explicitly implemented in the gui layer or the default Zipper
|
||||||
// based implementation is needed. I don't have time for that and I'm delegating
|
// API in libslic3r with minz.
|
||||||
// the implementation to the gui layer where the gui toolkit can cover this.
|
|
||||||
template<class Fmt> class LayerWriter {
|
template<class Fmt> class LayerWriter {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -91,21 +90,28 @@ public:
|
|||||||
"No layer writer implementation provided!");
|
"No layer writer implementation provided!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should create a new file within the zip with the given filename. It
|
||||||
|
// should also finish any previous entry.
|
||||||
void next_entry(const std::string& /*fname*/) {}
|
void next_entry(const std::string& /*fname*/) {}
|
||||||
|
|
||||||
// binary entry
|
// Should create a new file within the archive and write the provided data.
|
||||||
void binary_entry(const std::string& /*fname*/,
|
void binary_entry(const std::string& /*fname*/,
|
||||||
const std::uint8_t* buf, size_t len);
|
const std::uint8_t* buf, size_t len);
|
||||||
|
|
||||||
|
// Get the name of the archive but only the name part without the path or
|
||||||
|
// the extension.
|
||||||
std::string get_name() { return ""; }
|
std::string get_name() { return ""; }
|
||||||
|
|
||||||
|
// Test whether the object can still be used for writing.
|
||||||
bool is_ok() { return false; }
|
bool is_ok() { return false; }
|
||||||
|
|
||||||
|
// Write some data (text) into the current file (entry) within the archive.
|
||||||
template<class T> LayerWriter& operator<<(T&& /*arg*/) {
|
template<class T> LayerWriter& operator<<(T&& /*arg*/) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {}
|
// Flush the current entry into the archive.
|
||||||
|
void finalize() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implementation for PNG raster output
|
// Implementation for PNG raster output
|
||||||
@ -267,7 +273,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.close();
|
writer.finalize();
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << e.what();
|
BOOST_LOG_TRIVIAL(error) << e.what();
|
||||||
// Rethrow the exception
|
// Rethrow the exception
|
||||||
|
@ -322,18 +322,18 @@ template<> class LayerWriter<SLAminzZipper> {
|
|||||||
Zipper m_zip;
|
Zipper m_zip;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline LayerWriter(const std::string& zipfile_path): m_zip(zipfile_path) {}
|
LayerWriter(const std::string& zipfile_path): m_zip(zipfile_path) {}
|
||||||
|
|
||||||
inline void next_entry(const std::string& fname) { m_zip.add_entry(fname); }
|
void next_entry(const std::string& fname) { m_zip.add_entry(fname); }
|
||||||
|
|
||||||
inline void binary_entry(const std::string& fname,
|
void binary_entry(const std::string& fname,
|
||||||
const std::uint8_t* buf,
|
const std::uint8_t* buf,
|
||||||
size_t l)
|
size_t l)
|
||||||
{
|
{
|
||||||
m_zip.add_entry(fname, buf, l);
|
m_zip.add_entry(fname, buf, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string get_name() const {
|
std::string get_name() const {
|
||||||
return m_zip.get_name();
|
return m_zip.get_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,7 +345,11 @@ public:
|
|||||||
return true; // m_zip blows up if something goes wrong...
|
return true; // m_zip blows up if something goes wrong...
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void close() { m_zip.close(); }
|
// After finalize, no writing to the archive will have an effect. The only
|
||||||
|
// valid operation is to dispose the object calling the destructor which
|
||||||
|
// should close the file. This method can throw and signal potential errors
|
||||||
|
// when flushing the archive. This is why its present.
|
||||||
|
void finalize() { m_zip.finalize(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,6 +111,11 @@ public:
|
|||||||
{
|
{
|
||||||
throw std::runtime_error(formatted_errorstr());
|
throw std::runtime_error(formatted_errorstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_alive()
|
||||||
|
{
|
||||||
|
return arch.m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Zipper::Zipper(const std::string &zipfname, e_compression compression)
|
Zipper::Zipper(const std::string &zipfname, e_compression compression)
|
||||||
@ -129,11 +134,19 @@ Zipper::Zipper(const std::string &zipfname, e_compression compression)
|
|||||||
|
|
||||||
Zipper::~Zipper()
|
Zipper::~Zipper()
|
||||||
{
|
{
|
||||||
try {
|
if(m_impl->is_alive()) {
|
||||||
close();
|
// Flush the current entry if not finished yet.
|
||||||
} catch(...) {
|
try { finish_entry(); } catch(...) {
|
||||||
BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
|
BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mz_zip_writer_finalize_archive(&m_impl->arch))
|
||||||
|
BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The file should be closed no matter what...
|
||||||
|
if(!mz_zip_writer_end(&m_impl->arch))
|
||||||
|
BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr();
|
||||||
}
|
}
|
||||||
|
|
||||||
Zipper::Zipper(Zipper &&m):
|
Zipper::Zipper(Zipper &&m):
|
||||||
@ -152,12 +165,16 @@ Zipper &Zipper::operator=(Zipper &&m) {
|
|||||||
|
|
||||||
void Zipper::add_entry(const std::string &name)
|
void Zipper::add_entry(const std::string &name)
|
||||||
{
|
{
|
||||||
|
if(!m_impl->is_alive()) return;
|
||||||
|
|
||||||
finish_entry(); // finish previous business
|
finish_entry(); // finish previous business
|
||||||
m_entry = name;
|
m_entry = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zipper::add_entry(const std::string &name, const uint8_t *data, size_t l)
|
void Zipper::add_entry(const std::string &name, const uint8_t *data, size_t l)
|
||||||
{
|
{
|
||||||
|
if(!m_impl->is_alive()) return;
|
||||||
|
|
||||||
finish_entry();
|
finish_entry();
|
||||||
mz_uint cmpr = MZ_NO_COMPRESSION;
|
mz_uint cmpr = MZ_NO_COMPRESSION;
|
||||||
switch (m_compression) {
|
switch (m_compression) {
|
||||||
@ -175,7 +192,9 @@ void Zipper::add_entry(const std::string &name, const uint8_t *data, size_t l)
|
|||||||
|
|
||||||
void Zipper::finish_entry()
|
void Zipper::finish_entry()
|
||||||
{
|
{
|
||||||
if(!m_data.empty() > 0 && !m_entry.empty()) {
|
if(!m_impl->is_alive()) return;
|
||||||
|
|
||||||
|
if(!m_data.empty() && !m_entry.empty()) {
|
||||||
mz_uint compression = MZ_NO_COMPRESSION;
|
mz_uint compression = MZ_NO_COMPRESSION;
|
||||||
|
|
||||||
switch (m_compression) {
|
switch (m_compression) {
|
||||||
@ -198,12 +217,12 @@ std::string Zipper::get_name() const {
|
|||||||
return boost::filesystem::path(m_impl->m_zipname).stem().string();
|
return boost::filesystem::path(m_impl->m_zipname).stem().string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zipper::close()
|
void Zipper::finalize()
|
||||||
{
|
{
|
||||||
finish_entry();
|
finish_entry();
|
||||||
|
|
||||||
if(!mz_zip_writer_finalize_archive(&m_impl->arch)) m_impl->blow_up();
|
if(m_impl->is_alive()) if(!mz_zip_writer_finalize_archive(&m_impl->arch))
|
||||||
if(!mz_zip_writer_end(&m_impl->arch)) m_impl->blow_up();
|
m_impl->blow_up();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
void add_entry(const std::string& name);
|
void add_entry(const std::string& name);
|
||||||
|
|
||||||
/// Add a new binary file entry with an instantly given byte buffer.
|
/// Add a new binary file entry with an instantly given byte buffer.
|
||||||
|
/// This method throws exactly like finish_entry() does.
|
||||||
void add_entry(const std::string& name, const std::uint8_t* data, size_t l);
|
void add_entry(const std::string& name, const std::uint8_t* data, size_t l);
|
||||||
|
|
||||||
// Writing data to the archive works like with standard streams. The target
|
// Writing data to the archive works like with standard streams. The target
|
||||||
@ -74,12 +75,16 @@ public:
|
|||||||
/// buffer and ones an entry is added, the buffer will bind to the new entry
|
/// buffer and ones an entry is added, the buffer will bind to the new entry
|
||||||
/// If the buffer was written, but no entry was added, the buffer will be
|
/// If the buffer was written, but no entry was added, the buffer will be
|
||||||
/// cleared after this call.
|
/// cleared after this call.
|
||||||
|
///
|
||||||
|
/// This method will throw a runtime exception if an error occures. The
|
||||||
|
/// entry will still be open (with the data intact) but the state of the
|
||||||
|
/// file is up to minz after the erroneous write.
|
||||||
void finish_entry();
|
void finish_entry();
|
||||||
|
|
||||||
/// Gets the name of the archive without the path or extension.
|
/// Gets the name of the archive without the path or extension.
|
||||||
std::string get_name() const;
|
std::string get_name() const;
|
||||||
|
|
||||||
void close();
|
void finalize();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -649,20 +649,16 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
|||||||
}
|
}
|
||||||
case ConfigMenuLanguage:
|
case ConfigMenuLanguage:
|
||||||
{
|
{
|
||||||
/* Before change application language, let's check unsaved changes
|
/* Before change application language, let's check unsaved changes on 3D-Scene
|
||||||
* and draw user's attention to the application restarting after a language change
|
* and draw user's attention to the application restarting after a language change
|
||||||
*/
|
*/
|
||||||
wxMessageDialog dialog(nullptr,
|
wxMessageDialog dialog(nullptr,
|
||||||
_(L("Application will be restarted after language change, "
|
_(L("Application will be restarted after language change.")) + "\n" +
|
||||||
"and 3D-Scene will be cleaned.")) + "\n" +
|
_(L("3D-Scene will be cleaned.")) + "\n\n" +
|
||||||
_(L("Please, check your changes before.")) + "\n\n" +
|
_(L("Please, check your changes before.")),
|
||||||
_(L("Continue anyway?")),
|
|
||||||
_(L("Attention!")),
|
_(L("Attention!")),
|
||||||
wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
|
wxICON_QUESTION | wxOK | wxCANCEL);
|
||||||
if ( dialog.ShowModal() != wxID_YES)
|
if ( dialog.ShowModal() == wxID_CANCEL)
|
||||||
return;
|
|
||||||
|
|
||||||
if (!wxGetApp().check_unsaved_changes())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxArrayString names;
|
wxArrayString names;
|
||||||
|
@ -228,6 +228,21 @@ int ObjectList::get_selected_obj_idx() const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynamicPrintConfig& ObjectList::get_item_config(const wxDataViewItem& item) const
|
||||||
|
{
|
||||||
|
assert(item);
|
||||||
|
const ItemType type = m_objects_model->GetItemType(item);
|
||||||
|
|
||||||
|
const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) :
|
||||||
|
m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item));
|
||||||
|
|
||||||
|
const int vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1;
|
||||||
|
|
||||||
|
assert(obj_idx >= 0 || ((type & itVolume) && vol_idx >=0));
|
||||||
|
return type & itObject|itInstance ? (*m_objects)[obj_idx]->config :
|
||||||
|
(*m_objects)[obj_idx]->volumes[vol_idx]->config;
|
||||||
|
}
|
||||||
|
|
||||||
wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count)
|
wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count)
|
||||||
{
|
{
|
||||||
wxArrayString choices;
|
wxArrayString choices;
|
||||||
@ -910,8 +925,10 @@ wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu)
|
|||||||
wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
|
wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
|
||||||
{
|
{
|
||||||
PrusaMenu* menu = dynamic_cast<PrusaMenu*>(menu_);
|
PrusaMenu* menu = dynamic_cast<PrusaMenu*>(menu_);
|
||||||
|
|
||||||
|
const wxString menu_name = _(L("Add settings"));
|
||||||
// Delete old items from settings popupmenu
|
// Delete old items from settings popupmenu
|
||||||
auto settings_id = menu->FindItem(_("Add settings"));
|
auto settings_id = menu->FindItem(menu_name);
|
||||||
if (settings_id != wxNOT_FOUND)
|
if (settings_id != wxNOT_FOUND)
|
||||||
menu->Destroy(settings_id);
|
menu->Destroy(settings_id);
|
||||||
|
|
||||||
@ -966,14 +983,10 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
|
|||||||
menu->m_separator_scnd = menu->AppendSeparator();
|
menu->m_separator_scnd = menu->AppendSeparator();
|
||||||
|
|
||||||
// Add full settings list
|
// Add full settings list
|
||||||
auto menu_item = new wxMenuItem(menu, wxID_ANY, _(L("Add settings")));
|
auto menu_item = new wxMenuItem(menu, wxID_ANY, menu_name);
|
||||||
menu_item->SetBitmap(m_bmp_cog);
|
menu_item->SetBitmap(m_bmp_cog);
|
||||||
|
|
||||||
// const auto sel_vol = get_selected_model_volume();
|
menu_item->SetSubMenu(create_settings_popupmenu(menu));
|
||||||
// if (sel_vol && sel_vol->type() >= ModelVolumeType::SUPPORT_ENFORCER)
|
|
||||||
// menu_item->Enable(false);
|
|
||||||
// else
|
|
||||||
menu_item->SetSubMenu(create_settings_popupmenu(menu));
|
|
||||||
|
|
||||||
return menu->Append(menu_item);
|
return menu->Append(menu_item);
|
||||||
}
|
}
|
||||||
@ -1018,6 +1031,37 @@ void ObjectList::append_menu_item_export_stl(wxMenu* menu) const
|
|||||||
menu->AppendSeparator();
|
menu->AppendSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectList::append_menu_item_change_extruder(wxMenu* menu) const
|
||||||
|
{
|
||||||
|
const wxString name = _(L("Change extruder"));
|
||||||
|
// Delete old menu item
|
||||||
|
const int item_id = menu->FindItem(name);
|
||||||
|
if (item_id != wxNOT_FOUND)
|
||||||
|
menu->Destroy(item_id);
|
||||||
|
|
||||||
|
const int extruders_cnt = extruders_count();
|
||||||
|
const wxDataViewItem item = GetSelection();
|
||||||
|
if (item && extruders_cnt > 1)
|
||||||
|
{
|
||||||
|
DynamicPrintConfig& config = get_item_config(item);
|
||||||
|
|
||||||
|
const int initial_extruder = !config.has("extruder") ? 0 :
|
||||||
|
config.option<ConfigOptionInt>("extruder")->value;
|
||||||
|
|
||||||
|
wxMenu* extruder_selection_menu = new wxMenu();
|
||||||
|
|
||||||
|
for (int i = 0; i <= extruders_cnt; i++)
|
||||||
|
{
|
||||||
|
const wxString& item_name = i == 0 ? _(L("Default")) : wxString::Format("%d", i);
|
||||||
|
|
||||||
|
append_menu_radio_item(extruder_selection_menu, wxID_ANY, item_name, "",
|
||||||
|
[this, i](wxCommandEvent&) { set_extruder_for_selected_items(i); }, menu)->Check(i == initial_extruder);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu->AppendSubMenu(extruder_selection_menu, name, _(L("Select new extruder for the object/part")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectList::create_object_popupmenu(wxMenu *menu)
|
void ObjectList::create_object_popupmenu(wxMenu *menu)
|
||||||
{
|
{
|
||||||
#ifdef __WXOSX__
|
#ifdef __WXOSX__
|
||||||
@ -1989,7 +2033,7 @@ void ObjectList::update_selections_on_canvas()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto add_to_selection = [this](const wxDataViewItem& item, Selection& selection, bool as_single_selection)
|
auto add_to_selection = [this](const wxDataViewItem& item, Selection& selection, int instance_idx, bool as_single_selection)
|
||||||
{
|
{
|
||||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
|
if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
|
||||||
selection.add_object(m_objects_model->GetIdByItem(item), as_single_selection);
|
selection.add_object(m_objects_model->GetIdByItem(item), as_single_selection);
|
||||||
@ -1999,7 +2043,7 @@ void ObjectList::update_selections_on_canvas()
|
|||||||
if (m_objects_model->GetItemType(item) == itVolume) {
|
if (m_objects_model->GetItemType(item) == itVolume) {
|
||||||
const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetParent(item));
|
const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetParent(item));
|
||||||
const int vol_idx = m_objects_model->GetVolumeIdByItem(item);
|
const int vol_idx = m_objects_model->GetVolumeIdByItem(item);
|
||||||
selection.add_volume(obj_idx, vol_idx, 0, as_single_selection);
|
selection.add_volume(obj_idx, vol_idx, std::max(instance_idx, 0), as_single_selection);
|
||||||
}
|
}
|
||||||
else if (m_objects_model->GetItemType(item) == itInstance) {
|
else if (m_objects_model->GetItemType(item) == itInstance) {
|
||||||
const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item));
|
const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item));
|
||||||
@ -2011,9 +2055,9 @@ void ObjectList::update_selections_on_canvas()
|
|||||||
if (sel_cnt == 1) {
|
if (sel_cnt == 1) {
|
||||||
wxDataViewItem item = GetSelection();
|
wxDataViewItem item = GetSelection();
|
||||||
if (m_objects_model->GetItemType(item) & (itSettings|itInstanceRoot))
|
if (m_objects_model->GetItemType(item) & (itSettings|itInstanceRoot))
|
||||||
add_to_selection(m_objects_model->GetParent(item), selection, true);
|
add_to_selection(m_objects_model->GetParent(item), selection, -1, true);
|
||||||
else
|
else
|
||||||
add_to_selection(item, selection, true);
|
add_to_selection(item, selection, -1, true);
|
||||||
|
|
||||||
wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state();
|
wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state();
|
||||||
return;
|
return;
|
||||||
@ -2022,9 +2066,11 @@ void ObjectList::update_selections_on_canvas()
|
|||||||
wxDataViewItemArray sels;
|
wxDataViewItemArray sels;
|
||||||
GetSelections(sels);
|
GetSelections(sels);
|
||||||
|
|
||||||
|
// stores current instance idx before to clear the selection
|
||||||
|
int instance_idx = selection.get_instance_idx();
|
||||||
selection.clear();
|
selection.clear();
|
||||||
for (auto item: sels)
|
for (auto item: sels)
|
||||||
add_to_selection(item, selection, false);
|
add_to_selection(item, selection, instance_idx, false);
|
||||||
|
|
||||||
wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state();
|
wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state();
|
||||||
}
|
}
|
||||||
@ -2425,15 +2471,7 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const
|
|||||||
|
|
||||||
for (const wxDataViewItem& item : sels)
|
for (const wxDataViewItem& item : sels)
|
||||||
{
|
{
|
||||||
const ItemType type = m_objects_model->GetItemType(item);
|
DynamicPrintConfig& config = get_item_config(item);
|
||||||
|
|
||||||
const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) :
|
|
||||||
m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item));
|
|
||||||
|
|
||||||
const int vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1;
|
|
||||||
|
|
||||||
DynamicPrintConfig& config = type & itObject ? (*m_objects)[obj_idx]->config :
|
|
||||||
(*m_objects)[obj_idx]->volumes[vol_idx]->config;
|
|
||||||
|
|
||||||
if (config.has("extruder")) {
|
if (config.has("extruder")) {
|
||||||
if (extruder == 0)
|
if (extruder == 0)
|
||||||
@ -2446,7 +2484,16 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const
|
|||||||
|
|
||||||
const wxString extruder_str = extruder == 0 ? wxString ("default") :
|
const wxString extruder_str = extruder == 0 ? wxString ("default") :
|
||||||
wxString::Format("%d", config.option<ConfigOptionInt>("extruder")->value);
|
wxString::Format("%d", config.option<ConfigOptionInt>("extruder")->value);
|
||||||
m_objects_model->SetValue(extruder_str, item, 1);
|
|
||||||
|
auto const type = m_objects_model->GetItemType(item);
|
||||||
|
|
||||||
|
/* We can change extruder for Object/Volume only.
|
||||||
|
* So, if Instance is selected, get its Object item and change it
|
||||||
|
*/
|
||||||
|
m_objects_model->SetValue(extruder_str, type & itInstance ? m_objects_model->GetTopParent(item) : item, 1);
|
||||||
|
|
||||||
|
const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) :
|
||||||
|
m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item));
|
||||||
|
|
||||||
wxGetApp().plater()->canvas3D()->ensure_on_bed(obj_idx);
|
wxGetApp().plater()->canvas3D()->ensure_on_bed(obj_idx);
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,7 @@ public:
|
|||||||
void append_menu_items_osx(wxMenu* menu);
|
void append_menu_items_osx(wxMenu* menu);
|
||||||
void append_menu_item_fix_through_netfabb(wxMenu* menu);
|
void append_menu_item_fix_through_netfabb(wxMenu* menu);
|
||||||
void append_menu_item_export_stl(wxMenu* menu) const ;
|
void append_menu_item_export_stl(wxMenu* menu) const ;
|
||||||
|
void append_menu_item_change_extruder(wxMenu* menu) const;
|
||||||
void create_object_popupmenu(wxMenu *menu);
|
void create_object_popupmenu(wxMenu *menu);
|
||||||
void create_sla_object_popupmenu(wxMenu*menu);
|
void create_sla_object_popupmenu(wxMenu*menu);
|
||||||
void create_part_popupmenu(wxMenu*menu);
|
void create_part_popupmenu(wxMenu*menu);
|
||||||
@ -213,12 +214,13 @@ public:
|
|||||||
wxPoint get_mouse_position_in_control();
|
wxPoint get_mouse_position_in_control();
|
||||||
wxBoxSizer* get_sizer() {return m_sizer;}
|
wxBoxSizer* get_sizer() {return m_sizer;}
|
||||||
int get_selected_obj_idx() const;
|
int get_selected_obj_idx() const;
|
||||||
|
DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const;
|
||||||
bool is_parts_changed() const { return m_parts_changed; }
|
bool is_parts_changed() const { return m_parts_changed; }
|
||||||
bool is_part_settings_changed() const { return m_part_settings_changed; }
|
bool is_part_settings_changed() const { return m_part_settings_changed; }
|
||||||
void part_settings_changed();
|
void part_settings_changed();
|
||||||
|
|
||||||
void parts_changed(int obj_idx);
|
void parts_changed(int obj_idx);
|
||||||
void part_selection_changed();
|
void part_selection_changed();
|
||||||
|
|
||||||
// Add object to the list
|
// Add object to the list
|
||||||
void add_object_to_list(size_t obj_idx);
|
void add_object_to_list(size_t obj_idx);
|
||||||
|
@ -28,7 +28,7 @@ MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &he
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxBitmap bitmap, wxWindowID button_id) :
|
MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxBitmap bitmap, wxWindowID button_id) :
|
||||||
wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxRESIZE_BORDER),
|
wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
|
||||||
boldfont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)),
|
boldfont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)),
|
||||||
content_sizer(new wxBoxSizer(wxVERTICAL)),
|
content_sizer(new wxBoxSizer(wxVERTICAL)),
|
||||||
btn_sizer(new wxBoxSizer(wxHORIZONTAL))
|
btn_sizer(new wxBoxSizer(wxHORIZONTAL))
|
||||||
|
@ -427,7 +427,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
|
|||||||
|
|
||||||
option = m_og->get_option("fill_density");
|
option = m_og->get_option("fill_density");
|
||||||
option.opt.label = L("Infill");
|
option.opt.label = L("Infill");
|
||||||
option.opt.width = 5 * wxGetApp().em_unit();
|
option.opt.width = 6 * wxGetApp().em_unit();
|
||||||
option.opt.sidetext = " ";
|
option.opt.sidetext = " ";
|
||||||
line.append_option(option);
|
line.append_option(option);
|
||||||
|
|
||||||
@ -2624,29 +2624,35 @@ void Plater::priv::on_right_click(Vec2dEvent& evt)
|
|||||||
|
|
||||||
sidebar->obj_list()->append_menu_item_settings(menu);
|
sidebar->obj_list()->append_menu_item_settings(menu);
|
||||||
|
|
||||||
/* Remove/Prepend "increase/decrease instances" menu items according to the view mode.
|
if (printer_technology != ptSLA)
|
||||||
* Suppress to show those items for a Simple mode
|
sidebar->obj_list()->append_menu_item_change_extruder(menu);
|
||||||
*/
|
|
||||||
const MenuIdentifier id = printer_technology == ptSLA ? miObjectSLA : miObjectFFF;
|
if (menu != &part_menu)
|
||||||
if (wxGetApp().get_mode() == comSimple) {
|
{
|
||||||
if (menu->FindItem(_(L("Increase copies"))) != wxNOT_FOUND)
|
/* Remove/Prepend "increase/decrease instances" menu items according to the view mode.
|
||||||
{
|
* Suppress to show those items for a Simple mode
|
||||||
/* Detach an items from the menu, but don't delete them
|
*/
|
||||||
* so that they can be added back later
|
const MenuIdentifier id = printer_technology == ptSLA ? miObjectSLA : miObjectFFF;
|
||||||
* (after switching to the Advanced/Expert mode)
|
if (wxGetApp().get_mode() == comSimple) {
|
||||||
*/
|
if (menu->FindItem(_(L("Increase copies"))) != wxNOT_FOUND)
|
||||||
menu->Remove(items_increase[id]);
|
{
|
||||||
menu->Remove(items_decrease[id]);
|
/* Detach an items from the menu, but don't delete them
|
||||||
menu->Remove(items_set_number_of_copies[id]);
|
* so that they can be added back later
|
||||||
|
* (after switching to the Advanced/Expert mode)
|
||||||
|
*/
|
||||||
|
menu->Remove(items_increase[id]);
|
||||||
|
menu->Remove(items_decrease[id]);
|
||||||
|
menu->Remove(items_set_number_of_copies[id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else {
|
if (menu->FindItem(_(L("Increase copies"))) == wxNOT_FOUND)
|
||||||
if (menu->FindItem(_(L("Increase copies"))) == wxNOT_FOUND)
|
{
|
||||||
{
|
// Prepend items to the menu, if those aren't not there
|
||||||
// Prepend items to the menu, if those aren't not there
|
menu->Prepend(items_set_number_of_copies[id]);
|
||||||
menu->Prepend(items_set_number_of_copies[id]);
|
menu->Prepend(items_decrease[id]);
|
||||||
menu->Prepend(items_decrease[id]);
|
menu->Prepend(items_increase[id]);
|
||||||
menu->Prepend(items_increase[id]);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,24 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
|
||||||
|
std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler)
|
||||||
|
{
|
||||||
|
if (id == wxID_ANY)
|
||||||
|
id = wxNewId();
|
||||||
|
|
||||||
|
wxMenuItem* item = menu->AppendRadioItem(id, string, description);
|
||||||
|
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
if (event_handler != nullptr && event_handler != menu)
|
||||||
|
event_handler->Bind(wxEVT_MENU, cb, id);
|
||||||
|
else
|
||||||
|
#endif // __WXMSW__
|
||||||
|
menu->Bind(wxEVT_MENU, cb, id);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200;
|
const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200;
|
||||||
const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200;
|
const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200;
|
||||||
const unsigned int wxCheckListBoxComboPopup::DefaultItemHeight = 18;
|
const unsigned int wxCheckListBoxComboPopup::DefaultItemHeight = 18;
|
||||||
|
@ -25,7 +25,11 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const
|
|||||||
wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
|
wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
|
||||||
std::function<void(wxCommandEvent& event)> cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr);
|
std::function<void(wxCommandEvent& event)> cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr);
|
||||||
|
|
||||||
wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description, const std::string& icon = "");
|
wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description,
|
||||||
|
const std::string& icon = "");
|
||||||
|
|
||||||
|
wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
|
||||||
|
std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler);
|
||||||
|
|
||||||
wxBitmap create_scaled_bitmap(const std::string& bmp_name);
|
wxBitmap create_scaled_bitmap(const std::string& bmp_name);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user