mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-06 22:47:32 -06:00
Dialog for Clone (#9897)
* init * update * Update CloneDialog.cpp * fix focus
This commit is contained in:
parent
ea7cfbc050
commit
c4e8b26f17
5 changed files with 157 additions and 16 deletions
|
@ -470,6 +470,8 @@ set(SLIC3R_GUI_SOURCES
|
||||||
GUI/CalibrationWizardSavePage.hpp
|
GUI/CalibrationWizardSavePage.hpp
|
||||||
GUI/Calibration.hpp
|
GUI/Calibration.hpp
|
||||||
GUI/Calibration.cpp
|
GUI/Calibration.cpp
|
||||||
|
GUI/CloneDialog.hpp
|
||||||
|
GUI/CloneDialog.cpp
|
||||||
GUI/PrintOptionsDialog.hpp
|
GUI/PrintOptionsDialog.hpp
|
||||||
GUI/PrintOptionsDialog.cpp
|
GUI/PrintOptionsDialog.cpp
|
||||||
GUI/BonjourDialog.hpp
|
GUI/BonjourDialog.hpp
|
||||||
|
|
115
src/slic3r/GUI/CloneDialog.cpp
Normal file
115
src/slic3r/GUI/CloneDialog.cpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
#include "CloneDialog.hpp"
|
||||||
|
|
||||||
|
#include "GUI_App.hpp"
|
||||||
|
#include "MainFrame.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
|
CloneDialog::CloneDialog(wxWindow *parent)
|
||||||
|
: DPIDialog(parent ? parent : static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, _L("Clone"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
|
||||||
|
{
|
||||||
|
SetBackgroundColour(*wxWHITE);
|
||||||
|
SetFont(Label::Body_14);
|
||||||
|
|
||||||
|
m_plater = wxGetApp().plater();
|
||||||
|
m_config = wxGetApp().app_config;
|
||||||
|
m_cancel_process = false;
|
||||||
|
|
||||||
|
auto v_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
auto f_sizer = new wxFlexGridSizer(2, 2, FromDIP(4) , FromDIP(20));
|
||||||
|
|
||||||
|
auto count_label = new wxStaticText(this, wxID_ANY, _L("Number of copies:"), wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
m_count_spin = new SpinInput(this, wxEmptyString, "", wxDefaultPosition, wxSize(FromDIP(120), -1), wxSP_ARROW_KEYS, 1, 1000, 1);
|
||||||
|
m_count_spin->GetTextCtrl()->SetFocus();
|
||||||
|
f_sizer->Add(count_label , 0, wxEXPAND | wxALIGN_CENTER_VERTICAL);
|
||||||
|
f_sizer->Add(m_count_spin, 0, wxALIGN_CENTER_VERTICAL);
|
||||||
|
|
||||||
|
auto arrange_label = new wxStaticText(this, wxID_ANY, _L("Auto arrange plate after cloning") + ":", wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
arrange_label->Wrap(FromDIP(300));
|
||||||
|
m_arrange_cb = new ::CheckBox(this);
|
||||||
|
m_arrange_cb->SetValue(m_config->get("auto_arrange") == "true");
|
||||||
|
f_sizer->Add(arrange_label, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL);
|
||||||
|
f_sizer->Add(m_arrange_cb , 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, FromDIP(5));
|
||||||
|
|
||||||
|
v_sizer->Add(f_sizer, 1, wxEXPAND | wxALL, FromDIP(10));
|
||||||
|
|
||||||
|
auto bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
m_progress = new ProgressBar(this, wxID_ANY, 100);
|
||||||
|
m_progress->SetHeight(FromDIP(8));
|
||||||
|
m_progress->SetMaxSize(wxSize(-1, FromDIP(8)));
|
||||||
|
m_progress->SetProgressForedColour(StateColor::darkModeColorFor(wxColour("#DFDFDF")));
|
||||||
|
m_progress->SetDoubleBuffered(true);
|
||||||
|
m_progress->Hide();
|
||||||
|
bottom_sizer->Add(m_progress, 2, wxEXPAND | wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
|
||||||
|
|
||||||
|
// used next button to get automatic left alignment
|
||||||
|
// will add a left_align_first_n parameter to DialogButtons. current method not good
|
||||||
|
auto dlg_btns = new DialogButtons(this, {"Next", "OK", "Cancel"});
|
||||||
|
|
||||||
|
dlg_btns->GetNEXT()->SetLabel(_L("Fill"));
|
||||||
|
dlg_btns->GetNEXT()->SetToolTip(_L("Fill bed with copies"));
|
||||||
|
dlg_btns->GetNEXT()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
|
||||||
|
m_plater->fill_bed_with_instances();
|
||||||
|
EndModal(wxID_OK);
|
||||||
|
});
|
||||||
|
|
||||||
|
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, [this, dlg_btns, v_sizer](wxCommandEvent &e) {
|
||||||
|
|
||||||
|
m_count_spin->Disable(); // also ensures input box value applied with wxEVT_KILL_FOCUS
|
||||||
|
m_arrange_cb->Disable();
|
||||||
|
|
||||||
|
m_count = m_count_spin->GetValue();
|
||||||
|
|
||||||
|
m_progress->Show();
|
||||||
|
|
||||||
|
dlg_btns->GetOK()->Hide();
|
||||||
|
dlg_btns->GetNEXT()->Hide();
|
||||||
|
|
||||||
|
this->Layout();
|
||||||
|
v_sizer->Fit(this);
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
Selection& sel = m_plater->canvas3D()->get_selection();
|
||||||
|
m_plater->take_snapshot(std::string("Selection-clone"));
|
||||||
|
m_plater->Freeze(); // Better to stop rendering canvas while processing
|
||||||
|
sel.copy_to_clipboard();
|
||||||
|
for (int i = 0; i < m_count; i++) { // same method with Selection::clone()
|
||||||
|
m_progress->SetValue(static_cast<int>(static_cast<double>(i) / m_count * 100)); // pass 0 / 100
|
||||||
|
sel.paste_from_clipboard();
|
||||||
|
if(m_cancel_process){
|
||||||
|
m_plater->undo();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wxYield(); // Allow event loop to process updates
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!m_cancel_process){
|
||||||
|
if (m_arrange_cb->GetValue()){
|
||||||
|
m_plater->set_prepare_state(Job::PREPARE_STATE_MENU);
|
||||||
|
m_plater->arrange();
|
||||||
|
}
|
||||||
|
m_plater->Thaw();
|
||||||
|
EndModal(wxID_OK);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dlg_btns->GetCANCEL()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
|
||||||
|
m_cancel_process = true;
|
||||||
|
if(m_plater->IsFrozen())
|
||||||
|
m_plater->Thaw();
|
||||||
|
EndModal(wxID_CANCEL);
|
||||||
|
});
|
||||||
|
|
||||||
|
bottom_sizer->Add(dlg_btns, 1, wxEXPAND);
|
||||||
|
|
||||||
|
v_sizer->Add(bottom_sizer, 0, wxEXPAND);
|
||||||
|
|
||||||
|
this->SetSizer(v_sizer);
|
||||||
|
this->Layout();
|
||||||
|
v_sizer->Fit(this);
|
||||||
|
wxGetApp().UpdateDlgDarkUI(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloneDialog::~CloneDialog() {}
|
||||||
|
|
||||||
|
}} // namespace Slic3r::GUI
|
36
src/slic3r/GUI/CloneDialog.hpp
Normal file
36
src/slic3r/GUI/CloneDialog.hpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef slic3r_GUI_SingleChoice_hpp_
|
||||||
|
#define slic3r_GUI_SingleChoice_hpp_
|
||||||
|
|
||||||
|
#include "GUI_Utils.hpp"
|
||||||
|
#include "Plater.hpp"
|
||||||
|
#include "Selection.hpp"
|
||||||
|
|
||||||
|
#include "Widgets/Button.hpp"
|
||||||
|
#include "Widgets/SpinInput.hpp"
|
||||||
|
#include "Widgets/DialogButtons.hpp"
|
||||||
|
#include "Widgets/CheckBox.hpp"
|
||||||
|
#include "Widgets/ProgressBar.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
|
class CloneDialog : public DPIDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CloneDialog(wxWindow *parent = nullptr);
|
||||||
|
~CloneDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SpinInput* m_count_spin;
|
||||||
|
int m_count;
|
||||||
|
CheckBox* m_arrange_cb;
|
||||||
|
Plater* m_plater;
|
||||||
|
ProgressBar* m_progress;
|
||||||
|
AppConfig* m_config;
|
||||||
|
bool m_cancel_process;
|
||||||
|
|
||||||
|
void on_dpi_changed(const wxRect &suggested_rect) override {}
|
||||||
|
|
||||||
|
};
|
||||||
|
}} // namespace Slic3r::GUI
|
||||||
|
|
||||||
|
#endif
|
|
@ -1298,7 +1298,7 @@ void MenuFactory::create_object_menu()
|
||||||
|
|
||||||
void MenuFactory::create_extra_object_menu()
|
void MenuFactory::create_extra_object_menu()
|
||||||
{
|
{
|
||||||
append_menu_item_fill_bed(&m_object_menu);
|
//append_menu_item_fill_bed(&m_object_menu);
|
||||||
// Object Clone
|
// Object Clone
|
||||||
append_menu_item_clone(&m_object_menu);
|
append_menu_item_clone(&m_object_menu);
|
||||||
// Object Repair
|
// Object Repair
|
||||||
|
|
|
@ -153,6 +153,7 @@
|
||||||
#include "CreatePresetsDialog.hpp"
|
#include "CreatePresetsDialog.hpp"
|
||||||
#include "FileArchiveDialog.hpp"
|
#include "FileArchiveDialog.hpp"
|
||||||
#include "StepMeshDialog.hpp"
|
#include "StepMeshDialog.hpp"
|
||||||
|
#include "CloneDialog.hpp"
|
||||||
|
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
@ -13777,21 +13778,8 @@ void Plater::clone_selection()
|
||||||
{
|
{
|
||||||
if (is_selection_empty())
|
if (is_selection_empty())
|
||||||
return;
|
return;
|
||||||
long res = wxGetNumberFromUser("",
|
CloneDialog dlg(this);
|
||||||
_L("Clone"),
|
dlg.ShowModal();
|
||||||
_L("Number of copies:"),
|
|
||||||
1, 0, 1000, this);
|
|
||||||
wxString msg;
|
|
||||||
if (res == -1) {
|
|
||||||
msg = _L("Invalid number");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Selection& selection = p->get_selection();
|
|
||||||
selection.clone(res);
|
|
||||||
if (wxGetApp().app_config->get("auto_arrange") == "true") {
|
|
||||||
this->set_prepare_state(Job::PREPARE_STATE_MENU);
|
|
||||||
this->arrange();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Vec2f> Plater::get_empty_cells(const Vec2f step)
|
std::vector<Vec2f> Plater::get_empty_cells(const Vec2f step)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue