mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-20 23:31:13 -06:00
Merge mainstream changes
This commit is contained in:
commit
764b7d62a0
204 changed files with 5425 additions and 1411 deletions
|
@ -36,10 +36,6 @@ BBLStatusBarBind::BBLStatusBarBind(wxWindow *parent, int id)
|
|||
m_prog = new wxGauge(m_self, wxID_ANY, 100, wxDefaultPosition, wxSize(m_self->FromDIP(400), m_self->FromDIP(6)), wxGA_HORIZONTAL);
|
||||
m_prog->SetValue(0);
|
||||
|
||||
block_left = new wxWindow(m_prog, wxID_ANY, wxPoint(0, 0), wxSize(2, m_prog->GetSize().GetHeight() * 2));
|
||||
block_left->SetBackgroundColour(wxColour(255, 255, 255));
|
||||
block_right = new wxWindow(m_prog, wxID_ANY, wxPoint(m_prog->GetSize().GetWidth() - 2, 0), wxSize(2, m_prog->GetSize().GetHeight() * 2));
|
||||
block_right->SetBackgroundColour(wxColour(255, 255, 255));
|
||||
|
||||
m_stext_percent = new wxStaticText(m_self, wxID_ANY, _L(""), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_stext_percent->SetForegroundColour(wxColour(107, 107, 107));
|
||||
|
@ -61,8 +57,6 @@ BBLStatusBarBind::BBLStatusBarBind(wxWindow *parent, int id)
|
|||
|
||||
void BBLStatusBarBind::set_prog_block()
|
||||
{
|
||||
block_left->SetPosition(wxPoint(0, 0));
|
||||
block_right->SetPosition(wxPoint(m_prog->GetSize().GetWidth() - 2, 0));
|
||||
}
|
||||
|
||||
int BBLStatusBarBind::get_progress() const
|
||||
|
|
|
@ -35,8 +35,6 @@ class BBLStatusBarBind : public ProgressIndicator
|
|||
wxStaticText *m_stext_percent;
|
||||
wxBoxSizer * m_sizer;
|
||||
wxBoxSizer * m_sizer_eline;
|
||||
wxWindow * block_left;
|
||||
wxWindow * block_right;
|
||||
|
||||
public:
|
||||
BBLStatusBarBind(wxWindow *parent = nullptr, int id = -1);
|
||||
|
|
|
@ -131,7 +131,7 @@ void ConfigManipulation::check_bed_temperature_difference(int bed_type, DynamicP
|
|||
}
|
||||
|
||||
if (first_layer_bed_temp > vitrification || bed_temp > vitrification) {
|
||||
const wxString msg_text = wxString::Format(_L("Bed temperature is higher than vitrification temperature of this filament.\nThis may cause nozzle blocked and printing failure"));
|
||||
const wxString msg_text = wxString::Format(_L("Bed temperature is higher than vitrification temperature of this filament.\nThis may cause nozzle blocked and printing failure\nPlease keep the printer open during the printing process to ensure air circulation or reduce the temperature of the hot bed"));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
is_msg_dlg_already_exist = true;
|
||||
dialog.ShowModal();
|
||||
|
@ -384,8 +384,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
|||
wxString msg_text = GUI::format_wxstr(_L("%1% infill pattern doesn't support 100%% density."),
|
||||
_(fill_pattern_def->enum_labels[it_pattern - fill_pattern_def->enum_values.begin()]));
|
||||
if (is_global_config)
|
||||
msg_text += "\n" + _L("Switch to zig-zag pattern?\n"
|
||||
"Yes - switch to zig-zag pattern automaticlly\n"
|
||||
msg_text += "\n" + _L("Switch to rectilinear pattern?\n"
|
||||
"Yes - switch to rectilinear pattern automaticlly\n"
|
||||
"No - reset density to default non 100% value automaticlly\n");
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "",
|
||||
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) );
|
||||
|
@ -513,9 +513,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
for (auto el : { "support_style", "support_base_pattern",
|
||||
"support_base_pattern_spacing", "support_angle",
|
||||
"support_interface_pattern", "support_interface_top_layers", "support_interface_bottom_layers",
|
||||
"bridge_no_support", "thick_bridges", "max_bridge_length", "support_top_z_distance",
|
||||
"bridge_no_support", "max_bridge_length", "support_top_z_distance",
|
||||
//BBS: add more support params to dependent of enable_support
|
||||
"support_type","support_on_build_plate_only",
|
||||
"support_type", "support_on_build_plate_only", "support_critical_regions_only",
|
||||
"support_object_xy_distance", "independent_support_layer_height"})
|
||||
toggle_field(el, have_support_material);
|
||||
toggle_field("support_threshold_angle", have_support_material && (support_type == stNormalAuto || support_type == stTreeAuto || support_type==stHybridAuto));
|
||||
|
|
173
src/slic3r/GUI/ConfirmHintDialog.cpp
Normal file
173
src/slic3r/GUI/ConfirmHintDialog.cpp
Normal file
|
@ -0,0 +1,173 @@
|
|||
#include "ConfirmHintDialog.hpp"
|
||||
#include <slic3r/GUI/I18N.hpp>
|
||||
#include <wx/dcgraph.h>
|
||||
#include <wx/dcmemory.h>
|
||||
#include <slic3r/GUI/Widgets/Label.hpp>
|
||||
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxDEFINE_EVENT(EVT_CONFIRM_HINT, wxCommandEvent);
|
||||
|
||||
ConfirmHintDialog::ConfirmHintDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
|
||||
: DPIDialog(parent, id, title, pos, size, style)
|
||||
{
|
||||
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
|
||||
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
|
||||
|
||||
auto* main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
auto* button_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxPanel* m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
|
||||
m_button_confirm = new Button(this, _L("Confirm"));
|
||||
m_button_confirm->SetFont(Label::Body_14);
|
||||
m_button_confirm->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_confirm->SetCornerRadius(FromDIP(12));
|
||||
StateColor confirm_btn_bg(std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
|
||||
m_button_confirm->SetBackgroundColor(confirm_btn_bg);
|
||||
m_button_confirm->SetBorderColor(wxColour(0, 174, 66));
|
||||
m_button_confirm->SetTextColor(*wxWHITE);
|
||||
|
||||
m_button_close = new Button(this, _L("Cancel"));
|
||||
m_button_close->SetFont(Label::Body_14);
|
||||
m_button_close->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_close->SetCornerRadius(FromDIP(12));
|
||||
StateColor close_btn_bg(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
|
||||
m_button_close->SetBackgroundColor(close_btn_bg);
|
||||
m_button_close->SetBorderColor(wxColour(38, 46, 48));
|
||||
m_button_close->SetTextColor(wxColour(38, 46, 48));
|
||||
|
||||
button_sizer->AddStretchSpacer();
|
||||
button_sizer->Add(m_button_confirm);
|
||||
button_sizer->AddSpacer(FromDIP(20));
|
||||
button_sizer->Add(m_button_close);
|
||||
|
||||
main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
main_sizer->AddSpacer(wxSize(FromDIP(475), FromDIP(100)).y);
|
||||
main_sizer->Add(button_sizer, 0, wxBOTTOM | wxRIGHT | wxEXPAND, FromDIP(25));
|
||||
|
||||
SetSizer(main_sizer);
|
||||
|
||||
CenterOnParent();
|
||||
|
||||
this->SetSize(wxSize(wxSize(FromDIP(475), FromDIP(100)).x, -1));
|
||||
this->SetMinSize(wxSize(wxSize(FromDIP(475), FromDIP(100)).x, -1));
|
||||
Layout();
|
||||
Fit();
|
||||
this->Bind(wxEVT_PAINT, &ConfirmHintDialog::OnPaint, this);
|
||||
m_button_confirm->Bind(wxEVT_BUTTON, &ConfirmHintDialog::on_button_confirm, this);
|
||||
m_button_close->Bind(wxEVT_BUTTON, &ConfirmHintDialog::on_button_close, this);
|
||||
}
|
||||
|
||||
ConfirmHintDialog::~ConfirmHintDialog() {}
|
||||
|
||||
void ConfirmHintDialog::SetHint(const wxString& hint){
|
||||
firm_up_hint = hint;
|
||||
}
|
||||
|
||||
void ConfirmHintDialog::OnPaint(wxPaintEvent& event){
|
||||
wxPaintDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
void ConfirmHintDialog::render(wxDC& dc) {
|
||||
wxSize size = GetSize();
|
||||
|
||||
dc.SetFont(Label::Body_14);
|
||||
dc.SetTextForeground(text_color);
|
||||
wxPoint pos_start = wxPoint(FromDIP(25), FromDIP(25));
|
||||
|
||||
wxSize firm_up_hint_size = dc.GetTextExtent(firm_up_hint);
|
||||
wxPoint pos_firm_up_hint = pos_start;
|
||||
|
||||
if (firm_up_hint_size.x + pos_firm_up_hint.x + FromDIP(25) > wxSize(FromDIP(475), FromDIP(100)).x) {
|
||||
bool is_ch = false;
|
||||
if (firm_up_hint[0] > 0x80 && firm_up_hint[1] > 0x80)
|
||||
is_ch = true;
|
||||
|
||||
wxString fisrt_line;
|
||||
wxString remaining_line;
|
||||
|
||||
wxString count_txt;
|
||||
int new_line_pos = 0;
|
||||
for (int i = 0; i < firm_up_hint.length(); i++) {
|
||||
count_txt += firm_up_hint[i];
|
||||
auto text_size = dc.GetTextExtent(count_txt);
|
||||
if (text_size.x + pos_firm_up_hint.x + FromDIP(25) < wxSize(FromDIP(475), FromDIP(100)).x)
|
||||
{
|
||||
if (firm_up_hint[i] == ' ' || firm_up_hint[i] == '\n')
|
||||
new_line_pos = i;
|
||||
}
|
||||
else {
|
||||
if (!is_ch) {
|
||||
fisrt_line = firm_up_hint.SubString(0, new_line_pos);
|
||||
remaining_line = firm_up_hint.SubString(new_line_pos + 1, firm_up_hint.length());
|
||||
break;
|
||||
}
|
||||
else {
|
||||
fisrt_line = firm_up_hint.SubString(0, i);
|
||||
remaining_line = firm_up_hint.SubString(i, firm_up_hint.length());
|
||||
break;
|
||||
}
|
||||
count_txt = "";
|
||||
}
|
||||
}
|
||||
dc.DrawText(fisrt_line, pos_firm_up_hint);
|
||||
|
||||
|
||||
count_txt = "";
|
||||
new_line_pos = 0;
|
||||
for (int i = 0; i < remaining_line.length(); i++) {
|
||||
count_txt += remaining_line[i];
|
||||
auto text_size = dc.GetTextExtent(count_txt);
|
||||
if (text_size.x + FromDIP(25) + FromDIP(25) < wxSize(FromDIP(475), FromDIP(100)).x)
|
||||
{
|
||||
if (remaining_line[i] == ' ' || remaining_line[i] == '\n')
|
||||
new_line_pos = i;
|
||||
}
|
||||
else {
|
||||
if (!is_ch){
|
||||
remaining_line[new_line_pos] = '\n';
|
||||
}
|
||||
else {
|
||||
remaining_line.insert(i, '\n');
|
||||
}
|
||||
count_txt = "";
|
||||
}
|
||||
}
|
||||
wxPoint pos_txt = pos_firm_up_hint;
|
||||
pos_txt.y += dc.GetCharHeight();
|
||||
dc.DrawText(remaining_line, pos_txt);
|
||||
}
|
||||
else
|
||||
dc.DrawText(firm_up_hint, pos_firm_up_hint);
|
||||
}
|
||||
|
||||
void ConfirmHintDialog::on_button_confirm(wxCommandEvent& event) {
|
||||
wxCommandEvent evt(EVT_CONFIRM_HINT, GetId());
|
||||
event.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
|
||||
if (this->IsModal())
|
||||
this->EndModal(wxID_OK);
|
||||
else
|
||||
this->Close();
|
||||
}
|
||||
|
||||
void ConfirmHintDialog::on_button_close(wxCommandEvent& event) {
|
||||
this->Close();
|
||||
}
|
||||
|
||||
void ConfirmHintDialog::on_dpi_changed(const wxRect& suggested_rect) {
|
||||
m_button_confirm->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_confirm->SetCornerRadius(FromDIP(12));
|
||||
m_button_close->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_close->SetCornerRadius(FromDIP(12));
|
||||
Layout();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
45
src/slic3r/GUI/ConfirmHintDialog.hpp
Normal file
45
src/slic3r/GUI/ConfirmHintDialog.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef slic3r_GUI_ConfirmHintDialog_hpp_
|
||||
#define slic3r_GUI_ConfirmHintDialog_hpp_
|
||||
|
||||
#include "GUI_Utils.hpp"
|
||||
#include <wx/statbmp.h>
|
||||
#include "Widgets/Button.hpp"
|
||||
#include <wx/stattext.h>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxDECLARE_EVENT(EVT_CONFIRM_HINT, wxCommandEvent);
|
||||
|
||||
class ConfirmHintDialog : public DPIDialog
|
||||
{
|
||||
private:
|
||||
wxStaticText* m_staticText_hint;
|
||||
Button* m_button_confirm;
|
||||
Button* m_button_close;
|
||||
wxStaticBitmap* m_bitmap_home;
|
||||
ScalableBitmap m_home_bmp;
|
||||
wxString firm_up_hint = "";
|
||||
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void render(wxDC& dc);
|
||||
void on_button_confirm(wxCommandEvent& event);
|
||||
void on_button_close(wxCommandEvent& event);
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
|
||||
public:
|
||||
ConfirmHintDialog(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxEmptyString,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxCLOSE_BOX | wxCAPTION);
|
||||
|
||||
const wxColour text_color = wxColour(107, 107, 107);
|
||||
|
||||
void SetHint(const wxString &hint);
|
||||
|
||||
~ConfirmHintDialog();
|
||||
};
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
|
@ -5,9 +5,6 @@
|
|||
#include "slic3r/Utils/ColorSpaceConvert.hpp"
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "libslic3r/PlaceholderParser.hpp"
|
||||
#include "libslic3r/Print.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "MsgDialog.hpp"
|
||||
#include "Plater.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
|
@ -47,6 +44,10 @@ std::string PRINTING_STAGE_STR[PRINTING_STAGE_COUNT] = {
|
|||
"extruder_absolute_flow_cali"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
wxString get_stage_string(int stage)
|
||||
{
|
||||
switch(stage) {
|
||||
|
@ -665,9 +666,11 @@ int MachineObject::ams_filament_mapping(std::vector<FilamentInfo> filaments, std
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// is_support_ams_mapping
|
||||
if (!is_support_ams_mapping()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "ams_mapping: do not support, use order mapping";
|
||||
result.clear();
|
||||
for (int i = 0; i < filaments.size(); i++) {
|
||||
FilamentInfo info;
|
||||
info.id = filaments[i].id;
|
||||
|
@ -1162,7 +1165,7 @@ int MachineObject::command_request_push_all()
|
|||
|
||||
int MachineObject::command_upgrade_confirm()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(trace) << "command_upgrade_confirm";
|
||||
BOOST_LOG_TRIVIAL(info) << "command_upgrade_confirm";
|
||||
json j;
|
||||
j["upgrade"]["command"] = "upgrade_confirm";
|
||||
j["upgrade"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
|
@ -1170,6 +1173,16 @@ int MachineObject::command_upgrade_confirm()
|
|||
return this->publish_json(j.dump());
|
||||
}
|
||||
|
||||
int MachineObject::command_consistency_upgrade_confirm()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "command_consistency_upgrade_confirm";
|
||||
json j;
|
||||
j["upgrade"]["command"] = "consistency_confirm";
|
||||
j["upgrade"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["upgrade"]["src_id"] = 1; // 1 for slicer
|
||||
return this->publish_json(j.dump());
|
||||
}
|
||||
|
||||
int MachineObject::command_upgrade_firmware(FirmwareInfo info)
|
||||
{
|
||||
std::string version = info.version;
|
||||
|
@ -1258,55 +1271,23 @@ int MachineObject::command_ams_switch(int tray_index, int old_temp, int new_temp
|
|||
int tray_id_int = tray_index;
|
||||
|
||||
std::string gcode = "";
|
||||
Slic3r::Print & print = Slic3r::GUI::wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
||||
const PrintConfig &print_config = print.config();
|
||||
if (tray_index == 255) {
|
||||
// unload gcode
|
||||
gcode = "M620 S255\nM104 S250\nG28 X\nG91\nG1 Z3.0 F1200\nG90\n"
|
||||
"G1 X70 F12000\nG1 Y245\nG1 Y265 F3000\nM109 S250\nG1 X120 F12000\n"
|
||||
"G1 X20 Y50 F12000\nG1 Y-3\nT255\nM104 S25\nG1 X165 F5000\nG1 Y245\n"
|
||||
"G91\nG1 Z-3.0 F1200\nG90\nM621 S255\n";
|
||||
} else {
|
||||
// load gcode
|
||||
gcode = "M620 S[next_extruder]\nM104 S250\nG28 X\nG91\n\nG1 Z3.0 F1200\nG90\n"
|
||||
"G1 X70 F12000\nG1 Y245\nG1 Y265 F3000\nM109 S250\nG1 X120 F12000\nG1 X20 Y50 F12000\nG1 Y-3"
|
||||
"\nT[next_extruder]\nG1 X54 F12000\nG1 Y265\nM400\nM106 P1 S0\nG92 E0\nG1 E40 F200\nM400"
|
||||
"\nM109 S[new_filament_temp]\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM400\nM106 P1 S0\nG1 X70 F9000"
|
||||
"\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000\nG1 X70 F6000\nG1 X100 F5000\nG1 X70 F15000"
|
||||
"\nG1 X100 F5000\nG1 X70 F15000\nG1 X165 F5000\nG1 Y245\nG91\nG1 Z-3.0 F1200\nG90\nM621 S[next_extruder]\n";
|
||||
|
||||
PlaceholderParser m_placeholder_parser;
|
||||
m_placeholder_parser = print.placeholder_parser();
|
||||
PlaceholderParser::ContextData m_placeholder_parser_context;
|
||||
DynamicConfig dyn_config;
|
||||
|
||||
int old_filament_temp = old_temp;
|
||||
int new_filament_temp = new_temp;
|
||||
old_filament_temp = correct_filament_temperature(old_filament_temp);
|
||||
new_filament_temp = correct_filament_temperature(new_filament_temp);
|
||||
dyn_config.set_key_value("previous_extruder", new ConfigOptionInt(-1));
|
||||
dyn_config.set_key_value("next_extruder", new ConfigOptionInt(tray_id_int));
|
||||
dyn_config.set_key_value("layer_num", new ConfigOptionInt(0));
|
||||
dyn_config.set_key_value("layer_z", new ConfigOptionFloat(0.3));
|
||||
dyn_config.set_key_value("max_layer_z", new ConfigOptionFloat(10.));
|
||||
dyn_config.set_key_value("relative_e_axis", new ConfigOptionBool(RELATIVE_E_AXIS));
|
||||
dyn_config.set_key_value("toolchange_count", new ConfigOptionInt(1));
|
||||
dyn_config.set_key_value("fan_speed", new ConfigOptionInt(0));
|
||||
dyn_config.set_key_value("old_retract_length", new ConfigOptionFloat(2.));
|
||||
dyn_config.set_key_value("new_retract_length", new ConfigOptionFloat(2.));
|
||||
dyn_config.set_key_value("old_retract_length_toolchange", new ConfigOptionFloat(3.0));
|
||||
dyn_config.set_key_value("new_retract_length_toolchange", new ConfigOptionFloat(3.0));
|
||||
dyn_config.set_key_value("old_filament_temp", new ConfigOptionInt(old_filament_temp));
|
||||
dyn_config.set_key_value("new_filament_temp", new ConfigOptionInt(new_filament_temp));
|
||||
dyn_config.set_key_value("x_after_toolchange", new ConfigOptionFloat(50.));
|
||||
dyn_config.set_key_value("y_after_toolchange", new ConfigOptionFloat(50.));
|
||||
dyn_config.set_key_value("z_after_toolchange", new ConfigOptionFloat(10.));
|
||||
dyn_config.set_key_value("flush_length_1", new ConfigOptionFloat(5.f));
|
||||
dyn_config.set_key_value("flush_length_2", new ConfigOptionFloat(5.f));
|
||||
dyn_config.set_key_value("flush_length_3", new ConfigOptionFloat(0.f));
|
||||
dyn_config.set_key_value("flush_length_4", new ConfigOptionFloat(0.f));
|
||||
dyn_config.set_key_value("old_filament_e_feedrate", new ConfigOptionInt(100));
|
||||
dyn_config.set_key_value("new_filament_e_feedrate", new ConfigOptionInt(100));
|
||||
try {
|
||||
std::string parsed_command = m_placeholder_parser.process(print_config.change_filament_gcode.value, tray_id_int, &dyn_config, &m_placeholder_parser_context);
|
||||
// config xyz coordinate mode
|
||||
std::string auto_home_command = "G28 X\n";
|
||||
parsed_command = "G90\n" + auto_home_command + parsed_command;
|
||||
std::regex match_pattern(";.*\n");
|
||||
std::string replace_pattern = "\n";
|
||||
char result[1024] = {0};
|
||||
std::regex_replace(result, parsed_command.begin(), parsed_command.end(), match_pattern, replace_pattern);
|
||||
result[1023] = 0;
|
||||
gcode = std::string(result);
|
||||
} catch (Exception &e) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "exception, e=" << e.what();
|
||||
return -1;
|
||||
boost::replace_all(gcode, "[next_extruder]", std::to_string(tray_index));
|
||||
boost::replace_all(gcode, "[new_filament_temp]", std::to_string(new_temp));
|
||||
}
|
||||
|
||||
return this->publish_gcode(gcode);
|
||||
|
@ -1723,6 +1704,18 @@ bool MachineObject::is_function_supported(PrinterFunction func)
|
|||
case FUNC_CHAMBER_TEMP:
|
||||
func_name = "FUNC_CHAMBER_TEMP";
|
||||
break;
|
||||
case FUNC_CAMERA_VIDEO:
|
||||
func_name = "FUNC_CAMERA_VIDEO";
|
||||
break;
|
||||
case FUNC_MEDIA_FILE:
|
||||
func_name = "FUNC_MEDIA_FILE";
|
||||
break;
|
||||
case FUNC_REMOTE_TUNNEL:
|
||||
func_name = "FUNC_REMOTE_TUNNEL";
|
||||
break;
|
||||
case FUNC_LOCAL_TUNNEL:
|
||||
func_name = "FUNC_LOCAL_TUNNEL";
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,10 @@ enum PrinterFunction {
|
|||
FUNC_FLOW_CALIBRATION,
|
||||
FUNC_AUTO_LEVELING,
|
||||
FUNC_CHAMBER_TEMP,
|
||||
FUNC_CAMERA_VIDEO,
|
||||
FUNC_MEDIA_FILE,
|
||||
FUNC_REMOTE_TUNNEL,
|
||||
FUNC_LOCAL_TUNNEL,
|
||||
FUNC_MAX
|
||||
};
|
||||
|
||||
|
@ -534,6 +538,7 @@ public:
|
|||
|
||||
/* command upgrade */
|
||||
int command_upgrade_confirm();
|
||||
int command_consistency_upgrade_confirm();
|
||||
int command_upgrade_firmware(FirmwareInfo info);
|
||||
|
||||
/* control apis */
|
||||
|
|
|
@ -224,9 +224,19 @@ static wxString na_value() { return _(L("N/A")); }
|
|||
void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true*/)
|
||||
{
|
||||
switch (m_opt.type) {
|
||||
case coInt:
|
||||
m_value = wxAtoi(str);
|
||||
break;
|
||||
case coInt: {
|
||||
long val = 0;
|
||||
if (!str.ToLong(&val)) {
|
||||
if (!check_value) {
|
||||
m_value.clear();
|
||||
break;
|
||||
}
|
||||
show_error(m_parent, _(L("Invalid numeric.")));
|
||||
set_value(int(val), true);
|
||||
}
|
||||
m_value = int(val);
|
||||
break;
|
||||
}
|
||||
case coPercent:
|
||||
case coPercents:
|
||||
case coFloats:
|
||||
|
|
|
@ -302,7 +302,7 @@ void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& positi
|
|||
}
|
||||
|
||||
//BBS: GUI refactor: add canvas size from parameters
|
||||
void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_height) const
|
||||
void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves, uint64_t curr_line_id) const
|
||||
{
|
||||
if (!m_visible)
|
||||
return;
|
||||
|
@ -330,43 +330,109 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
|
||||
static float last_window_width = 0.0f;
|
||||
static size_t last_text_length = 0;
|
||||
static const ImU32 text_name_clr = IM_COL32(38, 46, 48, 255);
|
||||
static const ImU32 text_value_clr = IM_COL32(144, 144, 144, 255);
|
||||
static const ImU32 window_bg_clr = IM_COL32(255, 255, 255, 255);
|
||||
|
||||
if (wxGetApp().get_mode() == ConfigOptionMode::comDevelop) {
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
//BBS: GUI refactor: add canvas size from parameters
|
||||
//Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size();
|
||||
//imgui.set_next_window_pos(0.5f * static_cast<float>(cnv_size.get_width()), static_cast<float>(cnv_size.get_height()), ImGuiCond_Always, 0.5f, 1.0f);
|
||||
imgui.set_next_window_pos(0.5f * static_cast<float>(canvas_width), static_cast<float>(canvas_height), ImGuiCond_Always, 0.5f, 1.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::SetNextWindowBgAlpha(0.25f);
|
||||
imgui.begin(std::string("ExtruderPosition"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
|
||||
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Extruder position") + ":");
|
||||
ImGui::SameLine();
|
||||
char buf[1024];
|
||||
//BBS: minus the plate offset when show tool position
|
||||
PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list();
|
||||
PartPlate* plate = partplate_list.get_curr_plate();
|
||||
const Vec3f position = m_world_position + m_world_offset;
|
||||
sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", position.x() - plate->get_origin().x(), position.y() - plate->get_origin().y(), position.z());
|
||||
imgui.text(std::string(buf));
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
//BBS: GUI refactor: add canvas size from parameters
|
||||
imgui.set_next_window_pos(0.5f * static_cast<float>(canvas_width), static_cast<float>(canvas_height), ImGuiCond_Always, 0.5f, 1.0f);
|
||||
imgui.push_toolbar_style(m_scale);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0, 4.0 * m_scale));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0 * m_scale, 6.0 * m_scale));
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, window_bg_clr);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, text_name_clr);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, text_value_clr);
|
||||
imgui.begin(std::string("ExtruderPosition"), ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar);
|
||||
ImGui::AlignTextToFramePadding();
|
||||
//BBS: minus the plate offset when show tool position
|
||||
PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list();
|
||||
PartPlate* plate = partplate_list.get_curr_plate();
|
||||
const Vec3f position = m_world_position + m_world_offset;
|
||||
std::string x = ImGui::ColorMarkerStart + std::string("X: ") + ImGui::ColorMarkerEnd;
|
||||
std::string y = ImGui::ColorMarkerStart + std::string("Y: ") + ImGui::ColorMarkerEnd;
|
||||
std::string z = ImGui::ColorMarkerStart + std::string("Z: ") + ImGui::ColorMarkerEnd;
|
||||
std::string speed = ImGui::ColorMarkerStart + _u8L("Speed: ") + ImGui::ColorMarkerEnd;
|
||||
std::string flow = ImGui::ColorMarkerStart + _u8L("Flow: ") + ImGui::ColorMarkerEnd;
|
||||
|
||||
// force extra frame to automatically update window size
|
||||
float width = ImGui::GetWindowWidth();
|
||||
size_t length = strlen(buf);
|
||||
if (width != last_window_width || length != last_text_length) {
|
||||
last_window_width = width;
|
||||
last_text_length = length;
|
||||
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
|
||||
imgui.set_requires_extra_frame();
|
||||
#else
|
||||
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty();
|
||||
wxGetApp().plater()->get_current_canvas3D()->request_extra_frame();
|
||||
#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
|
||||
std::ostringstream buffer;
|
||||
char buf[1024];
|
||||
if (view_type == EViewType::Feedrate) {
|
||||
auto it = std::find_if(moves.begin(), moves.end(), [&curr_line_id](auto move) {
|
||||
if (move.gcode_id == curr_line_id)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
if (it != moves.end()) {
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine();
|
||||
sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y());
|
||||
imgui.text(buf);
|
||||
|
||||
sprintf(buf, "%s%.3f", z.c_str(), position.z());
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine();
|
||||
sprintf(buf, "%s%.f", speed.c_str(), it->feedrate);
|
||||
imgui.text(buf);
|
||||
}
|
||||
|
||||
imgui.end();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
else if (view_type == EViewType::VolumetricRate) {
|
||||
auto it = std::find_if(moves.begin(), moves.end(), [&curr_line_id](auto move) {
|
||||
if (move.gcode_id == curr_line_id)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
if (it != moves.end()) {
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine();
|
||||
sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y());
|
||||
imgui.text(buf);
|
||||
|
||||
sprintf(buf, "%s%.3f", z.c_str(), position.z());
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine();
|
||||
sprintf(buf, "%s%.f", flow.c_str(), it->volumetric_rate());
|
||||
imgui.text(buf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine();
|
||||
sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y());
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine();
|
||||
sprintf(buf, "%s%.3f", z.c_str() , position.z());
|
||||
imgui.text(buf);
|
||||
}
|
||||
// force extra frame to automatically update window size
|
||||
float width = ImGui::GetWindowWidth();
|
||||
//size_t length = strlen(buf);
|
||||
if (width != last_window_width /*|| length != last_text_length*/) {
|
||||
last_window_width = width;
|
||||
//last_text_length = length;
|
||||
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
|
||||
imgui.set_requires_extra_frame();
|
||||
#else
|
||||
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty();
|
||||
wxGetApp().plater()->get_current_canvas3D()->request_extra_frame();
|
||||
#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
|
||||
}
|
||||
|
||||
imgui.end();
|
||||
imgui.pop_toolbar_style();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor(3);
|
||||
}
|
||||
|
||||
void GCodeViewer::SequentialView::GCodeWindow::load_gcode(const std::string& filename, std::vector<size_t> &&lines_ends)
|
||||
|
@ -561,11 +627,10 @@ void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file()
|
|||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": finished mapping file " << m_filename;
|
||||
}
|
||||
}
|
||||
|
||||
//BBS: GUI refactor: move to the right
|
||||
void GCodeViewer::SequentialView::render(float legend_height, int canvas_width, int canvas_height) const
|
||||
void GCodeViewer::SequentialView::render(float legend_height, int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves) const
|
||||
{
|
||||
marker.render(canvas_width, canvas_height);
|
||||
marker.render(canvas_width, canvas_height, view_type, moves, static_cast<uint64_t>(gcode_ids[current.last]));
|
||||
//float bottom = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_height();
|
||||
// BBS
|
||||
#if 0
|
||||
|
@ -766,6 +831,10 @@ void GCodeViewer::init(ConfigOptionMode mode, PresetBundle* preset_bundle)
|
|||
void GCodeViewer::set_scale(float scale)
|
||||
{
|
||||
if(m_scale != scale)m_scale = scale;
|
||||
if (m_sequential_view.m_scale != scale) {
|
||||
m_sequential_view.m_scale = scale;
|
||||
m_sequential_view.marker.m_scale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
void GCodeViewer::update_by_mode(ConfigOptionMode mode)
|
||||
|
@ -804,6 +873,11 @@ void GCodeViewer::update_by_mode(ConfigOptionMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<int> GCodeViewer::get_plater_extruder()
|
||||
{
|
||||
return m_plater_extruder;
|
||||
}
|
||||
|
||||
//BBS: always load shell at preview
|
||||
void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print, const BuildVolume& build_volume,
|
||||
const std::vector<BoundingBoxf3>& exclude_bounding_box, bool initialized, ConfigOptionMode mode, bool only_gcode)
|
||||
|
@ -1125,7 +1199,7 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin)
|
|||
m_sequential_view.marker.set_world_position(m_sequential_view.current_position);
|
||||
m_sequential_view.marker.set_world_offset(m_sequential_view.current_offset);
|
||||
//BBS fixed buttom margin. m_moves_slider.pos_y
|
||||
m_sequential_view.render(legend_height, canvas_width - right_margin, canvas_height - bottom_margin);
|
||||
m_sequential_view.render(legend_height, canvas_width - right_margin * m_scale, canvas_height - bottom_margin * m_scale, m_view_type, m_gcode_result->moves);
|
||||
//}
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
render_statistics();
|
||||
|
@ -2897,6 +2971,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const
|
|||
sort_remove_duplicates(m_extruder_ids);
|
||||
m_extruder_ids.shrink_to_fit();
|
||||
|
||||
std::vector<int> plater_extruder;
|
||||
for (auto mid : m_extruder_ids){
|
||||
int eid = mid;
|
||||
plater_extruder.push_back(++eid);
|
||||
}
|
||||
m_plater_extruder = plater_extruder;
|
||||
|
||||
|
||||
// set layers z range
|
||||
if (!m_layers.empty())
|
||||
m_layers_z_range = { 0, static_cast<unsigned int>(m_layers.size() - 1) };
|
||||
|
@ -4122,7 +4204,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
}
|
||||
else {
|
||||
imgui.text(label);
|
||||
/* BBS refactor do not show used_filament info
|
||||
// BBS refactor do not show used_filament info
|
||||
if (used_filament_m > 0.0) {
|
||||
char buf[64];
|
||||
ImGui::SameLine(offsets[0]);
|
||||
|
@ -4131,7 +4213,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
ImGui::SameLine(offsets[1]);
|
||||
::sprintf(buf, "%.2f g", used_filament_g);
|
||||
imgui.text(buf);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
|
||||
|
@ -4318,6 +4400,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
std::vector<float> percents;
|
||||
std::vector<double> used_filaments_m;
|
||||
std::vector<double> used_filaments_g;
|
||||
double total_flushed_filament_m = 0.0;
|
||||
double total_flushed_filament_g = 0.0;
|
||||
|
||||
float max_percent = 0.0f;
|
||||
|
||||
|
@ -4418,19 +4502,31 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
used_filaments_g.push_back(used_filament_g);
|
||||
}
|
||||
|
||||
for (size_t extruder_id : m_extruder_ids) {
|
||||
if (m_print_statistics.flush_per_filament.find(extruder_id) == m_print_statistics.flush_per_filament.end()) continue;
|
||||
double volume = m_print_statistics.flush_per_filament.at(extruder_id);
|
||||
auto [flushed_filament_m, flushed_filament_g] = get_used_filament_from_volume(volume, extruder_id);
|
||||
total_flushed_filament_m += flushed_filament_m;
|
||||
total_flushed_filament_g += flushed_filament_g;
|
||||
}
|
||||
|
||||
std::string longest_used_filament_string;
|
||||
char buffer[64];
|
||||
for (double item : used_filaments_m) {
|
||||
char buffer[64];
|
||||
::sprintf(buffer, imperial_units ? "%.2f in" : "%.2f m", item);
|
||||
if (::strlen(buffer) > longest_used_filament_string.length()) longest_used_filament_string = buffer;
|
||||
}
|
||||
::sprintf(buffer, imperial_units ? "%.2f in" : "%.2f m", total_flushed_filament_m);
|
||||
if (::strlen(buffer) > longest_used_filament_string.length()) longest_used_filament_string = buffer;
|
||||
|
||||
std::string longest_used_filament_g_string;
|
||||
for (double item : used_filaments_g) {
|
||||
char buffer[64];
|
||||
::sprintf(buffer, imperial_units ? "%.2fg" : "%.2fg", item);
|
||||
::sprintf(buffer, imperial_units ? "%.2f g" : "%.2f g", item);
|
||||
if (::strlen(buffer) > longest_used_filament_g_string.length()) longest_used_filament_g_string = buffer;
|
||||
}
|
||||
::sprintf(buffer, imperial_units ? "%.2f g" : "%.2f g", total_flushed_filament_g);
|
||||
if (::strlen(buffer) > longest_used_filament_g_string.length()) longest_used_filament_g_string = buffer;
|
||||
|
||||
// BBL XX is placeholder
|
||||
offsets = calculate_offsets(labels, times, {_u8L("Filament N XX"), longest_used_filament_string, longest_used_filament_g_string, _u8L("Display")}, icon_size);
|
||||
append_headers({ _u8L("Color Print"), _u8L("Comsumption"), "", "", _u8L("Display") }, offsets);
|
||||
|
@ -4608,34 +4704,36 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
|
||||
//BBS display filament change times
|
||||
if (m_print_statistics.total_filamentchanges > 0) {
|
||||
std::string flushed_filament_title_str = _u8L("Flushed filament");
|
||||
std::string flushed_filament_str = _u8L("Filament");
|
||||
std::string total_flushed_filament_str = _u8L("Total");
|
||||
std::string filament_change_str = _u8L("Filament change times");
|
||||
ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1));
|
||||
ImGui::Dummy({ window_padding, window_padding });
|
||||
ImGui::SameLine();
|
||||
imgui.title(flushed_filament_title_str);
|
||||
//BBS: calculate total flushed filaments data
|
||||
double total_flushed_filament_m = 0.0;
|
||||
double total_flushed_filament_g = 0.0;
|
||||
float max_len = 10.0f + ImGui::GetStyle().ItemSpacing.x;
|
||||
max_len += ImGui::CalcTextSize(filament_change_str.c_str()).x;
|
||||
for (size_t extruder_id : m_extruder_ids) {
|
||||
if (m_print_statistics.flush_per_filament.find(extruder_id) == m_print_statistics.flush_per_filament.end())
|
||||
continue;
|
||||
if (m_print_statistics.flush_per_filament.find(extruder_id) == m_print_statistics.flush_per_filament.end()) continue;
|
||||
double volume = m_print_statistics.flush_per_filament.at(extruder_id);
|
||||
|
||||
auto [used_filament_m, used_filament_g] = get_used_filament_from_volume(volume, extruder_id);
|
||||
total_flushed_filament_m += used_filament_m;
|
||||
total_flushed_filament_g += used_filament_g;
|
||||
append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_id], flushed_filament_str + " " + std::to_string(extruder_id + 1), true, "", 0.0f, 0.0f, offsets,
|
||||
used_filament_m, used_filament_g);
|
||||
}
|
||||
|
||||
std::string flushed_filament_str = _u8L("Flushed filament");
|
||||
std::string filament_change_str = _u8L("Filament change times");
|
||||
float max_len = 10.0f + ImGui::GetStyle().ItemSpacing.x;
|
||||
max_len += std::max(ImGui::CalcTextSize(filament_change_str.c_str()).x, ImGui::CalcTextSize(flushed_filament_str.c_str()).x);
|
||||
//BBS: display total flushed filament
|
||||
{
|
||||
ImGui::Dummy({window_padding, window_padding});
|
||||
ImGui::SameLine();
|
||||
imgui.text(flushed_filament_str + ":");
|
||||
ImGui::SameLine(max_len);
|
||||
imgui.text(total_flushed_filament_str + ":");
|
||||
ImGui::SameLine(offsets[0]);
|
||||
char buf[64];
|
||||
::sprintf(buf, "%.2f m", total_flushed_filament_m);
|
||||
imgui.text(buf);
|
||||
ImGui::SameLine();
|
||||
::sprintf(buf, " %.2f g", total_flushed_filament_g);
|
||||
ImGui::SameLine(offsets[1]);
|
||||
::sprintf(buf, "%.2f g", total_flushed_filament_g);
|
||||
imgui.text(buf);
|
||||
}
|
||||
//BBS display filament change times
|
||||
|
@ -4645,7 +4743,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
imgui.text(filament_change_str + ":");
|
||||
ImGui::SameLine(max_len);
|
||||
char temp_buf[64];
|
||||
::sprintf(temp_buf, " %d", m_print_statistics.total_filamentchanges);
|
||||
::sprintf(temp_buf, "%d", m_print_statistics.total_filamentchanges);
|
||||
imgui.text(temp_buf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -600,6 +600,7 @@ class GCodeViewer
|
|||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
|
||||
public:
|
||||
enum class EViewType : unsigned char;
|
||||
struct SequentialView
|
||||
{
|
||||
class Marker
|
||||
|
@ -615,6 +616,8 @@ public:
|
|||
bool m_visible{ true };
|
||||
|
||||
public:
|
||||
float m_scale = 1.0f;
|
||||
|
||||
void init(std::string filename);
|
||||
|
||||
const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); }
|
||||
|
@ -626,7 +629,7 @@ public:
|
|||
void set_visible(bool visible) { m_visible = visible; }
|
||||
|
||||
//BBS: GUI refactor: add canvas size
|
||||
void render(int canvas_width, int canvas_height) const;
|
||||
void render(int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves, uint64_t curr_line_id) const;
|
||||
};
|
||||
|
||||
class GCodeWindow
|
||||
|
@ -683,9 +686,10 @@ public:
|
|||
Marker marker;
|
||||
GCodeWindow gcode_window;
|
||||
std::vector<unsigned int> gcode_ids;
|
||||
float m_scale = 1.0;
|
||||
|
||||
//BBS: GUI refactor: add canvas size
|
||||
void render(float legend_height, int canvas_width, int canvas_height) const;
|
||||
void render(float legend_height, int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves) const;
|
||||
};
|
||||
|
||||
struct ETools
|
||||
|
@ -710,6 +714,7 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
std::vector<int> m_plater_extruder;
|
||||
bool m_gl_data_initialized{ false };
|
||||
unsigned int m_last_result_id{ 0 };
|
||||
size_t m_moves_count{ 0 };
|
||||
|
@ -799,6 +804,7 @@ public:
|
|||
|
||||
bool has_data() const { return !m_roles.empty(); }
|
||||
bool can_export_toolpaths() const;
|
||||
std::vector<int> get_plater_extruder();
|
||||
|
||||
const BoundingBoxf3& get_paths_bounding_box() const { return m_paths_bounding_box; }
|
||||
const BoundingBoxf3& get_max_bounding_box() const { return m_max_bounding_box; }
|
||||
|
|
|
@ -3889,6 +3889,14 @@ void GLCanvas3D::do_flatten(const Vec3d& normal, const std::string& snapshot_typ
|
|||
do_rotate(""); // avoid taking another snapshot
|
||||
}
|
||||
|
||||
void GLCanvas3D::do_center()
|
||||
{
|
||||
if (m_model == nullptr)
|
||||
return;
|
||||
|
||||
m_selection.center();
|
||||
}
|
||||
|
||||
void GLCanvas3D::do_mirror(const std::string& snapshot_type)
|
||||
{
|
||||
if (m_model == nullptr)
|
||||
|
@ -4074,15 +4082,15 @@ double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const
|
|||
}
|
||||
|
||||
//BBS
|
||||
std::vector<Vec2f> GLCanvas3D::get_empty_cells(const Vec2f start_point)
|
||||
std::vector<Vec2f> GLCanvas3D::get_empty_cells(const Vec2f start_point, const Vec2f step)
|
||||
{
|
||||
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
|
||||
BoundingBoxf3 build_volume = plate->get_build_volume();
|
||||
Vec2d vmin(build_volume.min.x(), build_volume.min.y()), vmax(build_volume.max.x(), build_volume.max.y());
|
||||
BoundingBoxf bbox(vmin, vmax);
|
||||
std::vector<Vec2f> cells;
|
||||
for (float x = bbox.min.x(); x < bbox.max.x(); x+=10)
|
||||
for (float y = bbox.min.y(); y < bbox.max.y(); y += 10)
|
||||
for (float x = bbox.min.x(); x < bbox.max.x(); x += step(0))
|
||||
for (float y = bbox.min.y(); y < bbox.max.y(); y += step(1))
|
||||
{
|
||||
cells.emplace_back(x, y);
|
||||
}
|
||||
|
@ -4124,9 +4132,9 @@ std::vector<Vec2f> GLCanvas3D::get_empty_cells(const Vec2f start_point)
|
|||
return cells;
|
||||
}
|
||||
|
||||
Vec2f GLCanvas3D::get_nearest_empty_cell(const Vec2f start_point)
|
||||
Vec2f GLCanvas3D::get_nearest_empty_cell(const Vec2f start_point, const Vec2f step)
|
||||
{
|
||||
std::vector<Vec2f> empty_cells = get_empty_cells(start_point);
|
||||
std::vector<Vec2f> empty_cells = get_empty_cells(start_point, step);
|
||||
if (!empty_cells.empty())
|
||||
return empty_cells.front();
|
||||
else {
|
||||
|
|
|
@ -357,8 +357,7 @@ public:
|
|||
|
||||
struct ArrangeSettings
|
||||
{
|
||||
float distance = 1.;
|
||||
// float distance_seq_print = 6.; // Used when sequential print is ON
|
||||
float distance = 5.;
|
||||
// float distance_sla = 6.;
|
||||
float accuracy = 0.65f; // Unused currently
|
||||
bool enable_rotation = false;
|
||||
|
@ -784,6 +783,7 @@ public:
|
|||
void do_rotate(const std::string& snapshot_type);
|
||||
void do_scale(const std::string& snapshot_type);
|
||||
void do_flatten(const Vec3d& normal, const std::string& snapshot_type);
|
||||
void do_center();
|
||||
void do_mirror(const std::string& snapshot_type);
|
||||
|
||||
void update_gizmos_on_off_state();
|
||||
|
@ -831,11 +831,11 @@ public:
|
|||
double get_size_proportional_to_max_bed_size(double factor) const;
|
||||
|
||||
// BBS: get empty cells to put new object
|
||||
// start_point={-1,-1} means sort from bed center
|
||||
std::vector<Vec2f> get_empty_cells(const Vec2f start_point);
|
||||
// start_point={-1,-1} means sort from bed center, step is the unscaled x,y stride
|
||||
std::vector<Vec2f> get_empty_cells(const Vec2f start_point, const Vec2f step = {10, 10});
|
||||
// BBS: get the nearest empty cell
|
||||
// start_point={-1,-1} means sort from bed center
|
||||
Vec2f get_nearest_empty_cell(const Vec2f start_point);
|
||||
Vec2f get_nearest_empty_cell(const Vec2f start_point, const Vec2f step = {10, 10});
|
||||
|
||||
void set_cursor(ECursorType type);
|
||||
void msw_rescale();
|
||||
|
|
|
@ -771,7 +771,7 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, boo
|
|||
else
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
|
||||
if (use_mipmaps) {
|
||||
if (use_mipmaps && OpenGLManager::use_manually_generated_mipmaps()) {
|
||||
// we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards
|
||||
int lod_w = m_width;
|
||||
int lod_h = m_height;
|
||||
|
@ -800,8 +800,9 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, boo
|
|||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else if (use_mipmaps && !OpenGLManager::use_manually_generated_mipmaps()) {
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
} else {
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
#include "SysInfoDialog.hpp"
|
||||
#include "UpdateDialogs.hpp"
|
||||
#include "Mouse3DController.hpp"
|
||||
//#include "RemovableDriveManager.hpp"
|
||||
#include "RemovableDriveManager.hpp"
|
||||
#include "InstanceCheck.hpp"
|
||||
#include "NotificationManager.hpp"
|
||||
#include "UnsavedChangesDialog.hpp"
|
||||
|
@ -1098,6 +1098,31 @@ void GUI_App::post_init()
|
|||
std::string functional_config_file = Slic3r::resources_dir() + "/config.json";
|
||||
DeviceManager::load_functional_config(encode_path(functional_config_file.c_str()));
|
||||
|
||||
// remove old log files over LOG_FILES_MAX_NUM
|
||||
std::string log_addr = data_dir();
|
||||
if (!log_addr.empty()) {
|
||||
auto log_folder = boost::filesystem::path(log_addr) / "log";
|
||||
if (boost::filesystem::exists(log_folder)) {
|
||||
std::vector<std::pair<time_t, std::string>> files_vec;
|
||||
for (auto& it : boost::filesystem::directory_iterator(log_folder)) {
|
||||
auto temp_path = it.path();
|
||||
std::time_t lw_t = boost::filesystem::last_write_time(temp_path) ;
|
||||
files_vec.push_back({ lw_t, temp_path.filename().string() });
|
||||
}
|
||||
std::sort(files_vec.begin(), files_vec.end(), [](
|
||||
std::pair<time_t, std::string> &a, std::pair<time_t, std::string> &b) {
|
||||
return a.first > b.first;
|
||||
});
|
||||
|
||||
while (files_vec.size() > LOG_FILES_MAX_NUM) {
|
||||
auto full_path = log_folder / boost::filesystem::path(files_vec[files_vec.size() - 1].second);
|
||||
BOOST_LOG_TRIVIAL(info) << "delete log file over " << LOG_FILES_MAX_NUM << ", filename: "<< files_vec[files_vec.size() - 1].second;
|
||||
boost::filesystem::remove(full_path);
|
||||
files_vec.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "finished post_init";
|
||||
//BBS: remove the single instance currently
|
||||
/*#ifdef _WIN32
|
||||
|
@ -1121,7 +1146,7 @@ GUI_App::GUI_App()
|
|||
, m_em_unit(10)
|
||||
, m_imgui(new ImGuiWrapper())
|
||||
, hms_query(new HMSQuery())
|
||||
//, m_removable_drive_manager(std::make_unique<RemovableDriveManager>())
|
||||
, m_removable_drive_manager(std::make_unique<RemovableDriveManager>())
|
||||
//, m_other_instance_message_handler(std::make_unique<OtherInstanceMessageHandler>())
|
||||
{
|
||||
//app config initializes early becasuse it is used in instance checking in BambuStudio.cpp
|
||||
|
@ -1134,6 +1159,10 @@ void GUI_App::shutdown()
|
|||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "shutdown";
|
||||
|
||||
if (m_removable_drive_manager) {
|
||||
removable_drive_manager()->shutdown();
|
||||
}
|
||||
|
||||
if (m_is_recreating_gui) return;
|
||||
m_is_closing = true;
|
||||
stop_sync_user_preset();
|
||||
|
@ -1343,7 +1372,10 @@ int GUI_App::install_plugin(InstallProgressFn pro_fn, WasCancelledFn cancel_fn)
|
|||
|
||||
BOOST_LOG_TRIVIAL(info) << "[install_plugin] enter";
|
||||
// get plugin folder
|
||||
auto plugin_folder = boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins";
|
||||
std::string data_dir_str = data_dir();
|
||||
boost::filesystem::path data_dir_path(data_dir_str);
|
||||
auto plugin_folder = data_dir_path / "plugins";
|
||||
//auto plugin_folder = boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins";
|
||||
auto backup_folder = plugin_folder/"backup";
|
||||
if (!boost::filesystem::exists(plugin_folder)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "[install_plugin] will create directory "<<plugin_folder.string();
|
||||
|
@ -1486,7 +1518,10 @@ void GUI_App::restart_networking()
|
|||
|
||||
void GUI_App::remove_old_networking_plugins()
|
||||
{
|
||||
auto plugin_folder = boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins";
|
||||
std::string data_dir_str = data_dir();
|
||||
boost::filesystem::path data_dir_path(data_dir_str);
|
||||
auto plugin_folder = data_dir_path / "plugins";
|
||||
//auto plugin_folder = boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins";
|
||||
if (boost::filesystem::exists(plugin_folder)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "[remove_old_networking_plugins] remove the directory "<<plugin_folder.string();
|
||||
try {
|
||||
|
@ -1643,12 +1678,9 @@ void GUI_App::init_networking_callbacks()
|
|||
|
||||
if (obj) {
|
||||
obj->parse_json(msg);
|
||||
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
if (obj->is_ams_need_update) {
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj->amsList);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -2024,8 +2056,8 @@ bool GUI_App::on_init_inner()
|
|||
if (!skip_this_version
|
||||
|| evt.GetInt() != 0) {
|
||||
UpdateVersionDialog dialog(this->mainframe);
|
||||
wxString extmsg = wxString::FromUTF8(version_info.description);
|
||||
dialog.update_version_info(extmsg, version_info.version_str);
|
||||
//dialog.update_version_info(extmsg, version_info.version_str);
|
||||
dialog.update_version_info(version_info.description);
|
||||
if (evt.GetInt() != 0) {
|
||||
dialog.m_remind_choice->Hide();
|
||||
}
|
||||
|
@ -2235,11 +2267,11 @@ bool GUI_App::on_init_inner()
|
|||
|
||||
// An ugly solution to GH #5537 in which GUI_App::init_opengl (normally called from events wxEVT_PAINT
|
||||
// and wxEVT_SET_FOCUS before GUI_App::post_init is called) wasn't called before GUI_App::post_init and OpenGL wasn't initialized.
|
||||
#ifdef __linux__
|
||||
if (!m_post_initialized && m_opengl_initialized) {
|
||||
#else
|
||||
//#ifdef __linux__
|
||||
// if (!m_post_initialized && m_opengl_initialized) {
|
||||
//#else
|
||||
if (!m_post_initialized) {
|
||||
#endif
|
||||
//#endif
|
||||
m_post_initialized = true;
|
||||
#ifdef WIN32
|
||||
this->mainframe->register_win32_callbacks();
|
||||
|
@ -2306,11 +2338,12 @@ __retry:
|
|||
m_device_manager = new Slic3r::DeviceManager(m_agent);
|
||||
else
|
||||
m_device_manager->set_agent(m_agent);
|
||||
std::string data_dir = wxStandardPaths::Get().GetUserDataDir().ToUTF8().data();
|
||||
//std::string data_dir = wxStandardPaths::Get().GetUserDataDir().ToUTF8().data();
|
||||
std::string data_directory = data_dir();
|
||||
|
||||
//BBS set config dir
|
||||
if (m_agent) {
|
||||
m_agent->set_config_dir(data_dir);
|
||||
m_agent->set_config_dir(data_directory);
|
||||
}
|
||||
//BBS set cert dir
|
||||
if (m_agent)
|
||||
|
@ -4007,7 +4040,7 @@ bool GUI_App::load_language(wxString language, bool initial)
|
|||
|
||||
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
|
||||
//wxSetlocale(LC_NUMERIC, "C");
|
||||
Preset::update_suffix_modified((" (" + _L("*") + ")").ToUTF8().data());
|
||||
Preset::update_suffix_modified((_L("*") + " ").ToUTF8().data());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#define BBL_HAS_FIRST_PAGE 1
|
||||
#define STUDIO_INACTIVE_TIMEOUT 15*60*1000
|
||||
#define LOG_FILES_MAX_NUM 30
|
||||
|
||||
class wxMenuItem;
|
||||
class wxMenuBar;
|
||||
|
@ -52,7 +53,7 @@ class NetworkAgent;
|
|||
|
||||
namespace GUI{
|
||||
|
||||
//class RemovableDriveManager;
|
||||
class RemovableDriveManager;
|
||||
class OtherInstanceMessageHandler;
|
||||
class MainFrame;
|
||||
class Sidebar;
|
||||
|
@ -247,7 +248,7 @@ private:
|
|||
const wxLanguageInfo *m_language_info_best = nullptr;
|
||||
|
||||
OpenGLManager m_opengl_mgr;
|
||||
//std::unique_ptr<RemovableDriveManager> m_removable_drive_manager;
|
||||
std::unique_ptr<RemovableDriveManager> m_removable_drive_manager;
|
||||
|
||||
std::unique_ptr<ImGuiWrapper> m_imgui;
|
||||
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
|
||||
|
@ -484,7 +485,7 @@ public:
|
|||
std::vector<Tab *> tabs_list;
|
||||
std::vector<Tab *> model_tabs_list;
|
||||
|
||||
//RemovableDriveManager* removable_drive_manager() { return m_removable_drive_manager.get(); }
|
||||
RemovableDriveManager* removable_drive_manager() { return m_removable_drive_manager.get(); }
|
||||
//OtherInstanceMessageHandler* other_instance_message_handler() { return m_other_instance_message_handler.get(); }
|
||||
//wxSingleInstanceChecker* single_instance_checker() {return m_single_instance_checker.get();}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ static SettingsFactory::Bundle FREQ_SETTINGS_BUNDLE_FFF =
|
|||
{ L("Infill") , { "sparse_infill_density", "sparse_infill_pattern" } },
|
||||
// BBS
|
||||
{ L("Support") , { "enable_support", "support_type", "support_threshold_angle",
|
||||
"support_base_pattern", "support_on_build_plate_only",
|
||||
"support_base_pattern", "support_on_build_plate_only","support_critical_regions_only",
|
||||
"support_base_pattern_spacing" } }
|
||||
//BBS
|
||||
//{ L("Wipe options") , { "flush_into_infill", "flush_into_objects" } }
|
||||
|
@ -81,7 +81,7 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::OBJECT_C
|
|||
{"tree_support_branch_angle", "",10}, {"tree_support_wall_count", "",11},{"tree_support_with_infill", "",12},//tree support
|
||||
{"support_top_z_distance", "",13},{"support_base_pattern", "",14},{"support_base_pattern_spacing", "",15},
|
||||
{"support_interface_top_layers", "",16},{"support_interface_bottom_layers", "",17},{"support_interface_spacing", "",18},{"support_bottom_interface_spacing", "",19},
|
||||
{"support_object_xy_distance", "",20}, {"bridge_no_support", "",21},{"max_bridge_length", "",22}
|
||||
{"support_object_xy_distance", "",20}, {"bridge_no_support", "",21},{"max_bridge_length", "",22},{"support_critical_regions_only", "",23}
|
||||
}},
|
||||
{ L("Speed"), {{"support_speed", "",12}, {"support_interface_speed", "",13}
|
||||
}}
|
||||
|
@ -138,7 +138,7 @@ std::vector<SimpleSettingData> SettingsFactory::get_visible_options(const std::s
|
|||
//Quality
|
||||
"layer_height", "initial_layer_print_height", "adaptive_layer_height", "seam_position", "xy_hole_compensation", "xy_contour_compensation", "elefant_foot_compensation", "support_line_width",
|
||||
//Support
|
||||
"enable_support", "support_type", "support_threshold_angle", "support_on_build_plate_only", "enforce_support_layers",
|
||||
"enable_support", "support_type", "support_threshold_angle", "support_on_build_plate_only", "support_critical_regions_only", "enforce_support_layers",
|
||||
//tree support
|
||||
"tree_support_wall_count", "tree_support_with_infill",
|
||||
//support
|
||||
|
@ -652,12 +652,18 @@ void MenuFactory::append_menu_item_export_stl(wxMenu* menu, bool is_mulity_menu)
|
|||
|
||||
void MenuFactory::append_menu_item_reload_from_disk(wxMenu* menu)
|
||||
{
|
||||
// BBS: change "Reload from disk" to "Reload item"
|
||||
append_menu_item(menu, wxID_ANY, _L("Reload item"), _L("Reload items"),
|
||||
append_menu_item(menu, wxID_ANY, _L("Reload from disk"), _L("Reload the selected parts from disk"),
|
||||
[](wxCommandEvent&) { plater()->reload_from_disk(); }, "", menu,
|
||||
[]() { return plater()->can_reload_from_disk(); }, m_parent);
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_replace_with_stl(wxMenu *menu)
|
||||
{
|
||||
append_menu_item(menu, wxID_ANY, _L("Replace with STL"), _L("Replace the selected part with new STL"),
|
||||
[](wxCommandEvent &) { plater()->replace_with_stl(); }, "", menu,
|
||||
[]() { return plater()->can_replace_with_stl(); }, m_parent);
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_change_extruder(wxMenu* menu)
|
||||
{
|
||||
// BBS
|
||||
|
@ -886,6 +892,8 @@ void MenuFactory::create_bbl_object_menu()
|
|||
append_menu_item_fix_through_netfabb(&m_object_menu);
|
||||
// Object Simplify
|
||||
append_menu_item_simplify(&m_object_menu);
|
||||
// Object Center
|
||||
append_menu_item_center(&m_object_menu);
|
||||
// Object Split
|
||||
wxMenu* split_menu = new wxMenu();
|
||||
if (!split_menu)
|
||||
|
@ -915,6 +923,8 @@ void MenuFactory::create_bbl_object_menu()
|
|||
// Enter per object parameters
|
||||
append_menu_item_per_object_settings(&m_object_menu);
|
||||
m_object_menu.AppendSeparator();
|
||||
append_menu_item_reload_from_disk(&m_object_menu);
|
||||
append_menu_item_replace_with_stl(&m_object_menu);
|
||||
append_menu_item_export_stl(&m_object_menu);
|
||||
}
|
||||
|
||||
|
@ -975,6 +985,7 @@ void MenuFactory::create_bbl_part_menu()
|
|||
append_menu_item_delete(menu);
|
||||
append_menu_item_fix_through_netfabb(menu);
|
||||
append_menu_item_simplify(menu);
|
||||
append_menu_item_center(menu);
|
||||
append_menu_items_mirror(menu);
|
||||
wxMenu* split_menu = new wxMenu();
|
||||
if (!split_menu)
|
||||
|
@ -992,6 +1003,8 @@ void MenuFactory::create_bbl_part_menu()
|
|||
menu->AppendSeparator();
|
||||
append_menu_item_per_object_settings(menu);
|
||||
append_menu_item_change_type(menu);
|
||||
append_menu_item_reload_from_disk(menu);
|
||||
append_menu_item_replace_with_stl(menu);
|
||||
}
|
||||
|
||||
void MenuFactory::create_bbl_assemble_part_menu()
|
||||
|
@ -1172,6 +1185,7 @@ wxMenu* MenuFactory::multi_selection_menu()
|
|||
append_menu_item_merge_to_multipart_object(menu);
|
||||
index++;
|
||||
}
|
||||
append_menu_item_center(menu);
|
||||
append_menu_item_fix_through_netfabb(menu);
|
||||
//append_menu_item_simplify(menu);
|
||||
append_menu_item_delete(menu);
|
||||
|
@ -1186,6 +1200,7 @@ wxMenu* MenuFactory::multi_selection_menu()
|
|||
append_menu_item_export_stl(menu, true);
|
||||
}
|
||||
else {
|
||||
append_menu_item_center(menu);
|
||||
append_menu_item_fix_through_netfabb(menu);
|
||||
//append_menu_item_simplify(menu);
|
||||
append_menu_item_delete(menu);
|
||||
|
@ -1264,11 +1279,30 @@ void MenuFactory::append_menu_item_clone(wxMenu* menu)
|
|||
|
||||
void MenuFactory::append_menu_item_simplify(wxMenu* menu)
|
||||
{
|
||||
wxMenuItem* menu_item = append_menu_item(menu, wxID_ANY, _L("Reduce Triangles"), "",
|
||||
wxMenuItem* menu_item = append_menu_item(menu, wxID_ANY, _L("Simplify Model"), "",
|
||||
[](wxCommandEvent&) { obj_list()->simplify(); }, "", menu,
|
||||
[]() {return plater()->can_simplify(); }, m_parent);
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_center(wxMenu* menu)
|
||||
{
|
||||
append_menu_item(menu, wxID_ANY, _L("Center") , "",
|
||||
[this](wxCommandEvent&) {
|
||||
plater()->center_selection();
|
||||
}, "", nullptr,
|
||||
[]() {
|
||||
if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D)
|
||||
return false;
|
||||
else {
|
||||
Selection& selection = plater()->get_view3D_canvas3D()->get_selection();
|
||||
PartPlate* plate = plater()->get_partplate_list().get_selected_plate();
|
||||
Vec3d model_pos = selection.get_bounding_box().center();
|
||||
Vec3d center_pos = plate->get_center_origin();
|
||||
return !( (model_pos.x() == center_pos.x()) && (model_pos.y() == center_pos.y()) );
|
||||
} //disable if model is at center / not in View3D
|
||||
}, m_parent);
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_per_object_settings(wxMenu* menu)
|
||||
{
|
||||
const std::vector<wxString> names = { _L("Edit in Parameter Table"), _L("Edit print parameters for a single object") };
|
||||
|
@ -1309,6 +1343,9 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu)
|
|||
return;
|
||||
|
||||
std::vector<wxBitmap*> icons = get_extruder_color_icons(true);
|
||||
if (icons.size() < filaments_cnt) {
|
||||
BOOST_LOG_TRIVIAL(warning) << boost::format("Warning: icons size %1%, filaments_cnt=%2%")%icons.size()%filaments_cnt;
|
||||
}
|
||||
wxMenu* extruder_selection_menu = new wxMenu();
|
||||
const wxString& name = sels.Count() == 1 ? names[0] : names[1];
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ private:
|
|||
//BBS add bbl menu item
|
||||
void append_menu_item_clone(wxMenu* menu);
|
||||
void append_menu_item_simplify(wxMenu* menu);
|
||||
void append_menu_item_center(wxMenu* menu);
|
||||
void append_menu_item_per_object_settings(wxMenu* menu);
|
||||
void append_menu_item_change_filament(wxMenu* menu);
|
||||
void append_menu_item_set_printable(wxMenu* menu);
|
||||
|
|
|
@ -3353,12 +3353,9 @@ void ObjectTableDialog::OnClose(wxCloseEvent &evt)
|
|||
delete m_obj_panel;
|
||||
m_obj_panel = nullptr;
|
||||
}
|
||||
|
||||
DestroyChildren();
|
||||
Destroy();
|
||||
#endif
|
||||
|
||||
#ifdef __WXOSX_MAC__
|
||||
#else
|
||||
evt.Skip();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -148,6 +148,12 @@ void View3D::delete_selected()
|
|||
m_canvas->delete_selected();
|
||||
}
|
||||
|
||||
void View3D::center_selected()
|
||||
{
|
||||
if (m_canvas != nullptr)
|
||||
m_canvas->do_center();
|
||||
}
|
||||
|
||||
void View3D::mirror_selection(Axis axis)
|
||||
{
|
||||
if (m_canvas != nullptr)
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
void select_all();
|
||||
void deselect_all();
|
||||
void delete_selected();
|
||||
void center_selected();
|
||||
void mirror_selection(Axis axis);
|
||||
|
||||
bool is_dragging() const;
|
||||
|
|
|
@ -479,6 +479,13 @@ void GLGizmoAdvancedCut::on_render_input_window(float x, float y, float bottom_l
|
|||
if (std::abs(m_buffered_movement - m_movement) > EPSILON) {
|
||||
m_movement = m_buffered_movement;
|
||||
m_buffered_movement = 0.0;
|
||||
|
||||
// update absolute height
|
||||
Vec3d plane_normal = get_plane_normal();
|
||||
m_height_delta = plane_normal(2) * m_movement;
|
||||
m_height += m_height_delta;
|
||||
m_buffered_height = m_height;
|
||||
|
||||
update_plane_points();
|
||||
m_parent.post_event(SimpleEvent(wxEVT_PAINT));
|
||||
}
|
||||
|
@ -497,8 +504,7 @@ void GLGizmoAdvancedCut::on_render_input_window(float x, float y, float bottom_l
|
|||
if (current_active_id != m_last_active_id) {
|
||||
if (std::abs(m_buffered_height - m_height) > EPSILON) {
|
||||
m_height_delta = m_buffered_height - m_height;
|
||||
m_height = m_buffered_height;
|
||||
//m_buffered_height = 0.0;
|
||||
m_height = m_buffered_height;
|
||||
update_plane_points();
|
||||
m_parent.post_event(SimpleEvent(wxEVT_PAINT));
|
||||
}
|
||||
|
|
|
@ -120,6 +120,16 @@ void GLGizmoScale3D::on_start_dragging()
|
|||
|
||||
void GLGizmoScale3D::on_update(const UpdateData& data)
|
||||
{
|
||||
bool uniform_scale = false;
|
||||
AppConfig* config = wxGetApp().app_config;
|
||||
if (config)
|
||||
uniform_scale = config->get("uniform_scale") == "1" ? true : false;
|
||||
|
||||
if (uniform_scale) {
|
||||
do_scale_uniform(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_hover_id == 0) || (m_hover_id == 1))
|
||||
do_scale_along_axis(X, data);
|
||||
else if ((m_hover_id == 2) || (m_hover_id == 3))
|
||||
|
|
|
@ -569,7 +569,7 @@ void GLGizmoSimplify::apply_simplify() {
|
|||
mv->calculate_convex_hull();
|
||||
mv->set_new_unique_id();
|
||||
mv->get_object()->invalidate_bounding_box();
|
||||
mv->get_object()->ensure_on_bed(true); // allow negative z
|
||||
mv->get_object()->ensure_on_bed();
|
||||
|
||||
// fix hollowing, sla support points, modifiers, ...
|
||||
plater->changed_mesh(object_idx);
|
||||
|
|
|
@ -213,11 +213,6 @@ void GizmoObjectManipulation::update_if_dirty()
|
|||
update(m_cache.rotation, m_cache.rotation_rounded, m_new_rotation);
|
||||
}
|
||||
|
||||
|
||||
if (selection.requires_uniform_scale()) {
|
||||
m_uniform_scale = true;
|
||||
}
|
||||
|
||||
update_reset_buttons_visibility();
|
||||
//update_mirror_buttons_visibility();
|
||||
|
||||
|
@ -468,6 +463,9 @@ void GizmoObjectManipulation::set_uniform_scaling(const bool new_value)
|
|||
}
|
||||
}
|
||||
m_uniform_scale = new_value;
|
||||
AppConfig* config = wxGetApp().app_config;
|
||||
if (config)
|
||||
config->set("uniform_scale", new_value ? "1": "0");
|
||||
}
|
||||
|
||||
static const char* label_values[2][3] = {
|
||||
|
@ -899,6 +897,9 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
|
|||
|
||||
ImGui::Separator();
|
||||
|
||||
AppConfig* config = wxGetApp().app_config;
|
||||
if (config)
|
||||
this->m_uniform_scale = config->get("uniform_scale") == "1" ? true : false;
|
||||
bool uniform_scale = this->m_uniform_scale;
|
||||
|
||||
const Selection &selection = m_glcanvas.get_selection();
|
||||
|
|
|
@ -81,6 +81,7 @@ public:
|
|||
Vec3d m_buffered_size;
|
||||
bool m_new_enabled {true};
|
||||
bool m_uniform_scale {true};
|
||||
bool m_uniform_config {false};
|
||||
// Does the object manipulation panel work in World or Local coordinates?
|
||||
bool m_world_coordinates = true;
|
||||
|
||||
|
|
|
@ -150,9 +150,12 @@ wxString HMSQuery::query_hms_msg(std::string long_error_code)
|
|||
if (m_hms_json.contains("device_hms")) {
|
||||
if (m_hms_json["device_hms"].contains(lang_code)) {
|
||||
for (auto item = m_hms_json["device_hms"][lang_code].begin(); item != m_hms_json["device_hms"][lang_code].end(); item++) {
|
||||
if (item->contains("ecode") && (*item)["ecode"].get<std::string>() == long_error_code) {
|
||||
if (item->contains("intro")) {
|
||||
return wxString::FromUTF8((*item)["intro"].get<std::string>());
|
||||
if (item->contains("ecode")) {
|
||||
std::string temp_string = (*item)["ecode"].get<std::string>();
|
||||
if (boost::to_upper_copy(temp_string) == long_error_code) {
|
||||
if (item->contains("intro")) {
|
||||
return wxString::FromUTF8((*item)["intro"].get<std::string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,13 @@ HMSPanel::~HMSPanel() {
|
|||
|
||||
void HMSPanel::append_hms_panel(HMSItem& item) {
|
||||
m_notify_item = new HMSNotifyItem(m_scrolledWindow, item);
|
||||
m_top_sizer->Add(m_notify_item, 0, wxALIGN_CENTER_HORIZONTAL);
|
||||
wxString msg = wxGetApp().get_hms_query()->query_hms_msg(item.get_long_error_code());
|
||||
if (!msg.empty())
|
||||
m_top_sizer->Add(m_notify_item, 0, wxALIGN_CENTER_HORIZONTAL);
|
||||
else {
|
||||
// debug for hms display error info
|
||||
m_top_sizer->Add(m_notify_item, 0, wxALIGN_CENTER_HORIZONTAL);
|
||||
}
|
||||
}
|
||||
|
||||
void HMSPanel::delete_hms_panels() {
|
||||
|
|
|
@ -1271,7 +1271,7 @@ void IMSlider::render_menu()
|
|||
|
||||
//BBS render this menu item only when extruder_num > 1
|
||||
if (extruder_num > 1) {
|
||||
if (!m_can_change_color) {
|
||||
if (!m_can_change_color || m_draw_mode == dmSequentialFffPrint) {
|
||||
begin_menu(_u8L("Change Filament").c_str(), false);
|
||||
}
|
||||
else if (begin_menu(_u8L("Change Filament").c_str())) {
|
||||
|
@ -1360,9 +1360,7 @@ std::string IMSlider::get_label(int tick, LabelType label_type)
|
|||
}
|
||||
|
||||
char layer_height[64];
|
||||
m_values[value] == m_zero_layer_height ?
|
||||
::sprintf(layer_height, "") :
|
||||
::sprintf(layer_height, "%.2f", m_values.empty() ? m_label_koef * value : m_values[value]);
|
||||
::sprintf(layer_height, "%.2f", m_values.empty() ? m_label_koef * value : m_values[value]);
|
||||
if (label_type == ltHeight) return std::string(layer_height);
|
||||
if (label_type == ltHeightWithLayer) {
|
||||
char buffer[64];
|
||||
|
@ -1370,7 +1368,7 @@ std::string IMSlider::get_label(int tick, LabelType label_type)
|
|||
if (m_values[GetMinValueD()] == m_zero_layer_height) {
|
||||
layer_number = m_is_wipe_tower ? get_layer_number(value, label_type): (m_values.empty() ? value : value);
|
||||
m_values[value] == m_zero_layer_height ?
|
||||
::sprintf(buffer, "%5s", std::to_string(layer_number).c_str()) :
|
||||
::sprintf(buffer, "%5s\n%5s", _u8L("Start").c_str(), _u8L("G-code").c_str()) :
|
||||
::sprintf(buffer, "%5s\n%5s", std::to_string(layer_number).c_str(), layer_height);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -71,8 +71,8 @@ static const std::map<const wchar_t, std::string> font_icons_large = {
|
|||
{ImGui::CloseNotifButton , "notification_close" },
|
||||
{ImGui::CloseNotifHoverButton , "notification_close_hover" },
|
||||
//BBS removed
|
||||
//{ImGui::EjectButton , "notification_eject_sd" },
|
||||
//{ImGui::EjectHoverButton , "notification_eject_sd_hover" },
|
||||
{ImGui::EjectButton , "notification_eject_sd" },
|
||||
{ImGui::EjectHoverButton , "notification_eject_sd_hover" },
|
||||
//{ImGui::WarningMarker , "notification_warning" },
|
||||
//{ImGui::ErrorMarker , "notification_error" },
|
||||
{ImGui::CancelButton , "notification_cancel" },
|
||||
|
@ -118,6 +118,7 @@ int ImGuiWrapper::TOOLBAR_WINDOW_FLAGS = ImGuiWindowFlags_AlwaysAutoResize
|
|||
| ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_NoTitleBar;
|
||||
|
||||
static float accer = 1.f;
|
||||
|
||||
bool get_data_from_svg(const std::string &filename, unsigned int max_size_px, ThumbnailData &thumbnail_data)
|
||||
{
|
||||
|
@ -195,21 +196,7 @@ bool slider_behavior(ImGuiID id, const ImRect& region, const ImS32 v_min, const
|
|||
if (axis == ImGuiAxis_Y)
|
||||
mouse_wheel_responsive_region = ImRect(region.Min - ImVec2(0, handle_sz.y), region.Max + ImVec2(0, handle_sz.y));
|
||||
if (ImGui::ItemHoverable(mouse_wheel_responsive_region, id)) {
|
||||
#ifdef __APPLE__
|
||||
if (io.KeyShift)
|
||||
v_new = ImClamp(*out_value - 5 * (ImS32) (context.IO.MouseWheel), v_min, v_max);
|
||||
else if (io.KeyCtrl)
|
||||
v_new = ImClamp(*out_value + 5 * (ImS32) (context.IO.MouseWheel), v_min, v_max);
|
||||
else {
|
||||
v_new = ImClamp(*out_value + (ImS32) (context.IO.MouseWheel), v_min, v_max);
|
||||
}
|
||||
#else
|
||||
if (io.KeyCtrl || io.KeyShift)
|
||||
v_new = ImClamp(*out_value + 5 * (ImS32) (context.IO.MouseWheel), v_min, v_max);
|
||||
else {
|
||||
v_new = ImClamp(*out_value + (ImS32) (context.IO.MouseWheel), v_min, v_max);
|
||||
}
|
||||
#endif
|
||||
v_new = ImClamp(*out_value + (ImS32)(context.IO.MouseWheel * accer), v_min, v_max);
|
||||
}
|
||||
// drag behavior
|
||||
if (context.ActiveId == id)
|
||||
|
@ -416,9 +403,9 @@ bool ImGuiWrapper::update_mouse_data(wxMouseEvent& evt)
|
|||
io.MouseDown[1] = evt.RightIsDown();
|
||||
io.MouseDown[2] = evt.MiddleIsDown();
|
||||
float wheel_delta = static_cast<float>(evt.GetWheelDelta());
|
||||
if (wheel_delta != 0.0f)
|
||||
io.MouseWheel = static_cast<float>(evt.GetWheelRotation()) / wheel_delta;
|
||||
|
||||
if (wheel_delta != 0.0f) {
|
||||
io.MouseWheel = evt.GetWheelRotation() > 0 ? 1.f : -1.f;
|
||||
}
|
||||
unsigned buttons = (evt.LeftIsDown() ? 1 : 0) | (evt.RightIsDown() ? 2 : 0) | (evt.MiddleIsDown() ? 4 : 0);
|
||||
m_mouse_buttons = buttons;
|
||||
|
||||
|
@ -435,6 +422,19 @@ bool ImGuiWrapper::update_key_data(wxKeyEvent &evt)
|
|||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
if (evt.CmdDown()) {
|
||||
accer = 5.f;
|
||||
}
|
||||
else if (evt.ShiftDown()) {
|
||||
#ifdef __APPLE__
|
||||
accer = -5.f;
|
||||
#else
|
||||
accer = 5.f;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
accer = 1.f;
|
||||
|
||||
if (evt.GetEventType() == wxEVT_CHAR) {
|
||||
// Char event
|
||||
const auto key = evt.GetUnicodeKey();
|
||||
|
|
|
@ -187,6 +187,9 @@ void ImageGrid::UpdateLayout()
|
|||
{
|
||||
if (!m_file_sys) return;
|
||||
wxSize size = GetClientSize();
|
||||
wxSize mask_size{0, 60 * em_unit(this) / 10};
|
||||
if (m_file_sys->GetGroupMode() == PrinterFileSystem::G_NONE)
|
||||
mask_size.y = 20 * em_unit(this) / 10;
|
||||
int cell_width = m_cell_size.GetWidth();
|
||||
int cell_height = m_cell_size.GetHeight();
|
||||
int ncol = (size.GetWidth() - cell_width + m_image_size.GetWidth()) / cell_width;
|
||||
|
@ -199,7 +202,6 @@ void ImageGrid::UpdateLayout()
|
|||
if (m_row_offset >= m_row_count)
|
||||
m_row_offset = m_row_count == 0 ? 0 : m_row_count - 1;
|
||||
// create mask
|
||||
wxSize mask_size{0, 60 * em_unit(this) / 10};
|
||||
if (m_file_sys->GetGroupMode() == PrinterFileSystem::G_NONE) {
|
||||
mask_size.x = (m_col_count - 1) * m_cell_size.GetWidth() + m_image_size.GetWidth();
|
||||
}
|
||||
|
@ -370,6 +372,8 @@ size_t Slic3r::GUI::ImageGrid::firstItem(wxSize const &size, wxPoint &off)
|
|||
int index = (m_row_offset + 1 < m_row_count || m_row_count == 0) ?
|
||||
m_row_offset / 4 * m_col_count :
|
||||
((m_file_sys->GetCount() + m_col_count - 1) / m_col_count - (size.y + m_image_size.GetHeight() - 1) / m_cell_size.GetHeight()) * m_col_count;
|
||||
if (m_file_sys->GetGroupMode() == PrinterFileSystem::G_NONE)
|
||||
offy += m_mask.GetHeight();
|
||||
off = wxPoint{offx, offy};
|
||||
return index;
|
||||
}
|
||||
|
@ -523,12 +527,15 @@ void ImageGrid::render(wxDC& dc)
|
|||
}
|
||||
// Draw floating date range for non-group list
|
||||
if (m_file_sys->GetGroupMode() == PrinterFileSystem::G_NONE && m_file_sys->GetCount() > 0) {
|
||||
dc.DrawBitmap(m_mask, {off.x, 0});
|
||||
//dc.DrawBitmap(m_mask, {off.x, 0});
|
||||
dc.DrawRectangle({off.x, 0}, m_mask.GetSize());
|
||||
auto & file1 = m_file_sys->GetFile(start);
|
||||
auto & file2 = m_file_sys->GetFile(end - 1);
|
||||
auto date1 = wxDateTime((time_t) file1.time).Format(_L(formats[m_file_sys->GetGroupMode()]));
|
||||
auto date2 = wxDateTime((time_t) file2.time).Format(_L(formats[m_file_sys->GetGroupMode()]));
|
||||
dc.DrawText(date1 + " - " + date2, wxPoint{off.x + 24, 16});
|
||||
dc.SetFont(Label::Head_16);
|
||||
dc.SetTextForeground(wxColor("#262E30"));
|
||||
dc.DrawText(date1 + " - " + date2, wxPoint{off.x, 2});
|
||||
}
|
||||
// Draw bottom background
|
||||
if (off.y < size.y)
|
||||
|
|
|
@ -412,7 +412,7 @@ void ArrangeJob::prepare()
|
|||
|
||||
//add the virtual object into unselect list if has
|
||||
m_plater->get_partplate_list().preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES);
|
||||
|
||||
|
||||
#if SAVE_ARRANGE_POLY
|
||||
if (1)
|
||||
{ // subtract excluded region and get a polygon bed
|
||||
|
@ -625,8 +625,11 @@ void ArrangeJob::finalize() {
|
|||
//BBS: partplate
|
||||
PartPlateList& plate_list = m_plater->get_partplate_list();
|
||||
//clear all the relations before apply the arrangement results
|
||||
plate_list.clear();
|
||||
|
||||
if (only_on_partplate) {
|
||||
plate_list.clear(false, false, true, current_plate_index);
|
||||
}
|
||||
else
|
||||
plate_list.clear(false, false, true, -1);
|
||||
//BBS: adjust the bed_index, create new plates, get the max bed_index
|
||||
for (ArrangePolygon& ap : m_selected) {
|
||||
//if (ap.bed_idx < 0) continue; // bed_idx<0 means unarrangable
|
||||
|
@ -709,7 +712,12 @@ void ArrangeJob::finalize() {
|
|||
m_plater->get_notification_manager()->close_notification_of_type(NotificationType::ArrangeOngoing);
|
||||
|
||||
//BBS: reload all objects due to arrange
|
||||
plate_list.rebuild_plates_after_arrangement(!only_on_partplate);
|
||||
if (only_on_partplate) {
|
||||
plate_list.rebuild_plates_after_arrangement(!only_on_partplate, true, current_plate_index);
|
||||
}
|
||||
else {
|
||||
plate_list.rebuild_plates_after_arrangement(!only_on_partplate, true);
|
||||
}
|
||||
|
||||
// BBS: update slice context and gcode result.
|
||||
m_plater->update_slicing_context_to_current_partplate();
|
||||
|
|
|
@ -140,7 +140,7 @@ static wxIcon main_frame_icon(GUI_App::EAppMode app_mode)
|
|||
}
|
||||
|
||||
// BBS
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
#define BORDERLESS_FRAME_STYLE (wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX)
|
||||
#else
|
||||
#define BORDERLESS_FRAME_STYLE (wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX)
|
||||
|
@ -180,7 +180,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
|
|||
// Fonts were created by the DPIFrame constructor for the monitor, on which the window opened.
|
||||
wxGetApp().update_fonts(this);
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
m_topbar = new BBLTopbar(this);
|
||||
#else
|
||||
auto panel_topbar = new wxPanel(this, wxID_ANY);
|
||||
|
@ -286,7 +286,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
|
|||
//Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->cut_selection_to_clipboard(); }, wxID_HIGHEST + wxID_CUT);
|
||||
Bind(wxEVT_SIZE, [this](wxSizeEvent&) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "mainframe: size changed, is maximized = " << this->IsMaximized();
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
if (this->IsMaximized()) {
|
||||
m_topbar->SetWindowSize();
|
||||
} else {
|
||||
|
@ -328,7 +328,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
|
|||
// initialize layout
|
||||
m_main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
sizer->Add(m_topbar, 0, wxEXPAND);
|
||||
#else
|
||||
sizer->Add(panel_topbar, 0, wxEXPAND);
|
||||
|
@ -860,7 +860,7 @@ void MainFrame::init_tabpanel()
|
|||
//monitor
|
||||
}
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
if (sel == tp3DEditor) {
|
||||
m_topbar->EnableUndoRedoItems();
|
||||
}
|
||||
|
@ -1552,7 +1552,7 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect)
|
|||
dynamic_cast<Notebook*>(m_tabpanel)->Rescale();
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
// BBS
|
||||
m_topbar->Rescale();
|
||||
#endif
|
||||
|
@ -1675,7 +1675,7 @@ static wxMenu* generate_help_menu()
|
|||
return true;
|
||||
});
|
||||
// About
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
wxString about_title = wxString::Format(_L("&About %s"), SLIC3R_APP_FULL_NAME);
|
||||
append_menu_item(helpMenu, wxID_ANY, about_title, about_title,
|
||||
[](wxCommandEvent&) { Slic3r::GUI::about(); });
|
||||
|
@ -1736,7 +1736,7 @@ void MainFrame::init_menubar_as_editor()
|
|||
[this](){return can_start_new_project(); }, this);
|
||||
// Open Project
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Open Project") + dots + "\tCtrl+O", _L("Open a project file"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->load_project(); }, "menu_open", nullptr,
|
||||
[this](){return can_open_project(); }, this);
|
||||
|
@ -1767,7 +1767,7 @@ void MainFrame::init_menubar_as_editor()
|
|||
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_open_project() && (m_recent_projects.GetCount() > 0)); }, recent_projects_submenu->GetId());
|
||||
|
||||
// BBS: close save project
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Save Project") + "\tCtrl+S", _L("Save current project to file"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->save_project(); }, "menu_save", nullptr,
|
||||
[this](){return m_plater != nullptr && can_save(); }, this);
|
||||
|
@ -1778,7 +1778,7 @@ void MainFrame::init_menubar_as_editor()
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
append_menu_item(fileMenu, wxID_ANY, _L("Save Project as") + dots + "\tCtrl+Shift+S", _L("Save current project as"),
|
||||
[this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, "menu_save", nullptr,
|
||||
[this](){return m_plater != nullptr && can_save_as(); }, this);
|
||||
|
@ -1793,7 +1793,7 @@ void MainFrame::init_menubar_as_editor()
|
|||
|
||||
// BBS
|
||||
wxMenu *import_menu = new wxMenu();
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
append_menu_item(import_menu, wxID_ANY, _L("Import 3MF/STL/STEP/OBJ/AMF") + dots + "\tCtrl+I", _L("Load a model"),
|
||||
[this](wxCommandEvent&) { if (m_plater) {
|
||||
m_plater->add_model();
|
||||
|
@ -1836,7 +1836,7 @@ void MainFrame::init_menubar_as_editor()
|
|||
|
||||
fileMenu->AppendSeparator();
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
append_menu_item(fileMenu, wxID_EXIT, _L("Quit"), wxString::Format(_L("Quit")),
|
||||
[this](wxCommandEvent&) { Close(false); }, "menu_exit", nullptr);
|
||||
#else
|
||||
|
@ -1857,7 +1857,7 @@ void MainFrame::init_menubar_as_editor()
|
|||
wxString hotkey_delete = "Del";
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
// BBS undo
|
||||
append_menu_item(editMenu, wxID_ANY, _L("Undo") + "\tCtrl+Z",
|
||||
_L("Undo"), [this](wxCommandEvent&) { m_plater->undo(); },
|
||||
|
@ -2131,7 +2131,7 @@ void MainFrame::init_menubar_as_editor()
|
|||
auto helpMenu = generate_help_menu();
|
||||
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#ifndef __APPLE__
|
||||
m_topbar->SetFileMenu(fileMenu);
|
||||
if (editMenu)
|
||||
m_topbar->AddDropDownSubMenu(editMenu, _L("Edit"));
|
||||
|
|
|
@ -31,6 +31,9 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent)
|
|||
m_button_year = new ::Button(m_time_panel, _L("Year"), "", wxBORDER_NONE);
|
||||
m_button_month = new ::Button(m_time_panel, _L("Month"), "", wxBORDER_NONE);
|
||||
m_button_all = new ::Button(m_time_panel, _L("All Files"), "", wxBORDER_NONE);
|
||||
m_button_year->SetToolTip(L("Group files by year, recent first."));
|
||||
m_button_month->SetToolTip(L("Group files by month, recent first."));
|
||||
m_button_all->SetToolTip(L("Show all files, recent first."));
|
||||
m_button_all->SetFont(Label::Head_14); // sync with m_last_mode
|
||||
for (auto b : {m_button_year, m_button_month, m_button_all}) {
|
||||
b->SetBackgroundColor(StateColor());
|
||||
|
@ -49,14 +52,22 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent)
|
|||
top_sizer->Add(m_time_panel, 1, wxEXPAND);
|
||||
|
||||
// File type
|
||||
StateColor background(
|
||||
std::make_pair(0xEEEEEE, (int) StateColor::Checked),
|
||||
std::make_pair(*wxLIGHT_GREY, (int) StateColor::Hovered),
|
||||
std::make_pair(*wxWHITE, (int) StateColor::Normal));
|
||||
m_type_panel = new ::StaticBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
|
||||
m_type_panel->SetBackgroundColor(*wxWHITE);
|
||||
m_type_panel->SetCornerRadius(FromDIP(5));
|
||||
m_type_panel->SetMinSize({-1, 48 * em_unit(this) / 10});
|
||||
m_button_timelapse = new ::Button(m_type_panel, _L("Timelapse"), "", wxBORDER_NONE);
|
||||
m_button_timelapse->SetCanFocus(false);
|
||||
m_button_timelapse->SetToolTip(L("Switch to timelapse files."));
|
||||
m_button_video = new ::Button(m_type_panel, _L("Video"), "", wxBORDER_NONE);
|
||||
m_button_video->SetCanFocus(false);
|
||||
m_button_video->SetToolTip(L("Switch to video files."));
|
||||
for (auto b : {m_button_timelapse, m_button_video} ) {
|
||||
b->SetBackgroundColor(background);
|
||||
b->SetCanFocus(false);
|
||||
}
|
||||
|
||||
wxBoxSizer *type_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
type_sizer->Add(m_button_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 24);
|
||||
|
@ -68,13 +79,22 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent)
|
|||
m_manage_panel = new ::StaticBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
|
||||
m_manage_panel->SetBackgroundColor(StateColor());
|
||||
m_button_delete = new ::Button(m_manage_panel, _L("Delete"));
|
||||
m_button_delete->SetBackgroundColor(StateColor());
|
||||
m_button_delete->SetCanFocus(false);
|
||||
m_button_delete->SetToolTip(L("Delete selected files from printer."));
|
||||
m_button_download = new ::Button(m_manage_panel, _L("Download"));
|
||||
m_button_download->SetBackgroundColor(StateColor());
|
||||
m_button_download->SetCanFocus(false);
|
||||
m_button_download->SetToolTip(L("Download selected files from printer."));
|
||||
m_button_management = new ::Button(m_manage_panel, _L("Management"));
|
||||
m_button_management->SetBackgroundColor(StateColor());
|
||||
m_button_management->SetToolTip(L("Batch manage files."));
|
||||
for (auto b : {m_button_delete, m_button_download, m_button_management}) {
|
||||
b->SetBackgroundColor(StateColor());
|
||||
b->SetFont(Label::Body_12);
|
||||
b->SetCornerRadius(12);
|
||||
b->SetPaddingSize({10, 6});
|
||||
b->SetCanFocus(false);
|
||||
}
|
||||
m_button_delete->SetBorderColor(wxColor("#FF6F00"));
|
||||
m_button_delete->SetTextColor(wxColor("#FF6F00"));
|
||||
m_button_management->SetBorderWidth(0);
|
||||
m_button_management->SetBackgroundColor(wxColor("#00AE42"));
|
||||
|
||||
wxBoxSizer *manage_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
manage_sizer->AddStretchSpacer(1);
|
||||
|
@ -174,6 +194,17 @@ MediaFilePanel::~MediaFilePanel()
|
|||
void MediaFilePanel::SetMachineObject(MachineObject* obj)
|
||||
{
|
||||
std::string machine = obj ? obj->dev_id : "";
|
||||
if (obj && obj->is_function_supported(PrinterFunction::FUNC_MEDIA_FILE)) {
|
||||
m_lan_mode = obj->is_lan_mode_printer();
|
||||
m_lan_ip = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->dev_ip : "";
|
||||
m_lan_passwd = obj->access_code;
|
||||
m_tutk_support = obj->is_function_supported(PrinterFunction::FUNC_REMOTE_TUNNEL);
|
||||
} else {
|
||||
m_lan_mode = false;
|
||||
m_lan_ip.clear();
|
||||
m_lan_passwd.clear();
|
||||
m_tutk_support = true;
|
||||
}
|
||||
if (machine == m_machine)
|
||||
return;
|
||||
m_machine = machine;
|
||||
|
@ -185,8 +216,11 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
|
|||
}
|
||||
if (m_machine.empty()) {
|
||||
m_image_grid->SetStatus(m_bmp_failed.bmp(), _L("No printers."));
|
||||
} else if (m_lan_ip.empty() && (m_lan_mode && !m_tutk_support)) {
|
||||
m_image_grid->SetStatus(m_bmp_failed.bmp(), _L("Not supported."));
|
||||
} else {
|
||||
boost::shared_ptr<PrinterFileSystem> fs(new PrinterFileSystem);
|
||||
fs->Attached();
|
||||
m_image_grid->SetFileType(m_last_type);
|
||||
m_image_grid->SetFileSystem(fs);
|
||||
fs->Bind(EVT_MODE_CHANGED, &MediaFilePanel::modeChanged, this);
|
||||
|
@ -259,7 +293,17 @@ void MediaFilePanel::modeChanged(wxCommandEvent& e1)
|
|||
|
||||
void MediaFilePanel::fetchUrl(boost::weak_ptr<PrinterFileSystem> wfs)
|
||||
{
|
||||
NetworkAgent* agent = wxGetApp().getAgent();
|
||||
if (!m_lan_ip.empty()) {
|
||||
std::string url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd;
|
||||
boost::shared_ptr fs(wfs.lock());
|
||||
if (!fs || fs != m_image_grid->GetFileSystem()) return;
|
||||
fs->SetUrl(url);
|
||||
return;
|
||||
}
|
||||
if (m_lan_mode && !m_tutk_support) { // not support tutk
|
||||
return;
|
||||
}
|
||||
NetworkAgent *agent = wxGetApp().getAgent();
|
||||
if (agent) {
|
||||
agent->get_camera_url(m_machine,
|
||||
[this, wfs](std::string url) {
|
||||
|
|
|
@ -65,7 +65,13 @@ private:
|
|||
::Button *m_button_management = nullptr;
|
||||
|
||||
std::string m_machine;
|
||||
ImageGrid * m_image_grid = nullptr;
|
||||
std::string m_lan_ip;
|
||||
std::string m_lan_user;
|
||||
std::string m_lan_passwd;
|
||||
bool m_lan_mode = false;
|
||||
bool m_tutk_support = false;
|
||||
|
||||
ImageGrid * m_image_grid = nullptr;
|
||||
|
||||
int m_last_mode = 0;
|
||||
int m_last_type = 0;
|
||||
|
|
|
@ -19,11 +19,15 @@ MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl2 *media_ctrl, const w
|
|||
m_button_play = new Button(this, "", "media_play", wxBORDER_NONE);
|
||||
m_button_play->SetCanFocus(false);
|
||||
|
||||
m_label_status = new Label(this);
|
||||
m_label_status = new Label(this, "", LB_HYPERLINK);
|
||||
|
||||
m_button_play->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto & e) { TogglePlay(); });
|
||||
|
||||
m_button_play->Bind(wxEVT_RIGHT_UP, [this](auto & e) { m_media_ctrl->Play(); });
|
||||
m_label_status->Bind(wxEVT_LEFT_UP, [this](auto &e) {
|
||||
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/faq/live-view", L"en");
|
||||
wxLaunchDefaultBrowser(url);
|
||||
});
|
||||
|
||||
Bind(wxEVT_RIGHT_UP, [this](auto & e) { wxClipboard & c = *wxTheClipboard; if (c.Open()) { c.SetData(new wxTextDataObject(m_url)); c.Close(); } });
|
||||
|
||||
|
@ -48,6 +52,9 @@ MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl2 *media_ctrl, const w
|
|||
};
|
||||
parent->Bind(wxEVT_SHOW, onShowHide);
|
||||
parent->GetParent()->GetParent()->Bind(wxEVT_SHOW, onShowHide);
|
||||
|
||||
m_lan_user = "bblp";
|
||||
m_lan_passwd = "bblp";
|
||||
}
|
||||
|
||||
MediaPlayCtrl::~MediaPlayCtrl()
|
||||
|
@ -63,6 +70,17 @@ MediaPlayCtrl::~MediaPlayCtrl()
|
|||
void MediaPlayCtrl::SetMachineObject(MachineObject* obj)
|
||||
{
|
||||
std::string machine = obj ? obj->dev_id : "";
|
||||
if (obj && obj->is_function_supported(PrinterFunction::FUNC_CAMERA_VIDEO)) {
|
||||
m_lan_mode = obj->is_lan_mode_printer();
|
||||
m_lan_ip = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->dev_ip : "";
|
||||
m_lan_passwd = obj->access_code;
|
||||
m_tutk_support = obj->is_function_supported(PrinterFunction::FUNC_REMOTE_TUNNEL);
|
||||
} else {
|
||||
m_lan_mode = false;
|
||||
m_lan_ip.clear();
|
||||
m_lan_passwd.clear();
|
||||
m_tutk_support = true;
|
||||
}
|
||||
if (machine == m_machine) {
|
||||
if (m_last_state == MEDIASTATE_IDLE && m_next_retry.IsValid() && wxDateTime::Now() >= m_next_retry)
|
||||
Play();
|
||||
|
@ -92,10 +110,36 @@ void MediaPlayCtrl::Play()
|
|||
if (m_last_state != MEDIASTATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_last_state = MEDIASTATE_INITIALIZING;
|
||||
m_button_play->SetIcon("media_stop");
|
||||
SetStatus(_L("Initializing..."));
|
||||
|
||||
if (!m_lan_ip.empty()) {
|
||||
m_url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd;
|
||||
m_last_state = MEDIASTATE_LOADING;
|
||||
SetStatus(_L("Loading..."));
|
||||
if (wxGetApp().app_config->get("dump_video") == "true") {
|
||||
std::string file_h264 = data_dir() + "/video.h264";
|
||||
std::string file_info = data_dir() + "/video.info";
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl dump video to " << file_h264;
|
||||
// closed by BambuSource
|
||||
FILE *dump_h264_file = boost::nowide::fopen(file_h264.c_str(), "wb");
|
||||
FILE *dump_info_file = boost::nowide::fopen(file_info.c_str(), "wb");
|
||||
m_url = m_url + "&dump_h264=" + boost::lexical_cast<std::string>(dump_h264_file);
|
||||
m_url = m_url + "&dump_info=" + boost::lexical_cast<std::string>(dump_info_file);
|
||||
}
|
||||
boost::unique_lock lock(m_mutex);
|
||||
m_tasks.push_back(m_url);
|
||||
m_cond.notify_all();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_lan_mode && !m_tutk_support) { // not support tutk
|
||||
Stop();
|
||||
SetStatus(_L("Initialize failed (Not supported)!"));
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkAgent* agent = wxGetApp().getAgent();
|
||||
if (agent) {
|
||||
|
@ -166,7 +210,11 @@ void MediaPlayCtrl::SetStatus(wxString const& msg2)
|
|||
OutputDebugStringA("\n");
|
||||
#endif // __WXMSW__
|
||||
m_label_status->SetLabel(msg);
|
||||
//m_label_status->SetForegroundColour(!msg.EndsWith("!") ? 0x42AE00 : 0x3B65E9);
|
||||
long style = m_label_status->GetWindowStyle() & ~LB_HYPERLINK;
|
||||
if (m_failed_code && msg != msg2) {
|
||||
style |= LB_HYPERLINK;
|
||||
}
|
||||
m_label_status->SetWindowStyle(style);
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
@ -240,6 +288,8 @@ void MediaPlayCtrl::onStateChanged(wxMediaEvent& event)
|
|||
}
|
||||
else if (event.GetId()) {
|
||||
Stop();
|
||||
if (m_failed_code == 0)
|
||||
m_failed_code = 2;
|
||||
SetStatus(_L("Load failed [%d]!"));
|
||||
} else {
|
||||
m_last_state = last_state;
|
||||
|
|
|
@ -58,6 +58,11 @@ private:
|
|||
wxMediaCtrl2 * m_media_ctrl;
|
||||
wxMediaState m_last_state = MEDIASTATE_IDLE;
|
||||
std::string m_machine;
|
||||
std::string m_lan_ip;
|
||||
std::string m_lan_user;
|
||||
std::string m_lan_passwd;
|
||||
bool m_lan_mode = false;
|
||||
bool m_tutk_support = false;
|
||||
wxString m_url;
|
||||
|
||||
std::deque<wxString> m_tasks;
|
||||
|
|
|
@ -227,11 +227,6 @@ void MonitorPanel::set_default()
|
|||
/* reset side tool*/
|
||||
//m_bitmap_wifi_signal->SetBitmap(wxNullBitmap);
|
||||
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
/* reset time lapse panel */
|
||||
m_media_file_panel->SetMachineObject(nullptr);
|
||||
#endif
|
||||
|
||||
wxGetApp().sidebar().load_ams_list({});
|
||||
}
|
||||
|
||||
|
@ -324,6 +319,13 @@ void MonitorPanel::on_printer_clicked(wxMouseEvent &event)
|
|||
wxPoint pos = m_side_tools->ClientToScreen(wxPoint(0, 0));
|
||||
pos.y += m_side_tools->GetRect().height;
|
||||
m_select_machine.Position(pos, wxSize(0, 0));
|
||||
|
||||
#ifdef __linux__
|
||||
m_select_machine.SetSize(wxSize(m_side_tools->GetSize().x, -1));
|
||||
m_select_machine.SetMaxSize(wxSize(m_side_tools->GetSize().x, -1));
|
||||
m_select_machine.SetMinSize(wxSize(m_side_tools->GetSize().x, -1));
|
||||
#endif
|
||||
|
||||
m_select_machine.Popup();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ static constexpr int FADING_OUT_TIMEOUT = 100;
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
//wxDEFINE_EVENT(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, EjectDriveNotificationClickedEvent);
|
||||
wxDEFINE_EVENT(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, EjectDriveNotificationClickedEvent);
|
||||
wxDEFINE_EVENT(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, ExportGcodeNotificationClickedEvent);
|
||||
wxDEFINE_EVENT(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, PresetUpdateAvailableClickedEvent);
|
||||
|
||||
|
@ -801,11 +801,11 @@ void NotificationManager::ExportFinishedNotification::render_text(ImGuiWrapper&
|
|||
void NotificationManager::ExportFinishedNotification::render_close_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
PopNotification::render_close_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
//if(m_to_removable && ! m_eject_pending)
|
||||
// render_eject_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
if (m_to_removable && !m_eject_pending)
|
||||
render_eject_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||
}
|
||||
|
||||
/*void NotificationManager::ExportFinishedNotification::render_eject_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
void NotificationManager::ExportFinishedNotification::render_eject_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
ImVec2 win_size(win_size_x, win_size_y);
|
||||
ImVec2 win_pos(win_pos_x, win_pos_y);
|
||||
|
@ -818,23 +818,25 @@ void NotificationManager::ExportFinishedNotification::render_close_button(ImGuiW
|
|||
std::string button_text;
|
||||
button_text = ImGui::EjectButton;
|
||||
|
||||
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - m_line_height * 5.f, win_pos.y),
|
||||
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - m_line_height * 5.f, win_pos.y),
|
||||
ImVec2(win_pos.x - m_line_height * 2.5f, win_pos.y + win_size.y),
|
||||
true))
|
||||
{
|
||||
button_text = ImGui::EjectHoverButton;
|
||||
// tooltip
|
||||
//tooltip
|
||||
|
||||
long time_now = wxGetLocalTime();
|
||||
if (m_hover_time > 0 && m_hover_time < time_now) {
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
|
||||
ImGui::BeginTooltip();
|
||||
imgui.text(_u8L("Eject drive") + " " + GUI::shortkey_ctrl_prefix() + "T");
|
||||
ImGui::EndTooltip();
|
||||
//ImGui::BeginTooltip();
|
||||
//imgui.text(_u8L("Eject drive") + " " + GUI::shortkey_ctrl_prefix() + "T");
|
||||
//ImGui::EndTooltip();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (m_hover_time == 0)
|
||||
m_hover_time = time_now;
|
||||
} else
|
||||
}
|
||||
else
|
||||
m_hover_time = 0;
|
||||
|
||||
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
|
||||
|
@ -850,7 +852,7 @@ void NotificationManager::ExportFinishedNotification::render_close_button(ImGuiW
|
|||
}
|
||||
|
||||
//invisible large button
|
||||
ImGui::SetCursorPosX(win_size.x - m_line_height * 4.625f);
|
||||
ImGui::SetCursorPosX(win_size.x - m_line_height * 4.625f);
|
||||
ImGui::SetCursorPosY(0);
|
||||
if (imgui.button(" ", m_line_height * 2.f, win_size.y))
|
||||
{
|
||||
|
@ -860,7 +862,8 @@ void NotificationManager::ExportFinishedNotification::render_close_button(ImGuiW
|
|||
on_eject_click();
|
||||
}
|
||||
ImGui::PopStyleColor(5);
|
||||
}*/
|
||||
}
|
||||
|
||||
bool NotificationManager::ExportFinishedNotification::on_text_click()
|
||||
{
|
||||
open_folder(m_export_dir_path);
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
//using EjectDriveNotificationClickedEvent = SimpleEvent;
|
||||
//wxDECLARE_EVENT(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, EjectDriveNotificationClickedEvent);
|
||||
using EjectDriveNotificationClickedEvent = SimpleEvent;
|
||||
wxDECLARE_EVENT(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, EjectDriveNotificationClickedEvent);
|
||||
using ExportGcodeNotificationClickedEvent = SimpleEvent;
|
||||
wxDECLARE_EVENT(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, ExportGcodeNotificationClickedEvent);
|
||||
using PresetUpdateAvailableClickedEvent = SimpleEvent;
|
||||
|
@ -737,9 +737,9 @@ private:
|
|||
void render_close_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
/*void render_eject_button(ImGuiWrapper& imgui,
|
||||
void render_eject_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y);*/
|
||||
const float win_pos_x, const float win_pos_y);
|
||||
void render_minimize_button(ImGuiWrapper& imgui, const float win_pos_x, const float win_pos_y) override
|
||||
{ m_minimize_b_visible = false; }
|
||||
bool on_text_click() override;
|
||||
|
|
|
@ -53,8 +53,9 @@ OG_CustomCtrl::OG_CustomCtrl( wxWindow* parent,
|
|||
m_font = Label::Body_14;
|
||||
SetFont(m_font);
|
||||
m_em_unit = em_unit(m_parent);
|
||||
m_v_gap = lround(1.0 * m_em_unit);
|
||||
m_h_gap = lround(0.2 * m_em_unit);
|
||||
m_v_gap = lround(1.2 * m_em_unit);
|
||||
m_v_gap2 = lround(0.8 * m_em_unit);
|
||||
m_h_gap = lround(0.2 * m_em_unit);
|
||||
|
||||
//m_bmp_mode_sz = get_bitmap_size(create_scaled_bitmap("mode_simple", this, wxOSX ? 10 : 12));
|
||||
m_bmp_blinking_sz = get_bitmap_size(create_scaled_bitmap("blank_16", this));
|
||||
|
@ -101,7 +102,7 @@ void OG_CustomCtrl::init_ctrl_lines()
|
|||
wxSize label_sz = GetTextExtent(line.label);
|
||||
if (opt_group->split_multi_line) {
|
||||
if (option_set.size() > 1) // BBS
|
||||
height = (label_sz.y + m_v_gap) * option_set.size();
|
||||
height = (label_sz.y + m_v_gap2) * option_set.size() + m_v_gap - m_v_gap2;
|
||||
else
|
||||
height = label_sz.y * (label_sz.GetWidth() > int(opt_group->label_width * m_em_unit) ? 2 : 1) + m_v_gap;
|
||||
} else {
|
||||
|
@ -243,7 +244,7 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
|
|||
break;
|
||||
}
|
||||
if (opt_group->split_multi_line) {// BBS
|
||||
v_pos += ctrl_line.height / option_set.size();
|
||||
v_pos += (ctrl_line.height - m_v_gap + m_v_gap2) / option_set.size();
|
||||
} else {
|
||||
// BBS: new layout
|
||||
h_pos += field->getWindow()->GetSize().x;
|
||||
|
@ -507,7 +508,7 @@ void OG_CustomCtrl::correct_window_position(wxWindow* win, const Line& line, Fie
|
|||
int line_height = get_height(line);
|
||||
if (opt_group->split_multi_line) { // BBS
|
||||
if (line.get_options().size() > 1)
|
||||
line_height /= line.get_options().size();
|
||||
line_height = (line_height - m_v_gap + m_v_gap2) / line.get_options().size();
|
||||
}
|
||||
pos.y += std::max(0, int(0.5 * (line_height - win->GetSize().y)));
|
||||
win->SetPosition(pos);
|
||||
|
@ -544,7 +545,7 @@ int OG_CustomCtrl::get_title_width()
|
|||
if (!GetLabel().IsEmpty())
|
||||
return titleWidth;
|
||||
else
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
void OG_CustomCtrl::set_max_win_width(int max_win_width)
|
||||
|
@ -568,7 +569,8 @@ void OG_CustomCtrl::msw_rescale()
|
|||
m_font = Label::Body_14;
|
||||
SetFont(m_font);
|
||||
m_em_unit = em_unit(m_parent);
|
||||
m_v_gap = lround(1.5 * m_em_unit);
|
||||
m_v_gap = lround(1.2 * m_em_unit);
|
||||
m_v_gap2 = lround(0.8 * m_em_unit);
|
||||
m_h_gap = lround(0.2 * m_em_unit);
|
||||
|
||||
//m_bmp_mode_sz = create_scaled_bitmap("mode_simple", this, wxOSX ? 10 : 12).GetSize();
|
||||
|
@ -672,7 +674,7 @@ void OG_CustomCtrl::CtrlLine::msw_rescale()
|
|||
if (ctrl->opt_group->split_multi_line) { // BBS
|
||||
const std::vector<Option> &option_set = og_line.get_options();
|
||||
if (option_set.size() > 1)
|
||||
height = (label_sz.y + ctrl->m_v_gap) * option_set.size();
|
||||
height = (label_sz.y + ctrl->m_v_gap2) * option_set.size() + ctrl->m_v_gap - ctrl->m_v_gap2;
|
||||
else
|
||||
height = label_sz.y * (label_sz.GetWidth() > int(ctrl->opt_group->label_width * ctrl->m_em_unit) ? 2 : 1) + ctrl->m_v_gap;
|
||||
} else {
|
||||
|
@ -878,7 +880,7 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord h_pos, wxCoord v_pos)
|
|||
h_pos += lround(0.6 * ctrl->m_em_unit);
|
||||
|
||||
if (ctrl->opt_group->split_multi_line) { // BBS
|
||||
v_pos += height / option_set.size();
|
||||
v_pos += (height - ctrl->m_v_gap + ctrl->m_v_gap2) / option_set.size();
|
||||
h_pos = h_pos2;
|
||||
}
|
||||
}
|
||||
|
@ -894,7 +896,7 @@ wxCoord OG_CustomCtrl::CtrlLine::draw_text(wxDC &dc, wxPoint pos, const wxString
|
|||
|
||||
if (ctrl->opt_group->split_multi_line && !is_main) { // BBS
|
||||
const std::vector<Option> &option_set = og_line.get_options();
|
||||
pos.y = pos.y + lround((height / option_set.size() - size.y) / 2);
|
||||
pos.y = pos.y + lround(((height - ctrl->m_v_gap + ctrl->m_v_gap2) / option_set.size() - size.y) / 2);
|
||||
} else {
|
||||
pos.y = pos.y + lround((height - size.y) / 2);
|
||||
}
|
||||
|
@ -952,7 +954,7 @@ wxCoord OG_CustomCtrl::CtrlLine::draw_act_bmps(wxDC& dc, wxPoint pos, const wxBi
|
|||
if (ctrl->opt_group->split_multi_line) { // BBS
|
||||
const std::vector<Option> &option_set = og_line.get_options();
|
||||
if (option_set.size() > 1)
|
||||
pos.y += lround((height / option_set.size() - get_bitmap_size(bmp_undo).GetHeight()) / 2);
|
||||
pos.y += lround(((height - ctrl->m_v_gap + ctrl->m_v_gap2) / option_set.size() - get_bitmap_size(bmp_undo).GetHeight()) / 2);
|
||||
else
|
||||
pos.y += lround((height - get_bitmap_size(bmp_undo).GetHeight()) / 2);
|
||||
} else {
|
||||
|
|
|
@ -27,6 +27,7 @@ class OG_CustomCtrl :public wxPanel
|
|||
{
|
||||
wxFont m_font;
|
||||
int m_v_gap;
|
||||
int m_v_gap2;
|
||||
int m_h_gap;
|
||||
int m_em_unit;
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@ std::string OpenGLManager::GLInfo::to_string(bool for_github) const
|
|||
|
||||
OpenGLManager::GLInfo OpenGLManager::s_gl_info;
|
||||
bool OpenGLManager::s_compressed_textures_supported = false;
|
||||
bool OpenGLManager::m_use_manually_generated_mipmaps = true;
|
||||
OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::EMultisampleState::Unknown;
|
||||
OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown;
|
||||
|
||||
|
@ -276,6 +277,34 @@ bool OpenGLManager::init_gl()
|
|||
wxMessageBox(message, _L("Error loading shaders"), wxOK | wxICON_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Since AMD driver version 22.7.1, there is probably some bug in the driver that causes the issue with the missing
|
||||
// texture of the bed. It seems that this issue only triggers when mipmaps are generated manually
|
||||
// (combined with a texture compression) and when mipmaps are generated through OpenGL glGenerateMipmap is working.
|
||||
// So, for newer drivers than 22.6.1, the last working driver version, we use mipmaps generated through OpenGL.
|
||||
if (const auto gl_info = OpenGLManager::get_gl_info(); boost::contains(gl_info.get_vendor(), "ATI Technologies Inc.")) {
|
||||
// WHQL drivers seem to have one more version number at the end besides non-WHQL drivers.
|
||||
// WHQL: 4.6.14800 Compatibility Profile Context 22.6.1 30.0.21023.1015
|
||||
// Non-WHQL: 4.6.0 Compatibility Profile Context 22.8.1.220810
|
||||
std::regex version_rgx(R"(Compatibility\sProfile\sContext\s(\d+)\.(\d+)\.(\d+))");
|
||||
if (std::smatch matches; std::regex_search(gl_info.get_version(), matches, version_rgx) && matches.size() == 4) {
|
||||
int version_major = std::stoi(matches[1].str());
|
||||
int version_minor = std::stoi(matches[2].str());
|
||||
int version_patch = std::stoi(matches[3].str());
|
||||
BOOST_LOG_TRIVIAL(debug) << "Found AMD driver version: " << version_major << "." << version_minor << "." << version_patch;
|
||||
|
||||
if (version_major > 22 || (version_major == 22 && version_minor > 6) || (version_major == 22 && version_minor == 6 && version_patch > 1)) {
|
||||
m_use_manually_generated_mipmaps = false;
|
||||
BOOST_LOG_TRIVIAL(debug) << "Mipmapping through OpenGL was enabled.";
|
||||
}
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(error) << "Not recognized format of version.";
|
||||
}
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(error) << "Unable to parse version of AMD driver.";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -84,6 +84,7 @@ private:
|
|||
static EMultisampleState s_multisample;
|
||||
static EFramebufferType s_framebuffers_type;
|
||||
|
||||
static bool m_use_manually_generated_mipmaps;
|
||||
public:
|
||||
OpenGLManager() = default;
|
||||
~OpenGLManager();
|
||||
|
@ -100,6 +101,7 @@ public:
|
|||
static EFramebufferType get_framebuffers_type() { return s_framebuffers_type; }
|
||||
static wxGLCanvas* create_wxglcanvas(wxWindow& parent);
|
||||
static const GLInfo& get_gl_info() { return s_gl_info; }
|
||||
static bool use_manually_generated_mipmaps() { return m_use_manually_generated_mipmaps; }
|
||||
|
||||
private:
|
||||
static void detect_multisample(int* attribList);
|
||||
|
|
|
@ -113,10 +113,10 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
|
|||
return field;
|
||||
}
|
||||
|
||||
OptionsGroup::OptionsGroup( wxWindow* _parent, const wxString& title,
|
||||
OptionsGroup::OptionsGroup(wxWindow *_parent, const wxString &title, const wxString &icon,
|
||||
bool is_tab_opt /* = false */,
|
||||
column_t extra_clmn /* = nullptr */) :
|
||||
m_parent(_parent), title(title),
|
||||
m_parent(_parent), title(title), icon(icon),
|
||||
m_use_custom_ctrl(is_tab_opt),
|
||||
// BBS: new layout
|
||||
staticbox(!is_tab_opt), extra_column(extra_clmn)
|
||||
|
@ -461,7 +461,7 @@ bool OptionsGroup::activate(std::function<void()> throw_if_canceled/* = [](){}*/
|
|||
}
|
||||
else {
|
||||
// BBS: new layout
|
||||
::StaticLine* stl = new ::StaticLine(m_parent, false, _(title));
|
||||
::StaticLine* stl = new ::StaticLine(m_parent, false, _(title), icon);
|
||||
stl->SetFont(Label::Head_14);
|
||||
stl->SetForegroundColour("#262E30");
|
||||
sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
@ -850,6 +850,9 @@ void ConfigOptionsGroup::msw_rescale()
|
|||
|
||||
if (custom_ctrl)
|
||||
custom_ctrl->msw_rescale();
|
||||
|
||||
if (auto line = dynamic_cast<::StaticLine*>(stb))
|
||||
line->Rescale();
|
||||
}
|
||||
|
||||
void ConfigOptionsGroup::sys_color_changed()
|
||||
|
@ -1115,7 +1118,7 @@ boost::any ConfigOptionsGroup::get_config_value2(const DynamicPrintConfig& confi
|
|||
ret = config.opt_bool(opt_key);
|
||||
break;
|
||||
case coBools:
|
||||
ret = config.opt_bool(opt_key, idx);
|
||||
ret = static_cast<unsigned char>(config.opt_bool(opt_key, idx));
|
||||
break;
|
||||
case coInt:
|
||||
ret = config.opt_int(opt_key);
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
bool option_label_at_right{false};
|
||||
// BBS: new layout
|
||||
wxWindow * stb;
|
||||
const wxString icon;
|
||||
const wxString title;
|
||||
size_t label_width = 20 ;// {200};
|
||||
wxSizer* sizer {nullptr};
|
||||
|
@ -180,7 +181,7 @@ public:
|
|||
|
||||
void hide_labels() { label_width = 0; }
|
||||
|
||||
OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false,
|
||||
OptionsGroup(wxWindow *_parent, const wxString &title, const wxString &icon, bool is_tab_opt = false,
|
||||
column_t extra_clmn = nullptr);
|
||||
~OptionsGroup() { clear(true); }
|
||||
|
||||
|
@ -239,14 +240,17 @@ public:
|
|||
|
||||
class ConfigOptionsGroup: public OptionsGroup {
|
||||
public:
|
||||
ConfigOptionsGroup( wxWindow* parent, const wxString& title, const wxString& icon, DynamicPrintConfig* config = nullptr,
|
||||
bool is_tab_opt = false, column_t extra_clmn = nullptr) :
|
||||
OptionsGroup(parent, title, icon, is_tab_opt, extra_clmn), m_config(config) {}
|
||||
ConfigOptionsGroup( wxWindow* parent, const wxString& title, DynamicPrintConfig* config = nullptr,
|
||||
bool is_tab_opt = false, column_t extra_clmn = nullptr) :
|
||||
OptionsGroup(parent, title, is_tab_opt, extra_clmn), m_config(config) {}
|
||||
ConfigOptionsGroup(parent, title, wxEmptyString, config, is_tab_opt, extra_clmn) {}
|
||||
ConfigOptionsGroup( wxWindow* parent, const wxString& title, ModelConfig* config,
|
||||
bool is_tab_opt = false, column_t extra_clmn = nullptr) :
|
||||
OptionsGroup(parent, title, is_tab_opt, extra_clmn), m_config(&config->get()), m_modelconfig(config) {}
|
||||
OptionsGroup(parent, title, wxEmptyString, is_tab_opt, extra_clmn), m_config(&config->get()), m_modelconfig(config) {}
|
||||
ConfigOptionsGroup( wxWindow* parent) :
|
||||
OptionsGroup(parent, wxEmptyString, true, nullptr) {}
|
||||
OptionsGroup(parent, wxEmptyString, wxEmptyString, true, nullptr) {}
|
||||
|
||||
const wxString& config_category() const throw() { return m_config_category; }
|
||||
int config_type() const throw() { return m_config_type; }
|
||||
|
@ -316,7 +320,7 @@ class ExtruderOptionsGroup : public ConfigOptionsGroup {
|
|||
public:
|
||||
ExtruderOptionsGroup(wxWindow* parent, const wxString& title, DynamicPrintConfig* config = nullptr,
|
||||
bool is_tab_opt = false, column_t extra_clmn = nullptr) :
|
||||
ConfigOptionsGroup(parent, title, config, is_tab_opt, extra_clmn) {}
|
||||
ConfigOptionsGroup(parent, title, wxEmptyString, config, is_tab_opt, extra_clmn) {}
|
||||
|
||||
void on_change_OG(const t_config_option_key& opt_id, const boost::any& value) override;
|
||||
};
|
||||
|
|
|
@ -1162,12 +1162,14 @@ void PartPlate::set_index(int index)
|
|||
m_print->set_plate_index(index);
|
||||
}
|
||||
|
||||
void PartPlate::clear()
|
||||
void PartPlate::clear(bool clear_sliced_result)
|
||||
{
|
||||
obj_to_instance_set.clear();
|
||||
instance_outside_set.clear();
|
||||
m_ready_for_slice = true;
|
||||
update_slice_result_valid_state(false);
|
||||
if (clear_sliced_result) {
|
||||
m_ready_for_slice = true;
|
||||
update_slice_result_valid_state(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1250,7 +1252,7 @@ Vec3d PartPlate::get_center_origin()
|
|||
Vec3d origin;
|
||||
|
||||
origin(0) = (m_bounding_box.min(0) + m_bounding_box.max(0)) / 2;//m_origin.x() + m_width / 2;
|
||||
origin(1) = (m_bounding_box.min(0) + m_bounding_box.max(0)) / 2; //m_origin.y() + m_depth / 2;
|
||||
origin(1) = (m_bounding_box.min(1) + m_bounding_box.max(1)) / 2; //m_origin.y() + m_depth / 2;
|
||||
origin(2) = m_origin.z();
|
||||
|
||||
return origin;
|
||||
|
@ -2415,14 +2417,19 @@ void PartPlateList::reset_size(int width, int depth, int height)
|
|||
}
|
||||
|
||||
//clear all the instances in the plate, but keep the plates
|
||||
void PartPlateList::clear(bool delete_plates, bool release_print_list)
|
||||
void PartPlateList::clear(bool delete_plates, bool release_print_list, bool except_locked, int plate_index)
|
||||
{
|
||||
for (unsigned int i = 0; i < (unsigned int)m_plate_list.size(); ++i)
|
||||
{
|
||||
PartPlate* plate = m_plate_list[i];
|
||||
assert(plate != NULL);
|
||||
|
||||
plate->clear();
|
||||
if (except_locked && plate->is_locked())
|
||||
plate->clear(false);
|
||||
else if ((plate_index != -1) && (plate_index != i))
|
||||
plate->clear(false);
|
||||
else
|
||||
plate->clear();
|
||||
if (delete_plates)
|
||||
delete plate;
|
||||
}
|
||||
|
@ -3202,12 +3209,12 @@ int PartPlateList::add_to_plate(int obj_id, int instance_id, int plate_id)
|
|||
}
|
||||
|
||||
//reload all objects
|
||||
int PartPlateList::reload_all_objects()
|
||||
int PartPlateList::reload_all_objects(bool except_locked, int plate_index)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, j, k;
|
||||
|
||||
clear();
|
||||
clear(false, false, except_locked, plate_index);
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": m_model->objects.size() is %1%") % m_model->objects.size();
|
||||
//try to find a new plate
|
||||
|
@ -3573,10 +3580,15 @@ void PartPlateList::postprocess_arrange_polygon(arrangement::ArrangePolygon& arr
|
|||
{
|
||||
if (arrange_polygon.bed_idx == -1)
|
||||
{
|
||||
//outarea for large object
|
||||
// outarea for large object
|
||||
arrange_polygon.bed_idx = m_plate_list.size();
|
||||
arrange_polygon.translation(X) = scaled<double>(0.5 * plate_stride_x());
|
||||
arrange_polygon.translation(Y) = scaled<double>(0.5 * plate_stride_y());
|
||||
BoundingBox apbox(arrange_polygon.poly);
|
||||
auto apbox_size = apbox.size();
|
||||
|
||||
//arrange_polygon.translation(X) = scaled<double>(0.5 * plate_stride_x());
|
||||
//arrange_polygon.translation(Y) = scaled<double>(0.5 * plate_stride_y());
|
||||
arrange_polygon.translation(X) = 0.5 * apbox_size[0];
|
||||
arrange_polygon.translation(Y) = scaled<double>(static_cast<double>(m_plate_depth)) - 0.5 * apbox_size[1];
|
||||
}
|
||||
|
||||
arrange_polygon.row = arrange_polygon.bed_idx / m_plate_cols;
|
||||
|
@ -3945,7 +3957,7 @@ int PartPlateList::rebuild_plates_after_deserialize(std::vector<bool>& previous_
|
|||
}
|
||||
|
||||
//retruct plates structures after auto-arrangement
|
||||
int PartPlateList::rebuild_plates_after_arrangement(bool recycle_plates)
|
||||
int PartPlateList::rebuild_plates_after_arrangement(bool recycle_plates, bool except_locked, int plate_index)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -3956,7 +3968,7 @@ int PartPlateList::rebuild_plates_after_arrangement(bool recycle_plates)
|
|||
//for (auto object : m_model->objects)
|
||||
// std::sort(object->instances.begin(), object->instances.end(), [](auto a, auto b) {return a->arrange_order < b->arrange_order; });
|
||||
|
||||
ret = reload_all_objects();
|
||||
ret = reload_all_objects(except_locked, plate_index);
|
||||
|
||||
if (recycle_plates)
|
||||
{
|
||||
|
|
|
@ -198,7 +198,7 @@ public:
|
|||
bool operator<(PartPlate&) const;
|
||||
|
||||
//clear alll the instances in plate
|
||||
void clear();
|
||||
void clear(bool clear_sliced_result = true);
|
||||
|
||||
//static const int plate_x_offset = 20; //mm
|
||||
//static const double plate_x_gap = 0.2;
|
||||
|
@ -468,7 +468,7 @@ public:
|
|||
//this may be happened after machine changed
|
||||
void reset_size(int width, int depth, int height);
|
||||
//clear all the instances in the plate, but keep the plates
|
||||
void clear(bool delete_plates = false, bool release_print_list = false);
|
||||
void clear(bool delete_plates = false, bool release_print_list = false, bool except_locked = false, int plate_index = -1);
|
||||
//clear all the instances in the plate, and delete the plates, only keep the first default plate
|
||||
void reset(bool do_init);
|
||||
|
||||
|
@ -563,7 +563,7 @@ public:
|
|||
int add_to_plate(int obj_id, int instance_id, int plate_id);
|
||||
|
||||
//reload all objects
|
||||
int reload_all_objects();
|
||||
int reload_all_objects(bool except_locked = false, int plate_index = -1);
|
||||
|
||||
//reload objects for newly created plate
|
||||
int construct_objects_list_for_new_plate(int plate_index);
|
||||
|
@ -624,7 +624,7 @@ public:
|
|||
int rebuild_plates_after_deserialize(std::vector<bool>& previous_sliced_result, std::vector<std::string>& previous_gcode_paths);
|
||||
|
||||
//retruct plates structures after auto-arrangement
|
||||
int rebuild_plates_after_arrangement(bool recycle_plates = true);
|
||||
int rebuild_plates_after_arrangement(bool recycle_plates = true, bool except_locked = false, int plate_index = -1);
|
||||
|
||||
/* load/store releted functions, with_gcode = true and plate_idx = -1, export all gcode
|
||||
* if with_gcode = true and specify plate_idx, export plate_idx gcode only
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
#include "../Utils/UndoRedo.hpp"
|
||||
#include "../Utils/PresetUpdater.hpp"
|
||||
#include "../Utils/Process.hpp"
|
||||
//#include "RemovableDriveManager.hpp"
|
||||
#include "RemovableDriveManager.hpp"
|
||||
#include "InstanceCheck.hpp"
|
||||
#include "NotificationManager.hpp"
|
||||
#include "PresetComboBoxes.hpp"
|
||||
|
@ -290,6 +290,7 @@ struct Sidebar::priv
|
|||
wxStaticText* m_staticText_filament_settings;
|
||||
ScalableButton * m_bpButton_add_filament;
|
||||
ScalableButton * m_bpButton_del_filament;
|
||||
ScalableButton * m_bpButton_ams_filament;
|
||||
ScalableButton * m_bpButton_set_filament;
|
||||
wxPanel* m_panel_filament_content;
|
||||
wxScrolledWindow* m_scrolledWindow_filament_content;
|
||||
|
@ -552,7 +553,9 @@ Sidebar::Sidebar(Plater *parent)
|
|||
wxLaunchDefaultBrowser("https://wiki.bambulab.com/en/x1/manual/compatibility-and-parameter-settings-of-filaments");
|
||||
});
|
||||
|
||||
m_bed_type_list->Select(0);
|
||||
AppConfig *app_config = wxGetApp().app_config;
|
||||
std::string str_bed_type = app_config->get("curr_bed_type");
|
||||
m_bed_type_list->Select(atoi(str_bed_type.c_str()));
|
||||
bed_type_sizer->Add(bed_type_title, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
|
||||
bed_type_sizer->Add(m_bed_type_list, 1, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(10));
|
||||
vsizer_printer->Add(bed_type_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
|
||||
|
@ -650,6 +653,7 @@ Sidebar::Sidebar(Plater *parent)
|
|||
bSizer39->Add(FromDIP(10), 0, 0, 0, 0 );
|
||||
|
||||
ScalableButton* add_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "add_filament");
|
||||
add_btn->SetToolTip(_L("Add one filament"));
|
||||
add_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent& e){
|
||||
// BBS: limit filament choices to 16
|
||||
if (p->combos_filament.size() >= 16)
|
||||
|
@ -668,7 +672,8 @@ Sidebar::Sidebar(Plater *parent)
|
|||
bSizer39->Add(FromDIP(10), 0, 0, 0, 0 );
|
||||
|
||||
ScalableButton* del_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "delete_filament");
|
||||
del_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent& e){
|
||||
del_btn->SetToolTip(_L("Remove last filament"));
|
||||
del_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) {
|
||||
if (p->combos_filament.size() <= 1)
|
||||
return;
|
||||
|
||||
|
@ -690,8 +695,20 @@ Sidebar::Sidebar(Plater *parent)
|
|||
bSizer39->Add(del_btn, 0, wxALIGN_CENTER_VERTICAL, FromDIP(5));
|
||||
bSizer39->Add(FromDIP(20), 0, 0, 0, 0);
|
||||
|
||||
ScalableButton *ams_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "ams_fila_sync", wxEmptyString, wxDefaultSize, wxDefaultPosition,
|
||||
wxBU_EXACTFIT | wxNO_BORDER, false, 18);
|
||||
ams_btn->SetToolTip(_L("Sync material list from AMS"));
|
||||
ams_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) {
|
||||
sync_ams_list();
|
||||
});
|
||||
p->m_bpButton_ams_filament = ams_btn;
|
||||
|
||||
bSizer39->Add(ams_btn, 0, wxALIGN_CENTER|wxALL, FromDIP(5));
|
||||
bSizer39->Add(FromDIP(10), 0, 0, 0, 0 );
|
||||
|
||||
ScalableButton* set_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "settings");
|
||||
set_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
|
||||
set_btn->SetToolTip(_L("Set filaments to use"));
|
||||
set_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
|
||||
// p->editing_filament = -1;
|
||||
// wxGetApp().params_dialog()->Popup();
|
||||
// wxGetApp().get_tab(Preset::TYPE_FILAMENT)->restore_last_select_item();
|
||||
|
@ -1006,6 +1023,7 @@ void Sidebar::msw_rescale()
|
|||
p->m_filament_icon->msw_rescale();
|
||||
p->m_bpButton_add_filament->msw_rescale();
|
||||
p->m_bpButton_del_filament->msw_rescale();
|
||||
p->m_bpButton_ams_filament->msw_rescale();
|
||||
p->m_bpButton_set_filament->msw_rescale();
|
||||
p->m_flushing_volume_btn->Rescale();
|
||||
//BBS
|
||||
|
@ -1185,42 +1203,9 @@ void Sidebar::load_ams_list(std::map<std::string, Ams *> const &list)
|
|||
std::vector<DynamicPrintConfig> filament_ams_list;
|
||||
for (auto ams : list) {
|
||||
for (auto tray : ams.second->trayList) {
|
||||
if (tray.second->setting_id.empty())
|
||||
continue;
|
||||
if (tray.second->setting_id.empty()) continue;
|
||||
DynamicPrintConfig ams;
|
||||
auto & filaments = wxGetApp().preset_bundle->filaments.get_presets();
|
||||
auto iter = std::find_if(filaments.begin(), filaments.end(),
|
||||
[&tray](auto &f) { return f.filament_id == tray.second->setting_id; });
|
||||
if (iter != filaments.end()) {
|
||||
ams.set_key_value("filament_settings_id", new ConfigOptionStrings{tray.second->setting_id});
|
||||
} else {
|
||||
/* std::shared_ptr<std::map<std::string, std::string>> preset(new std::map<std::string, std::string>);
|
||||
(*preset)->setting_id = tray.second->setting_id;
|
||||
ams.set_key_value("filament_settings_id", new ConfigOptionStrings{tray.second->setting_id});
|
||||
//TODO: comment it currently
|
||||
NetworkAgent* agent = wxGetApp().getAgent();
|
||||
if (agent) {
|
||||
agent->get_setting(tray.second->setting_id, *preset, [preset] {
|
||||
wxGetApp().CallAfter([preset] {
|
||||
if ((*preset)->name.empty())
|
||||
return;
|
||||
PresetsConfigSubstitutions substitutions;
|
||||
wxGetApp().preset_bundle->filaments.load_user_presets({{(*preset)->name, *preset}},
|
||||
PRESET_FILAMENT_NAME, substitutions, ForwardCompatibilitySubstitutionRule::Enable);
|
||||
auto & ams_list = wxGetApp().preset_bundle->filament_ams_list;
|
||||
for (auto& ams : ams_list) {
|
||||
if (ams.opt_string("filament_settings_id", 0u) == (*preset)->setting_id) {
|
||||
ams.set_key_value("filament_settings_id", new ConfigOptionStrings{(*preset)->name});
|
||||
for (auto c : wxGetApp().sidebar().combos_filament()) c->update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
ams.set_key_value("filament_id", new ConfigOptionStrings{tray.second->setting_id});
|
||||
ams.set_key_value("filament_colour", new ConfigOptionStrings{"#" + tray.second->color.substr(0, 6)});
|
||||
filament_ams_list.emplace_back(std::move(ams));
|
||||
}
|
||||
|
@ -1230,6 +1215,34 @@ void Sidebar::load_ams_list(std::map<std::string, Ams *> const &list)
|
|||
c->update();
|
||||
}
|
||||
|
||||
void Sidebar::sync_ams_list()
|
||||
{
|
||||
auto & list = wxGetApp().preset_bundle->filament_ams_list;
|
||||
if (list.empty()) {
|
||||
MessageDialog dlg(this,
|
||||
_L("No AMS filaments. Please select a printer in 'Device' page to load AMS info."),
|
||||
_L("Sync filaments with AMS"), wxOK);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
MessageDialog dlg(this,
|
||||
_L("Sync filaments with AMS will drop all current selected filament presets and colors. Do you want to continue?"),
|
||||
_L("Sync filaments with AMS"), wxYES_NO);
|
||||
if (dlg.ShowModal() != wxID_YES) return;
|
||||
auto n = wxGetApp().preset_bundle->sync_ams_list();
|
||||
if (n == 0) {
|
||||
MessageDialog dlg(this,
|
||||
_L("There are no compatible filaments, and sync is not performed."),
|
||||
_L("Sync filaments with AMS"), wxOK);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
wxGetApp().plater()->on_filaments_change(n);
|
||||
for (auto &c : p->combos_filament)
|
||||
c->update();
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update();
|
||||
}
|
||||
|
||||
ObjectList* Sidebar::obj_list()
|
||||
{
|
||||
// BBS
|
||||
|
@ -1690,6 +1703,7 @@ struct Plater::priv
|
|||
void delete_object_from_model(size_t obj_idx, bool refresh_immediately = true); //BBS
|
||||
void delete_all_objects_from_model();
|
||||
void reset(bool apply_presets_change = false);
|
||||
void center_selection();
|
||||
void mirror(Axis axis);
|
||||
void split_object();
|
||||
void split_volume();
|
||||
|
@ -2257,12 +2271,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
//notification_manager = new NotificationManager(this->q);
|
||||
|
||||
if (wxGetApp().is_editor()) {
|
||||
//this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); });
|
||||
this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); });
|
||||
this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); });
|
||||
this->q->Bind(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, [](PresetUpdateAvailableClickedEvent&) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); });
|
||||
|
||||
/* BBS do not handle removeable driver event */
|
||||
/*
|
||||
this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this](RemovableDriveEjectEvent &evt) {
|
||||
if (evt.data.second) {
|
||||
// BBS
|
||||
|
@ -2285,14 +2298,13 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
// Close notification ExportingFinished but only if last export was to removable
|
||||
notification_manager->device_ejected();
|
||||
});
|
||||
*/
|
||||
// Start the background thread and register this window as a target for update events.
|
||||
//wxGetApp().removable_drive_manager()->init(this->q);
|
||||
//#ifdef _WIN32
|
||||
// Trigger enumeration of removable media on Win32 notification.
|
||||
//this->q->Bind(EVT_VOLUME_ATTACHED, [this](VolumeAttachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
|
||||
//this->q->Bind(EVT_VOLUME_DETACHED, [this](VolumeDetachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
|
||||
//#endif /* _WIN32 */
|
||||
wxGetApp().removable_drive_manager()->init(this->q);
|
||||
#ifdef _WIN32
|
||||
//Trigger enumeration of removable media on Win32 notification.
|
||||
this->q->Bind(EVT_VOLUME_ATTACHED, [this](VolumeAttachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
|
||||
this->q->Bind(EVT_VOLUME_DETACHED, [this](VolumeDetachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
// Initialize the Undo / Redo stack with a first snapshot.
|
||||
|
@ -2601,6 +2613,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
{
|
||||
std::vector<size_t> empty_result;
|
||||
bool dlg_cont = true;
|
||||
bool is_user_cancel = false;
|
||||
|
||||
if (input_files.empty()) { return std::vector<size_t>(); }
|
||||
|
||||
|
@ -2713,7 +2726,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
// BBS: backup & restore
|
||||
model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, en_3mf_file_type, strategy, &plate_data, &project_presets,
|
||||
&file_version,
|
||||
[this, &dlg, real_filename, &progress_percent, &file_percent, stage_percent, INPUT_FILES_RATIO, total_files, i](int import_stage, int current, int total, bool &cancel) {
|
||||
[this, &dlg, real_filename, &progress_percent, &file_percent, stage_percent, INPUT_FILES_RATIO, total_files, i,
|
||||
&is_user_cancel](int import_stage, int current, int total, bool &cancel) {
|
||||
bool cont = true;
|
||||
float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * ((float)stage_percent[import_stage] + (float)current * (float)(stage_percent[import_stage + 1] - stage_percent[import_stage]) /(float) total) / (float)total_files;
|
||||
BOOST_LOG_TRIVIAL(trace) << "load_3mf_file: percent(float)=" << percent_float << ", stage = " << import_stage << ", curr = " << current << ", total = " << total;
|
||||
|
@ -2721,14 +2735,16 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename));
|
||||
cont = dlg.Update(progress_percent, msg);
|
||||
cancel = !cont;
|
||||
if (cancel)
|
||||
is_user_cancel = cancel;
|
||||
});
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__
|
||||
<< boost::format(", plate_data.size %1%, project_preset.size %2%, is_bbs_3mf %3%, file_version %4% \n") % plate_data.size() %
|
||||
project_presets.size() % (en_3mf_file_type == En3mfType::From_BBS) % file_version.to_string();
|
||||
|
||||
// 1. add extruder for prusa model if the number of existing extruders is not enough
|
||||
// 2. add extruder for BBS model if only import geometry
|
||||
if (en_3mf_file_type == En3mfType::From_Prusa || (en_3mf_file_type == En3mfType::From_BBS && load_model && !load_config)) {
|
||||
// 2. add extruder for BBS or Other model if only import geometry
|
||||
if (en_3mf_file_type == En3mfType::From_Prusa || (load_model && !load_config)) {
|
||||
std::set<int> extruderIds;
|
||||
for (ModelObject *o : model.objects) {
|
||||
if (o->config.option("extruder")) extruderIds.insert(o->config.extruder());
|
||||
|
@ -3038,7 +3054,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
GUI::show_error(q, message);
|
||||
continue;
|
||||
} catch (const std::exception &e) {
|
||||
GUI::show_error(q, e.what());
|
||||
if (!is_user_cancel)
|
||||
GUI::show_error(q, e.what());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3100,16 +3117,16 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
// convert_model_if(model, answer_convert_from_imperial_units == wxID_YES);
|
||||
}
|
||||
|
||||
// if (model.looks_like_multipart_object()) {
|
||||
// MessageDialog msg_dlg(q, _L(
|
||||
// "This file contains several objects positioned at multiple heights.\n"
|
||||
// "Instead of considering them as multiple objects, should \n"
|
||||
// "the file be loaded as a single object having multiple parts?") + "\n",
|
||||
// _L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO);
|
||||
// if (msg_dlg.ShowModal() == wxID_YES) {
|
||||
// model.convert_multipart_object(filaments_cnt);
|
||||
// }
|
||||
//}
|
||||
if (model.looks_like_multipart_object()) {
|
||||
MessageDialog msg_dlg(q, _L(
|
||||
"This file contains several objects positioned at multiple heights.\n"
|
||||
"Instead of considering them as multiple objects, should \n"
|
||||
"the file be loaded as a single object having multiple parts?") + "\n",
|
||||
_L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO);
|
||||
if (msg_dlg.ShowModal() == wxID_YES) {
|
||||
model.convert_multipart_object(filaments_cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
// else if ((wxGetApp().get_mode() == comSimple) && (type_3mf || type_any_amf) && model_has_advanced_features(model)) {
|
||||
// MessageDialog msg_dlg(q, _L("This file cannot be loaded in a simple mode. Do you want to switch to an advanced mode?")+"\n",
|
||||
|
@ -3271,8 +3288,10 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
|
||||
if (tolal_model_count <= 0 && !q->m_exported_file) {
|
||||
dlg.Hide();
|
||||
MessageDialog msg(wxGetApp().mainframe, _L("The file does not contain any geometry data."), _L("Warning"), wxYES | wxICON_WARNING);
|
||||
if (msg.ShowModal() == wxID_YES) {}
|
||||
if (!is_user_cancel) {
|
||||
MessageDialog msg(wxGetApp().mainframe, _L("The file does not contain any geometry data."), _L("Warning"), wxYES | wxICON_WARNING);
|
||||
if (msg.ShowModal() == wxID_YES) {}
|
||||
}
|
||||
}
|
||||
return obj_idxs;
|
||||
}
|
||||
|
@ -3714,6 +3733,11 @@ void Plater::priv::reset(bool apply_presets_change)
|
|||
m_saved_timestamp = m_backup_timestamp = size_t(-1);
|
||||
}
|
||||
|
||||
void Plater::priv::center_selection()
|
||||
{
|
||||
view3D->center_selected();
|
||||
}
|
||||
|
||||
void Plater::priv::mirror(Axis axis)
|
||||
{
|
||||
view3D->mirror_selection(axis);
|
||||
|
@ -3823,7 +3847,7 @@ void Plater::priv::update_print_volume_state()
|
|||
//BBS: use the plate's bounding box instead of the bed's
|
||||
PartPlate* pp = partplate_list.get_curr_plate();
|
||||
BuildVolume build_volume(pp->get_shape(), this->bed.build_volume().printable_height());
|
||||
this->q->model().update_print_volume_state(build_volume);
|
||||
this->model.update_print_volume_state(build_volume);
|
||||
}
|
||||
|
||||
void Plater::priv::process_validation_warning(StringObjectException const &warning) const
|
||||
|
@ -3903,7 +3927,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
|
|||
this->partplate_list.update_slice_context_to_current_plate(background_process);
|
||||
this->preview->update_gcode_result(partplate_list.get_current_slice_result());
|
||||
}
|
||||
Print::ApplyStatus invalidated = background_process.apply(q->model(), wxGetApp().preset_bundle->full_config());
|
||||
Print::ApplyStatus invalidated = background_process.apply(this->model, wxGetApp().preset_bundle->full_config());
|
||||
|
||||
if ((invalidated == Print::APPLY_STATUS_CHANGED) || (invalidated == Print::APPLY_STATUS_INVALIDATED))
|
||||
// BBS: add only gcode mode
|
||||
|
@ -4023,7 +4047,8 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
|
|||
|
||||
//BBS: add slice&&print status update logic
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: background data valid, return_state=%2%")%__LINE__%return_state;
|
||||
if (background_process.finished())
|
||||
PartPlate* cur_plate = background_process.get_current_plate();
|
||||
if (background_process.finished() && cur_plate && cur_plate->is_slice_result_valid())
|
||||
{
|
||||
ready_to_slice = false;
|
||||
this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false);
|
||||
|
@ -4291,55 +4316,91 @@ bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const
|
|||
|
||||
void Plater::priv::replace_with_stl()
|
||||
{
|
||||
// BBS do not support replace with STL
|
||||
//if (! q->get_view3D_canvas3D()->get_gizmos_manager().check_gizmos_closed_except(GLGizmosManager::EType::Undefined))
|
||||
// return;
|
||||
if (! q->get_view3D_canvas3D()->get_gizmos_manager().check_gizmos_closed_except(GLGizmosManager::EType::Undefined))
|
||||
return;
|
||||
|
||||
//const Selection& selection = get_selection();
|
||||
const Selection& selection = get_selection();
|
||||
|
||||
//if (selection.is_wipe_tower() || get_selection().get_volume_idxs().size() != 1)
|
||||
// return;
|
||||
if (selection.is_wipe_tower() || get_selection().get_volume_idxs().size() != 1)
|
||||
return;
|
||||
|
||||
//const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
//int object_idx = v->object_idx();
|
||||
//int volume_idx = v->volume_idx();
|
||||
const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
int object_idx = v->object_idx();
|
||||
int volume_idx = v->volume_idx();
|
||||
|
||||
//// collects paths of files to load
|
||||
// collects paths of files to load
|
||||
|
||||
//const ModelObject* object = model.objects[object_idx];
|
||||
//const ModelVolume* volume = object->volumes[volume_idx];
|
||||
const ModelObject* object = model.objects[object_idx];
|
||||
const ModelVolume* volume = object->volumes[volume_idx];
|
||||
|
||||
//fs::path input_path;
|
||||
//if (!volume->source.input_file.empty() && fs::exists(volume->source.input_file))
|
||||
// input_path = volume->source.input_file;
|
||||
fs::path input_path;
|
||||
if (!volume->source.input_file.empty() && fs::exists(volume->source.input_file))
|
||||
input_path = volume->source.input_file;
|
||||
|
||||
//wxString title = _L("Select the new file");
|
||||
//title += ":";
|
||||
//wxFileDialog dialog(q, title, "", from_u8(input_path.filename().string()), file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
//if (dialog.ShowModal() != wxID_OK)
|
||||
// return;
|
||||
wxString title = _L("Select a new file");
|
||||
title += ":";
|
||||
wxFileDialog dialog(q, title, "", from_u8(input_path.filename().string()), file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
if (dialog.ShowModal() != wxID_OK)
|
||||
return;
|
||||
|
||||
//fs::path out_path = dialog.GetPath().ToUTF8().data();
|
||||
//if (out_path.empty()) {
|
||||
// MessageDialog dlg(q, _L("File for the replace wasn't selected"), _L("Error during replace"), wxOK | wxOK_DEFAULT | wxICON_WARNING);
|
||||
// dlg.ShowModal();
|
||||
// return;
|
||||
//}
|
||||
fs::path out_path = dialog.GetPath().ToUTF8().data();
|
||||
if (out_path.empty()) {
|
||||
MessageDialog dlg(q, _L("File for the replace wasn't selected"), _L("Error during replace"), wxOK | wxOK_DEFAULT | wxICON_WARNING);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
//if (!replace_volume_with_stl(object_idx, volume_idx, out_path, "Replace with STL"))
|
||||
// return;
|
||||
if (!replace_volume_with_stl(object_idx, volume_idx, out_path, "Replace with STL"))
|
||||
return;
|
||||
|
||||
//// update 3D scene
|
||||
//update();
|
||||
// update 3D scene
|
||||
update();
|
||||
|
||||
//// new GLVolumes have been created at this point, so update their printable state
|
||||
//for (size_t i = 0; i < model.objects.size(); ++i) {
|
||||
// view3D->get_canvas3d()->update_instance_printable_state_for_object(i);
|
||||
//}
|
||||
// new GLVolumes have been created at this point, so update their printable state
|
||||
for (size_t i = 0; i < model.objects.size(); ++i) {
|
||||
view3D->get_canvas3d()->update_instance_printable_state_for_object(i);
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
static std::vector<std::pair<int, int>> reloadable_volumes(const Model &model, const Selection &selection)
|
||||
{
|
||||
std::vector<std::pair<int, int>> ret;
|
||||
const std::set<unsigned int> & selected_volumes_idxs = selection.get_volume_idxs();
|
||||
for (unsigned int idx : selected_volumes_idxs) {
|
||||
const GLVolume &v = *selection.get_volume(idx);
|
||||
const int o_idx = v.object_idx();
|
||||
if (0 <= o_idx && o_idx < int(model.objects.size())) {
|
||||
const ModelObject *obj = model.objects[o_idx];
|
||||
const int v_idx = v.volume_idx();
|
||||
if (0 <= v_idx && v_idx < int(obj->volumes.size())) {
|
||||
const ModelVolume *vol = obj->volumes[v_idx];
|
||||
if (!vol->source.is_from_builtin_objects && !vol->source.input_file.empty() && !fs::path(vol->source.input_file).extension().string().empty())
|
||||
ret.push_back({o_idx, v_idx});
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
|
||||
void Plater::priv::reload_from_disk()
|
||||
{
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
// collect selected reloadable ModelVolumes
|
||||
std::vector<std::pair<int, int>> selected_volumes = reloadable_volumes(model, get_selection());
|
||||
|
||||
// nothing to reload, return
|
||||
if (selected_volumes.empty())
|
||||
return;
|
||||
|
||||
std::sort(selected_volumes.begin(), selected_volumes.end(), [](const std::pair<int, int> &v1, const std::pair<int, int> &v2) {
|
||||
return (v1.first < v2.first) || (v1.first == v2.first && v1.second < v2.second);
|
||||
});
|
||||
selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end(), [](const std::pair<int, int> &v1, const std::pair<int, int> &v2) {
|
||||
return (v1.first == v2.first) && (v1.second == v2.second);
|
||||
}), selected_volumes.end());
|
||||
#else
|
||||
Plater::TakeSnapshot snapshot(q, "Reload from disk");
|
||||
|
||||
const Selection& selection = get_selection();
|
||||
|
@ -4372,10 +4433,36 @@ void Plater::priv::reload_from_disk()
|
|||
}
|
||||
std::sort(selected_volumes.begin(), selected_volumes.end());
|
||||
selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end()), selected_volumes.end());
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
|
||||
// collects paths of files to load
|
||||
std::vector<fs::path> input_paths;
|
||||
std::vector<fs::path> missing_input_paths;
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
std::vector<std::pair<fs::path, fs::path>> replace_paths;
|
||||
for (auto [obj_idx, vol_idx] : selected_volumes) {
|
||||
const ModelObject *object = model.objects[obj_idx];
|
||||
const ModelVolume *volume = object->volumes[vol_idx];
|
||||
if (fs::exists(volume->source.input_file))
|
||||
input_paths.push_back(volume->source.input_file);
|
||||
else {
|
||||
// searches the source in the same folder containing the object
|
||||
bool found = false;
|
||||
if (!object->input_file.empty()) {
|
||||
fs::path object_path = fs::path(object->input_file).remove_filename();
|
||||
if (!object_path.empty()) {
|
||||
object_path /= fs::path(volume->source.input_file).filename();
|
||||
if (fs::exists(object_path)) {
|
||||
input_paths.push_back(object_path);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
missing_input_paths.push_back(volume->source.input_file);
|
||||
}
|
||||
}
|
||||
#else
|
||||
std::vector<fs::path> replace_paths;
|
||||
for (const SelectedVolume& v : selected_volumes) {
|
||||
const ModelObject* object = model.objects[v.object_idx];
|
||||
|
@ -4405,6 +4492,7 @@ void Plater::priv::reload_from_disk()
|
|||
else if (!object->input_file.empty() && volume->is_model_part() && !volume->name.empty() && !volume->source.is_from_builtin_objects)
|
||||
missing_input_paths.push_back(volume->name);
|
||||
}
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
|
||||
std::sort(missing_input_paths.begin(), missing_input_paths.end());
|
||||
missing_input_paths.erase(std::unique(missing_input_paths.begin(), missing_input_paths.end()), missing_input_paths.end());
|
||||
|
@ -4446,7 +4534,11 @@ void Plater::priv::reload_from_disk()
|
|||
wxString message = _devL("Do you want to replace it") + " ?";
|
||||
MessageDialog dlg(q, message, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION);
|
||||
if (dlg.ShowModal() == wxID_YES)
|
||||
replace_paths.push_back(sel_filename_path);
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
replace_paths.emplace_back(search, sel_filename_path);
|
||||
#else
|
||||
replace_paths.emplace_back(sel_filename_path);
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
missing_input_paths.pop_back();
|
||||
}
|
||||
}
|
||||
|
@ -4457,6 +4549,10 @@ void Plater::priv::reload_from_disk()
|
|||
std::sort(replace_paths.begin(), replace_paths.end());
|
||||
replace_paths.erase(std::unique(replace_paths.begin(), replace_paths.end()), replace_paths.end());
|
||||
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
Plater::TakeSnapshot snapshot(q, "Reload from disk");
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
|
||||
std::vector<wxString> fail_list;
|
||||
|
||||
// load one file at a time
|
||||
|
@ -4497,6 +4593,93 @@ void Plater::priv::reload_from_disk()
|
|||
return;
|
||||
}
|
||||
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
for (auto [obj_idx, vol_idx] : selected_volumes) {
|
||||
ModelObject *old_model_object = model.objects[obj_idx];
|
||||
ModelVolume *old_volume = old_model_object->volumes[vol_idx];
|
||||
|
||||
bool sinking = old_model_object->bounding_box().min.z() < SINKING_Z_THRESHOLD;
|
||||
|
||||
bool has_source = !old_volume->source.input_file.empty() &&
|
||||
boost::algorithm::iequals(fs::path(old_volume->source.input_file).filename().string(), fs::path(path).filename().string());
|
||||
bool has_name = !old_volume->name.empty() && boost::algorithm::iequals(old_volume->name, fs::path(path).filename().string());
|
||||
if (has_source || has_name) {
|
||||
int new_volume_idx = -1;
|
||||
int new_object_idx = -1;
|
||||
bool match_found = false;
|
||||
// take idxs from the matching volume
|
||||
if (has_source && old_volume->source.object_idx < int(new_model.objects.size())) {
|
||||
const ModelObject *obj = new_model.objects[old_volume->source.object_idx];
|
||||
if (old_volume->source.volume_idx < int(obj->volumes.size())) {
|
||||
if (obj->volumes[old_volume->source.volume_idx]->name == old_volume->name) {
|
||||
new_volume_idx = old_volume->source.volume_idx;
|
||||
new_object_idx = old_volume->source.object_idx;
|
||||
match_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!match_found && has_name) {
|
||||
// take idxs from the 1st matching volume
|
||||
for (size_t o = 0; o < new_model.objects.size(); ++o) {
|
||||
ModelObject *obj = new_model.objects[o];
|
||||
bool found = false;
|
||||
for (size_t v = 0; v < obj->volumes.size(); ++v) {
|
||||
if (obj->volumes[v]->name == old_volume->name) {
|
||||
new_volume_idx = (int) v;
|
||||
new_object_idx = (int) o;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_object_idx < 0 || int(new_model.objects.size()) <= new_object_idx) {
|
||||
fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name));
|
||||
continue;
|
||||
}
|
||||
ModelObject *new_model_object = new_model.objects[new_object_idx];
|
||||
if (new_volume_idx < 0 || int(new_model_object->volumes.size()) <= new_volume_idx) {
|
||||
fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name));
|
||||
continue;
|
||||
}
|
||||
|
||||
old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]);
|
||||
ModelVolume *new_volume = old_model_object->volumes.back();
|
||||
new_volume->set_new_unique_id();
|
||||
new_volume->config.apply(old_volume->config);
|
||||
new_volume->set_type(old_volume->type());
|
||||
new_volume->set_material_id(old_volume->material_id());
|
||||
#if 0// ENABLE_WORLD_COORDINATE
|
||||
new_volume->set_transformation(Geometry::translation_transform(old_volume->source.transform.get_offset()) *
|
||||
old_volume->get_transformation().get_matrix_no_offset() * old_volume->source.transform.get_matrix_no_offset());
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix_no_offset() * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
#else
|
||||
new_volume->set_transformation(Geometry::assemble_transform(old_volume->source.transform.get_offset()) * old_volume->get_transformation().get_matrix(true) *
|
||||
old_volume->source.transform.get_matrix(true));
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
new_volume->source.object_idx = old_volume->source.object_idx;
|
||||
new_volume->source.volume_idx = old_volume->source.volume_idx;
|
||||
assert(!old_volume->source.is_converted_from_inches || !old_volume->source.is_converted_from_meters);
|
||||
if (old_volume->source.is_converted_from_inches)
|
||||
new_volume->convert_from_imperial_units();
|
||||
else if (old_volume->source.is_converted_from_meters)
|
||||
new_volume->convert_from_meters();
|
||||
std::swap(old_model_object->volumes[vol_idx], old_model_object->volumes.back());
|
||||
old_model_object->delete_volume(old_model_object->volumes.size() - 1);
|
||||
if (!sinking) old_model_object->ensure_on_bed();
|
||||
old_model_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1");
|
||||
|
||||
sla::reproject_points_and_holes(old_model_object);
|
||||
|
||||
// Fix warning icon in object list
|
||||
wxGetApp().obj_list()->update_item_error_icon(obj_idx, vol_idx);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// update the selected volumes whose source is the current file
|
||||
for (const SelectedVolume& sel_v : selected_volumes) {
|
||||
ModelObject* old_model_object = model.objects[sel_v.object_idx];
|
||||
|
@ -4566,8 +4749,17 @@ void Plater::priv::reload_from_disk()
|
|||
sla::reproject_points_and_holes(old_model_object);
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
}
|
||||
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
for (auto [src, dest] : replace_paths) {
|
||||
for (auto [obj_idx, vol_idx] : selected_volumes) {
|
||||
if (boost::algorithm::iequals(model.objects[obj_idx]->volumes[vol_idx]->source.input_file, src.string()))
|
||||
replace_volume_with_stl(obj_idx, vol_idx, dest, "");
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (size_t i = 0; i < replace_paths.size(); ++i) {
|
||||
const auto& path = replace_paths[i].string();
|
||||
for (const SelectedVolume& sel_v : selected_volumes) {
|
||||
|
@ -4579,6 +4771,7 @@ void Plater::priv::reload_from_disk()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
|
||||
if (!fail_list.empty()) {
|
||||
wxString message = _devL("Unable to reload:") + "\n";
|
||||
|
@ -4893,6 +5086,10 @@ void Plater::priv::on_select_bed_type(wxCommandEvent &evt)
|
|||
config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
|
||||
// update plater with new config
|
||||
q->on_config_change(wxGetApp().preset_bundle->full_config());
|
||||
|
||||
// update app_config
|
||||
AppConfig *app_config = wxGetApp().app_config;
|
||||
app_config->set("curr_bed_type", std::to_string(int(bed_type)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5257,16 +5454,16 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
|
|||
notification_manager->close_notification_of_type(NotificationType::ExportOngoing);
|
||||
}
|
||||
// If writing to removable drive was scheduled, show notification with eject button
|
||||
/*if (exporting_status == ExportingStatus::EXPORTING_TO_REMOVABLE && !has_error) {
|
||||
if (exporting_status == ExportingStatus::EXPORTING_TO_REMOVABLE && !has_error) {
|
||||
//show_action_buttons(ready_to_slice);
|
||||
this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, ready_to_slice, true);
|
||||
notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path,
|
||||
// Don't offer the "Eject" button on ChromeOS, the Linux side has no control over it.
|
||||
platform_flavor() != PlatformFlavor::LinuxOnChromium);
|
||||
//wxGetApp().removable_drive_manager()->set_exporting_finished(true);
|
||||
}else */
|
||||
//if (exporting_status == ExportingStatus::EXPORTING_TO_LOCAL && !has_error)
|
||||
// notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path, false);
|
||||
wxGetApp().removable_drive_manager()->set_exporting_finished(true);
|
||||
}else
|
||||
if (exporting_status == ExportingStatus::EXPORTING_TO_LOCAL && !has_error)
|
||||
notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path, false);
|
||||
}
|
||||
|
||||
exporting_status = ExportingStatus::NOT_EXPORTING;
|
||||
|
@ -6033,6 +6230,13 @@ bool Plater::priv::can_replace_with_stl() const
|
|||
|
||||
bool Plater::priv::can_reload_from_disk() const
|
||||
{
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
// collect selected reloadable ModelVolumes
|
||||
std::vector<std::pair<int, int>> selected_volumes = reloadable_volumes(model, get_selection());
|
||||
// nothing to reload, return
|
||||
if (selected_volumes.empty())
|
||||
return false;
|
||||
#else
|
||||
// struct to hold selected ModelVolumes by their indices
|
||||
struct SelectedVolume
|
||||
{
|
||||
|
@ -6058,6 +6262,22 @@ bool Plater::priv::can_reload_from_disk() const
|
|||
selected_volumes.push_back({ o_idx, v_idx });
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
|
||||
#if ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
std::sort(selected_volumes.begin(), selected_volumes.end(), [](const std::pair<int, int> &v1, const std::pair<int, int> &v2) {
|
||||
return (v1.first < v2.first) || (v1.first == v2.first && v1.second < v2.second);
|
||||
});
|
||||
selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end(), [](const std::pair<int, int> &v1, const std::pair<int, int> &v2) {
|
||||
return (v1.first == v2.first) && (v1.second == v2.second);
|
||||
}), selected_volumes.end());
|
||||
|
||||
// collects paths of files to load
|
||||
std::vector<fs::path> paths;
|
||||
for (auto [obj_idx, vol_idx] : selected_volumes) {
|
||||
paths.push_back(model.objects[obj_idx]->volumes[vol_idx]->source.input_file);
|
||||
}
|
||||
#else
|
||||
std::sort(selected_volumes.begin(), selected_volumes.end());
|
||||
selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end()), selected_volumes.end());
|
||||
|
||||
|
@ -6071,6 +6291,7 @@ bool Plater::priv::can_reload_from_disk() const
|
|||
else if (!object->input_file.empty() && !volume->name.empty() && !volume->source.is_from_builtin_objects)
|
||||
paths.push_back(volume->name);
|
||||
}
|
||||
#endif // ENABLE_RELOAD_FROM_DISK_REWORK
|
||||
std::sort(paths.begin(), paths.end());
|
||||
paths.erase(std::unique(paths.begin(), paths.end()), paths.end());
|
||||
|
||||
|
@ -6607,7 +6828,8 @@ Plater::Plater(wxWindow *parent, MainFrame *main_frame)
|
|||
|
||||
bool Plater::Show(bool show)
|
||||
{
|
||||
wxGetApp().mainframe->show_option(show);
|
||||
if (wxGetApp().mainframe)
|
||||
wxGetApp().mainframe->show_option(show);
|
||||
return wxPanel::Show(show);
|
||||
}
|
||||
|
||||
|
@ -8031,16 +8253,16 @@ void Plater::export_gcode(bool prefer_removable)
|
|||
}
|
||||
default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string()));
|
||||
AppConfig &appconfig = *wxGetApp().app_config;
|
||||
//RemovableDriveManager &removable_drive_manager = *wxGetApp().removable_drive_manager();
|
||||
RemovableDriveManager &removable_drive_manager = *wxGetApp().removable_drive_manager();
|
||||
// Get a last save path, either to removable media or to an internal media.
|
||||
std::string start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), prefer_removable);
|
||||
/*if (prefer_removable) {
|
||||
if (prefer_removable) {
|
||||
// Returns a path to a removable media if it exists, prefering start_dir. Update the internal removable drives database.
|
||||
start_dir = removable_drive_manager.get_removable_drive_path(start_dir);
|
||||
if (start_dir.empty())
|
||||
// Direct user to the last internal media.
|
||||
start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), false);
|
||||
}*/
|
||||
}
|
||||
|
||||
fs::path output_path;
|
||||
{
|
||||
|
@ -8068,8 +8290,8 @@ void Plater::export_gcode(bool prefer_removable)
|
|||
}
|
||||
|
||||
if (! output_path.empty()) {
|
||||
//bool path_on_removable_media = removable_drive_manager.set_and_verify_last_save_path(output_path.string());
|
||||
bool path_on_removable_media = false;
|
||||
bool path_on_removable_media = removable_drive_manager.set_and_verify_last_save_path(output_path.string());
|
||||
//bool path_on_removable_media = false;
|
||||
p->notification_manager->new_export_began(path_on_removable_media);
|
||||
p->exporting_status = path_on_removable_media ? ExportingStatus::EXPORTING_TO_REMOVABLE : ExportingStatus::EXPORTING_TO_LOCAL;
|
||||
p->last_output_path = output_path.string();
|
||||
|
@ -8138,13 +8360,20 @@ void Plater::export_gcode_3mf()
|
|||
p->notification_manager->new_export_began(path_on_removable_media);
|
||||
p->exporting_status = path_on_removable_media ? ExportingStatus::EXPORTING_TO_REMOVABLE : ExportingStatus::EXPORTING_TO_LOCAL;
|
||||
//BBS do not save last output path
|
||||
//p->last_output_path = output_path.string();
|
||||
p->last_output_path = output_path.string();
|
||||
p->last_output_dir_path = output_path.parent_path().string();
|
||||
int curr_plate_idx = get_partplate_list().get_curr_plate_index();
|
||||
export_3mf(output_path, SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithGcode | SaveStrategy::SkipModel, curr_plate_idx); // BBS: silence
|
||||
// update lost output dir
|
||||
|
||||
RemovableDriveManager& removable_drive_manager = *wxGetApp().removable_drive_manager();
|
||||
|
||||
|
||||
bool on_removable = removable_drive_manager.is_path_on_removable_drive(p->last_output_dir_path);
|
||||
|
||||
|
||||
// update last output dir
|
||||
appconfig.update_last_output_dir(output_path.parent_path().string(), false);
|
||||
p->notification_manager->push_exporting_finished_notification(output_path.string(), p->last_output_dir_path, false);
|
||||
p->notification_manager->push_exporting_finished_notification(output_path.string(), p->last_output_dir_path, on_removable);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8556,6 +8785,7 @@ void Plater::reslice()
|
|||
if (p->process_completed_with_error)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": process_completed_with_error, return directly");
|
||||
reset_gcode_toolpaths();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8830,11 +9060,12 @@ void Plater::print_job_finished(wxCommandEvent &evt)
|
|||
}
|
||||
|
||||
// Called when the Eject button is pressed.
|
||||
/*void Plater::eject_drive()
|
||||
void Plater::eject_drive()
|
||||
{
|
||||
wxBusyCursor wait;
|
||||
wxGetApp().removable_drive_manager()->eject_drive();
|
||||
}*/
|
||||
wxBusyCursor wait;
|
||||
wxGetApp().removable_drive_manager()->set_and_verify_last_save_path(p->last_output_dir_path);
|
||||
wxGetApp().removable_drive_manager()->eject_drive();
|
||||
}
|
||||
|
||||
void Plater::take_snapshot(const std::string &snapshot_name) { p->take_snapshot(snapshot_name); }
|
||||
//void Plater::take_snapshot(const wxString &snapshot_name) { p->take_snapshot(snapshot_name); }
|
||||
|
@ -9367,6 +9598,7 @@ void Plater::suppress_background_process(const bool stop_background_process)
|
|||
this->p->suppressed_backround_processing_update = true;
|
||||
}
|
||||
|
||||
void Plater::center_selection() { p->center_selection(); }
|
||||
void Plater::mirror(Axis axis) { p->mirror(axis); }
|
||||
void Plater::split_object() { p->split_object(); }
|
||||
void Plater::split_volume() { p->split_volume(); }
|
||||
|
|
|
@ -117,7 +117,8 @@ public:
|
|||
void on_filaments_change(size_t num_filaments);
|
||||
// BBS
|
||||
void on_bed_type_change(BedType bed_type);
|
||||
void load_ams_list(std::map<std::string, Ams *> const & list);
|
||||
void load_ams_list(std::map<std::string, Ams *> const &list);
|
||||
void sync_ams_list();
|
||||
|
||||
ObjectList* obj_list();
|
||||
ObjectSettings* obj_settings();
|
||||
|
@ -333,7 +334,7 @@ public:
|
|||
int export_config_3mf(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
|
||||
//BBS jump to nonitor after print job finished
|
||||
void print_job_finished(wxCommandEvent &evt);
|
||||
//void eject_drive();
|
||||
void eject_drive();
|
||||
|
||||
void take_snapshot(const std::string &snapshot_name);
|
||||
//void take_snapshot(const wxString &snapshot_name);
|
||||
|
@ -412,6 +413,7 @@ public:
|
|||
void paste_from_clipboard();
|
||||
//BBS: add clone logic
|
||||
void clone_selection();
|
||||
void center_selection();
|
||||
void search(bool plater_is_active, Preset::Type type, wxWindow *tag, wxTextCtrl *etag, wxWindow *stag);
|
||||
void mirror(Axis axis);
|
||||
void split_object();
|
||||
|
|
|
@ -244,16 +244,6 @@ int PresetComboBox::update_ams_color()
|
|||
return idx;
|
||||
}
|
||||
|
||||
static std::string suffix(const Preset& preset)
|
||||
{
|
||||
return (preset.is_dirty ? Preset::suffix_modified() : "");
|
||||
}
|
||||
|
||||
static std::string suffix(Preset* preset)
|
||||
{
|
||||
return (preset->is_dirty ? Preset::suffix_modified() : "");
|
||||
}
|
||||
|
||||
wxColor PresetComboBox::different_color(wxColor const &clr)
|
||||
{
|
||||
if (clr.GetLuminance() < 0.51) return *wxWHITE;
|
||||
|
@ -387,11 +377,11 @@ void PresetComboBox::add_ams_filaments(std::string selected, bool alias_name)
|
|||
m_first_ams_filament = GetCount();
|
||||
auto &filaments = m_collection->get_presets();
|
||||
for (auto &f : m_preset_bundle->filament_ams_list) {
|
||||
std::string setting_id = f.opt_string("filament_settings_id", 0u);
|
||||
std::string filament_id = f.opt_string("filament_id", 0u);
|
||||
auto iter = std::find_if(filaments.begin(), filaments.end(),
|
||||
[&setting_id](auto &f) { return f.is_compatible && f.is_system && f.filament_id == setting_id; });
|
||||
[&filament_id](auto &f) { return f.is_compatible && f.is_system && f.filament_id == filament_id; });
|
||||
if (iter == filaments.end()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": filament_id %1% not found or system or compatible") % setting_id;
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": filament_id %1% not found or system or compatible") % filament_id;
|
||||
continue;
|
||||
}
|
||||
const_cast<Preset&>(*iter).is_visible = true;
|
||||
|
@ -771,7 +761,7 @@ void PlaterPresetComboBox::switch_to_tab()
|
|||
if (m_type == Preset::TYPE_FILAMENT)
|
||||
{
|
||||
const std::string& selected_preset = GetString(GetSelection()).ToUTF8().data();
|
||||
if (!boost::algorithm::ends_with(selected_preset, Preset::suffix_modified()))
|
||||
if (!boost::algorithm::starts_with(selected_preset, Preset::suffix_modified()))
|
||||
{
|
||||
const std::string& preset_name = wxGetApp().preset_bundle->filaments.get_preset_name_by_alias(selected_preset);
|
||||
wxGetApp().get_tab(m_type)->select_preset(preset_name);
|
||||
|
@ -869,8 +859,7 @@ void PlaterPresetComboBox::show_edit_menu()
|
|||
|
||||
wxString PlaterPresetComboBox::get_preset_name(const Preset& preset)
|
||||
{
|
||||
std::string name = preset.alias.empty() ? preset.name : preset.alias;
|
||||
return from_u8(name + suffix(preset));
|
||||
return from_u8(preset.label(false));
|
||||
}
|
||||
|
||||
// Only the compatible presets are shown.
|
||||
|
@ -979,10 +968,10 @@ void PlaterPresetComboBox::update()
|
|||
const std::string name = preset.alias.empty() ? preset.name : preset.alias;
|
||||
if (preset.is_default || preset.is_system) {
|
||||
//BBS: move system to the end
|
||||
system_presets.emplace(wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), bmp);
|
||||
system_presets.emplace(get_preset_name(preset), bmp);
|
||||
if (is_selected) {
|
||||
tooltip = get_tooltip(preset);
|
||||
selected_system_preset = wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
|
||||
selected_system_preset = get_preset_name(preset);
|
||||
}
|
||||
//Append(get_preset_name(preset), *bmp);
|
||||
//validate_selection(is_selected);
|
||||
|
@ -993,9 +982,9 @@ void PlaterPresetComboBox::update()
|
|||
//BBS: add project embedded preset logic
|
||||
else if (preset.is_project_embedded)
|
||||
{
|
||||
project_embedded_presets.emplace(wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), bmp);
|
||||
project_embedded_presets.emplace(get_preset_name(preset), bmp);
|
||||
if (is_selected) {
|
||||
selected_user_preset = wxString::FromUTF8((name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
|
||||
selected_user_preset = get_preset_name(preset);
|
||||
tooltip = wxString::FromUTF8(preset.name.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -1166,7 +1155,7 @@ void TabPresetComboBox::OnSelect(wxCommandEvent &evt)
|
|||
|
||||
wxString TabPresetComboBox::get_preset_name(const Preset& preset)
|
||||
{
|
||||
return from_u8(preset.name + suffix(preset));
|
||||
return from_u8(preset.label(true));
|
||||
}
|
||||
|
||||
// Update the choice UI from the list of presets.
|
||||
|
@ -1221,9 +1210,9 @@ void TabPresetComboBox::update()
|
|||
|
||||
if (preset.is_default || preset.is_system) {
|
||||
//BBS: move system to the end
|
||||
system_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), std::pair<wxBitmap*, bool>(bmp, is_enabled));
|
||||
system_presets.emplace(get_preset_name(preset), std::pair<wxBitmap *, bool>(bmp, is_enabled));
|
||||
if (i == idx_selected)
|
||||
selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
|
||||
selected = get_preset_name(preset);
|
||||
//int item_id = Append(get_preset_name(preset), *bmp);
|
||||
//if (!is_enabled)
|
||||
// set_label_marker(item_id, LABEL_ITEM_DISABLED);
|
||||
|
@ -1233,9 +1222,9 @@ void TabPresetComboBox::update()
|
|||
else if (preset.is_project_embedded)
|
||||
{
|
||||
//std::pair<wxBitmap*, bool> pair(bmp, is_enabled);
|
||||
project_embedded_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), std::pair<wxBitmap*, bool>(bmp, is_enabled));
|
||||
project_embedded_presets.emplace(get_preset_name(preset), std::pair<wxBitmap *, bool>(bmp, is_enabled));
|
||||
if (i == idx_selected)
|
||||
selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
|
||||
selected = get_preset_name(preset);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1364,7 +1353,7 @@ void TabPresetComboBox::update_dirty()
|
|||
|
||||
Preset* preset = m_collection->find_preset(preset_name, false);
|
||||
if (preset) {
|
||||
std::string new_label = preset->name + suffix(preset);
|
||||
std::string new_label = preset->label(true);
|
||||
|
||||
if (marker == LABEL_ITEM_PHYSICAL_PRINTER)
|
||||
new_label = ph_printer_name + PhysicalPrinter::separator() + new_label;
|
||||
|
|
|
@ -108,7 +108,7 @@ wxBoxSizer* PrintOptionsDialog::create_settings_group(wxWindow* parent)
|
|||
auto sizer = new wxBoxSizer(wxVERTICAL);
|
||||
auto line_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_cb_spaghetti = new CheckBox(parent);
|
||||
text_spaghetti = new wxStaticText(parent, wxID_ANY, _L("Spaghetti Detection"));
|
||||
text_spaghetti = new wxStaticText(parent, wxID_ANY, _L("Spaghetti and Excess Chute Pileup Detection"));
|
||||
text_spaghetti->SetFont(Label::Body_14);
|
||||
line_sizer->Add(FromDIP(5), 0, 0, 0);
|
||||
line_sizer->Add(m_cb_spaghetti, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
|
||||
|
@ -117,7 +117,7 @@ wxBoxSizer* PrintOptionsDialog::create_settings_group(wxWindow* parent)
|
|||
|
||||
line_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_cb_spaghetti_print_halt = new CheckBox(parent);
|
||||
text_spaghetti_print_halt = new wxStaticText(parent, wxID_ANY, _L("Stop printing when spaghetti detected"));
|
||||
text_spaghetti_print_halt = new wxStaticText(parent, wxID_ANY, _L("Stop printing when Spaghetti or Excess Chute Pileup is detected"));
|
||||
text_spaghetti_print_halt->SetFont(Label::Body_14);
|
||||
line_sizer->Add(FromDIP(30), 0, 0, 0);
|
||||
line_sizer->Add(m_cb_spaghetti_print_halt, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
|
||||
|
|
|
@ -27,7 +27,6 @@ struct StaticBambuLib : BambuLib {
|
|||
|
||||
PrinterFileSystem::PrinterFileSystem()
|
||||
: BambuLib(StaticBambuLib::get())
|
||||
, m_recv_thread(&PrinterFileSystem::RecvMessageThread, this)
|
||||
{
|
||||
if (!default_thumbnail.IsOk())
|
||||
default_thumbnail = wxImage(Slic3r::encode_path(Slic3r::var("live_stream_default.png").c_str()));
|
||||
|
@ -41,7 +40,9 @@ PrinterFileSystem::PrinterFileSystem()
|
|||
}
|
||||
|
||||
PrinterFileSystem::~PrinterFileSystem()
|
||||
{ m_recv_thread.detach(); }
|
||||
{
|
||||
m_recv_thread.detach();
|
||||
}
|
||||
|
||||
void PrinterFileSystem::SetFileType(FileType type)
|
||||
{
|
||||
|
@ -251,6 +252,15 @@ int PrinterFileSystem::RecvData(std::function<int(Bambu_Sample& sample)> const &
|
|||
return result;
|
||||
}
|
||||
|
||||
void PrinterFileSystem::Attached()
|
||||
{
|
||||
boost::unique_lock lock(m_mutex);
|
||||
m_recv_thread = std::move(boost::thread([w = weak_from_this()] {
|
||||
boost::shared_ptr<PrinterFileSystem> s = w.lock();
|
||||
if (s) s->RecvMessageThread();
|
||||
}));
|
||||
}
|
||||
|
||||
void PrinterFileSystem::Start()
|
||||
{
|
||||
boost::unique_lock l(m_mutex);
|
||||
|
@ -277,8 +287,6 @@ void PrinterFileSystem::Stop(bool quit)
|
|||
boost::unique_lock l(m_mutex);
|
||||
if (quit) {
|
||||
m_session.owner = nullptr;
|
||||
// let the thread delete this
|
||||
m_callbacks.push_back([thiz = shared_from_this()](int result, json const &, unsigned char const *) { (void) thiz; });
|
||||
} else if (m_stopped) {
|
||||
return;
|
||||
}
|
||||
|
@ -490,6 +498,8 @@ size_t PrinterFileSystem::FindFile(size_t index, std::string const &name)
|
|||
void PrinterFileSystem::FileRemoved(size_t index, std::string const &name)
|
||||
{
|
||||
index = FindFile(index, name);
|
||||
if (index == size_t(-1))
|
||||
return;
|
||||
auto removeFromGroup = [](std::vector<size_t> &group, size_t index, int total) {
|
||||
for (auto iter = group.begin(); iter != group.end(); ++iter) {
|
||||
size_t index2 = -1;
|
||||
|
@ -622,7 +632,7 @@ void PrinterFileSystem::RecvMessageThread()
|
|||
if (m_stopped && (m_session.owner == nullptr || (m_messages.empty() && m_callbacks.empty()))) {
|
||||
Reconnect(l, 0); // Close and wait start again
|
||||
if (m_session.owner == nullptr) {
|
||||
// clear callbacks may invoke destructor, so clear first
|
||||
// clear callbacks first
|
||||
auto callbacks(std::move(m_callbacks));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -149,6 +149,8 @@ public:
|
|||
Status GetStatus() const { return m_status; }
|
||||
int GetLastError() const { return m_last_error; }
|
||||
|
||||
void Attached();
|
||||
|
||||
void Start();
|
||||
|
||||
void Retry();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Widgets/ProgressDialog.hpp"
|
||||
#include "Widgets/RoundedRectangle.hpp"
|
||||
#include "Widgets/StaticBox.hpp"
|
||||
#include "Widgets/WebView.hpp"
|
||||
|
||||
#include <wx/progdlg.h>
|
||||
#include <wx/clipbrd.h>
|
||||
|
@ -129,11 +130,25 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
|
|||
|
||||
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
|
||||
|
||||
m_scrollwindw_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)), wxVSCROLL);
|
||||
m_scrollwindw_release_note->SetScrollRate(5, 5);
|
||||
//webview
|
||||
m_scrollwindw_release_note = CreateTipView(this);
|
||||
m_scrollwindw_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||
m_scrollwindw_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
m_scrollwindw_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
m_scrollwindw_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
|
||||
fs::path ph(data_dir());
|
||||
ph /= "resources/tooltip/common/releasenote.html";
|
||||
if (!fs::exists(ph)) {
|
||||
ph = resources_dir();
|
||||
ph /= "tooltip/releasenote.html";
|
||||
}
|
||||
auto url = ph.string();
|
||||
std::replace(url.begin(), url.end(), '\\', '/');
|
||||
url = "file:///" + url;
|
||||
m_scrollwindw_release_note->LoadURL(from_u8(url));
|
||||
|
||||
|
||||
m_remind_choice = new wxCheckBox( this, wxID_ANY, _L("Don't remind me of this version again"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_remind_choice->SetValue(false);
|
||||
m_remind_choice->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &UpdateVersionDialog::alter_choice,this);
|
||||
|
@ -194,21 +209,95 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
|
|||
|
||||
UpdateVersionDialog::~UpdateVersionDialog() {}
|
||||
|
||||
wxWebView* UpdateVersionDialog::CreateTipView(wxWindow* parent)
|
||||
{
|
||||
wxWebView* tipView = WebView::CreateWebView(parent, "");
|
||||
tipView->Bind(wxEVT_WEBVIEW_LOADED, &UpdateVersionDialog::OnLoaded, this);
|
||||
tipView->Bind(wxEVT_WEBVIEW_NAVIGATED, &UpdateVersionDialog::OnTitleChanged, this);
|
||||
tipView->Bind(wxEVT_WEBVIEW_ERROR, &UpdateVersionDialog::OnError, this);
|
||||
return tipView;
|
||||
}
|
||||
|
||||
void UpdateVersionDialog::OnLoaded(wxWebViewEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void UpdateVersionDialog::OnTitleChanged(wxWebViewEvent& event)
|
||||
{
|
||||
//ShowReleaseNote();
|
||||
event.Skip();
|
||||
}
|
||||
void UpdateVersionDialog::OnError(wxWebViewEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
static std::string url_encode(const std::string& value) {
|
||||
std::ostringstream escaped;
|
||||
escaped.fill('0');
|
||||
escaped << std::hex;
|
||||
for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
|
||||
std::string::value_type c = (*i);
|
||||
|
||||
// Keep alphanumeric and other accepted characters intact
|
||||
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
escaped << c;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Any other characters are percent-encoded
|
||||
escaped << std::uppercase;
|
||||
escaped << '%' << std::setw(2) << int((unsigned char)c);
|
||||
escaped << std::nouppercase;
|
||||
}
|
||||
return escaped.str();
|
||||
}
|
||||
|
||||
bool UpdateVersionDialog::ShowReleaseNote(std::string content)
|
||||
{
|
||||
auto script = "window.showMarkdown('" + url_encode(content) + "', true);";
|
||||
RunScript(script);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateVersionDialog::RunScript(std::string script)
|
||||
{
|
||||
WebView::RunScript(m_scrollwindw_release_note, script);
|
||||
script.clear();
|
||||
}
|
||||
|
||||
void UpdateVersionDialog::on_dpi_changed(const wxRect &suggested_rect) {
|
||||
m_button_ok->Rescale();
|
||||
m_button_cancel->Rescale();
|
||||
}
|
||||
|
||||
void UpdateVersionDialog::update_version_info(wxString release_note, wxString version)
|
||||
void UpdateVersionDialog::update_version_info(std::string url)
|
||||
{
|
||||
m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version));
|
||||
/*m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version));
|
||||
wxBoxSizer *sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_staticText_release_note = new wxStaticText(m_scrollwindw_release_note, wxID_ANY, release_note, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_staticText_release_note->Wrap(FromDIP(530));
|
||||
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5);
|
||||
m_scrollwindw_release_note->SetSizer(sizer_text_release_note);
|
||||
m_scrollwindw_release_note->Layout();
|
||||
m_scrollwindw_release_note->Layout();*/
|
||||
|
||||
if (url.empty()) {
|
||||
fs::path ph(data_dir());
|
||||
ph /= "resources/tooltip/common/releasenote.html";
|
||||
if (!fs::exists(ph)) {
|
||||
ph = resources_dir();
|
||||
ph /= "tooltip/releasenote.html";
|
||||
}
|
||||
auto url = ph.string();
|
||||
std::replace(url.begin(), url.end(), '\\', '/');
|
||||
url = "file:///" + url;
|
||||
m_scrollwindw_release_note->LoadURL(from_u8(url));
|
||||
}
|
||||
else {
|
||||
m_scrollwindw_release_note->LoadURL(from_u8(url));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "Widgets/ComboBox.hpp"
|
||||
#include "Widgets/ScrolledWindow.hpp"
|
||||
#include <wx/hashmap.h>
|
||||
#include <wx/webview.h>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
@ -55,12 +56,18 @@ public:
|
|||
UpdateVersionDialog(wxWindow *parent = nullptr);
|
||||
~UpdateVersionDialog();
|
||||
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
void update_version_info(wxString release_note, wxString version);
|
||||
wxWebView* CreateTipView(wxWindow* parent);
|
||||
void OnLoaded(wxWebViewEvent& event);
|
||||
void OnTitleChanged(wxWebViewEvent& event);
|
||||
void OnError(wxWebViewEvent& event);
|
||||
bool ShowReleaseNote(std::string content);
|
||||
void RunScript(std::string script);
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
void update_version_info(std::string url);
|
||||
void alter_choice(wxCommandEvent& event);
|
||||
|
||||
wxStaticText * m_text_up_info{nullptr};
|
||||
wxScrolledWindow *m_scrollwindw_release_note{nullptr};
|
||||
wxWebView* m_scrollwindw_release_note{nullptr};
|
||||
wxBoxSizer * sizer_text_release_note{nullptr};
|
||||
wxStaticText * m_staticText_release_note{nullptr};
|
||||
wxCheckBox* m_remind_choice;
|
||||
|
|
|
@ -387,6 +387,7 @@ std::string RemovableDriveManager::get_removable_drive_from_path(const std::stri
|
|||
|
||||
void RemovableDriveManager::init(wxEvtHandler *callback_evt_handler)
|
||||
{
|
||||
//no need use assert
|
||||
assert(! m_initialized);
|
||||
assert(m_callback_evt_handler == nullptr);
|
||||
|
||||
|
@ -442,7 +443,14 @@ bool RemovableDriveManager::set_and_verify_last_save_path(const std::string &pat
|
|||
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||
this->update();
|
||||
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||
|
||||
#ifdef __APPLE__
|
||||
m_last_save_path = path;
|
||||
#else
|
||||
m_last_save_path = this->get_removable_drive_from_path(path);
|
||||
#endif
|
||||
|
||||
|
||||
m_exporting_finished = false;
|
||||
return ! m_last_save_path.empty();
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
RemovableDriveManager() = default;
|
||||
RemovableDriveManager(RemovableDriveManager const&) = delete;
|
||||
void operator=(RemovableDriveManager const&) = delete;
|
||||
~RemovableDriveManager() { assert(! m_initialized); }
|
||||
~RemovableDriveManager() { /*assert(! m_initialized);*/ }
|
||||
|
||||
// Start the background thread and register this window as a target for update events.
|
||||
// Register for OSX notifications.
|
||||
|
|
|
@ -1927,7 +1927,7 @@ void SelectMachineDialog::on_selection_changed(wxCommandEvent &event)
|
|||
|
||||
void SelectMachineDialog::update_ams_check(MachineObject* obj)
|
||||
{
|
||||
if (obj && obj->ams_support_use_ams) {
|
||||
if (obj && obj->ams_support_use_ams && obj->has_ams()) {
|
||||
select_use_ams->Show();
|
||||
} else {
|
||||
select_use_ams->Hide();
|
||||
|
@ -1991,6 +1991,18 @@ void SelectMachineDialog::update_show_status()
|
|||
reset_timeout();
|
||||
update_ams_check(obj_);
|
||||
|
||||
// do ams mapping if no ams result
|
||||
if (obj_->has_ams() && m_ams_mapping_result.empty()) {
|
||||
if (obj_->ams_support_use_ams) {
|
||||
if (ams_check->GetValue()) {
|
||||
do_ams_mapping(obj_);
|
||||
} else {
|
||||
m_ams_mapping_result.clear();
|
||||
sync_ams_mapping_result(m_ams_mapping_result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reading done
|
||||
if (obj_->is_in_upgrading()) {
|
||||
show_status(PrintDialogStatus::PrintStatusInUpgrading);
|
||||
|
@ -2214,7 +2226,9 @@ void SelectMachineDialog::set_default()
|
|||
}
|
||||
|
||||
// material info
|
||||
auto extruders = m_plater->get_partplate_list().get_curr_plate()->get_extruders();
|
||||
|
||||
//auto extruders1 = m_plater->get_partplate_list().get_curr_plate()->get_extruders();
|
||||
auto extruders = wxGetApp().plater()->get_preview_canvas3D()->get_gcode_viewer().get_plater_extruder();
|
||||
BitmapCache bmcache;
|
||||
|
||||
MaterialHash::iterator iter = m_materialList.begin();
|
||||
|
|
|
@ -450,6 +450,20 @@ void Selection::clone(int numbers)
|
|||
}
|
||||
}
|
||||
|
||||
void Selection::center()
|
||||
{
|
||||
PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_selected_plate();
|
||||
|
||||
// calc distance
|
||||
Vec3d src_pos = this->get_bounding_box().center();
|
||||
Vec3d tar_pos = plate->get_center_origin();
|
||||
Vec3d distance = Vec3d(tar_pos.x() - src_pos.x(), tar_pos.y() - src_pos.y(), 0);
|
||||
|
||||
this->move_to_center(distance);
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->do_move(L("Move Object"));
|
||||
return;
|
||||
}
|
||||
|
||||
//BBS
|
||||
void Selection::set_printable(bool printable)
|
||||
{
|
||||
|
@ -806,6 +820,39 @@ void Selection::start_dragging()
|
|||
set_caches();
|
||||
}
|
||||
|
||||
void Selection::move_to_center(const Vec3d& displacement, bool local)
|
||||
{
|
||||
if (!m_valid)
|
||||
return;
|
||||
|
||||
EMode translation_type = m_mode;
|
||||
//BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": %1%, displacement {%2%, %3%, %4%}") % __LINE__ % displacement(X) % displacement(Y) % displacement(Z);
|
||||
|
||||
set_caches();
|
||||
for (unsigned int i : m_list) {
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
if (m_mode == Volume) {
|
||||
if (local)
|
||||
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement);
|
||||
else {
|
||||
const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||
}
|
||||
}
|
||||
else if (m_mode == Instance) {
|
||||
if (is_from_fully_selected_instance(i)) {
|
||||
v.set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
|
||||
}
|
||||
else {
|
||||
const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||
translation_type = Volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->set_bounding_boxes_dirty();
|
||||
}
|
||||
|
||||
void Selection::translate(const Vec3d& displacement, bool local)
|
||||
{
|
||||
if (!m_valid)
|
||||
|
@ -2619,6 +2666,7 @@ void Selection::paste_objects_from_clipboard()
|
|||
|
||||
//BBS: if multiple objects are selected, move them as a whole after copy
|
||||
Vec2d shift_all = {0, 0};
|
||||
Vec2f empty_cell_all = {0, 0};
|
||||
if (src_objects.size() > 1) {
|
||||
BoundingBoxf3 bbox_all;
|
||||
for (const ModelObject *src_object : src_objects) {
|
||||
|
@ -2632,25 +2680,27 @@ void Selection::paste_objects_from_clipboard()
|
|||
shift_all = {0, bbox_all.size().y()};
|
||||
}
|
||||
|
||||
for (const ModelObject* src_object : src_objects)
|
||||
for (size_t i=0;i<src_objects.size();i++)
|
||||
{
|
||||
const ModelObject *src_object = src_objects[i];
|
||||
ModelObject* dst_object = m_model->add_object(*src_object);
|
||||
|
||||
// BBS: find an empty cell to put the copied object
|
||||
BoundingBoxf3 bbox = src_object->instance_convex_hull_bounding_box(0);
|
||||
|
||||
Vec3d displacement;
|
||||
bool in_current = plate->intersects(bbox);
|
||||
auto start_point = in_current ? bbox.center() : plate->get_build_volume().center();
|
||||
if (shift_all(0) != 0 || shift_all(1) != 0) {
|
||||
// BBS: if multiple objects are selected, move them as a whole after copy
|
||||
auto start_point = bbox.center();
|
||||
displacement = {shift_all.x() + start_point.x(), shift_all.y() + start_point.y(), start_point(2)};
|
||||
if (i == 0) empty_cell_all = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}, {bbox.size()(0)+1,bbox.size()(1)+1});
|
||||
auto instance_shift = src_object->instances.front()->get_offset() - src_objects[0]->instances.front()->get_offset();
|
||||
displacement = {shift_all.x() + empty_cell_all.x()+instance_shift.x(), shift_all.y() + empty_cell_all.y()+instance_shift.y(), start_point(2)};
|
||||
} else {
|
||||
// BBS: if only one object is copied, find an empty cell to put it
|
||||
bool in_current = plate->intersects(bbox);
|
||||
auto start_point = in_current ? bbox.center() : plate->get_build_volume().center();
|
||||
auto start_offset = in_current ? src_object->instances.front()->get_offset() : plate->get_build_volume().center();
|
||||
auto point_offset = start_offset - start_point;
|
||||
auto empty_cell = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)});
|
||||
auto empty_cell = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}, {bbox.size()(0)+1, bbox.size()(1)+1});
|
||||
displacement = {empty_cell.x() + point_offset.x(), empty_cell.y() + point_offset.y(), start_point(2)};
|
||||
}
|
||||
|
||||
|
|
|
@ -262,6 +262,7 @@ public:
|
|||
void add_curr_plate();
|
||||
void remove_curr_plate();
|
||||
void clone(int numbers = 1);
|
||||
void center();
|
||||
void set_printable(bool printable);
|
||||
|
||||
void add_all();
|
||||
|
@ -330,6 +331,7 @@ public:
|
|||
bool is_dragging() const { return m_dragging; }
|
||||
|
||||
void translate(const Vec3d& displacement, bool local = false);
|
||||
void move_to_center(const Vec3d& displacement, bool local = false);
|
||||
void rotate(const Vec3d& rotation, TransformationType transformation_type);
|
||||
void flattening_rotate(const Vec3d& normal);
|
||||
void scale(const Vec3d& scale, TransformationType transformation_type);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "slic3r/Utils/Http.hpp"
|
||||
#include "libslic3r/Thread.hpp"
|
||||
#include "RecenterDialog.hpp"
|
||||
#include "ConfirmHintDialog.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
@ -44,7 +45,7 @@ static const wxColour GROUP_STATIC_LINE_COL = wxColour(206, 206, 206);
|
|||
|
||||
/* font and foreground colors */
|
||||
static const wxFont PAGE_TITLE_FONT = Label::Body_14;
|
||||
static const wxFont GROUP_TITLE_FONT = Label::sysFont(17);
|
||||
//static const wxFont GROUP_TITLE_FONT = Label::sysFont(17);
|
||||
|
||||
static wxColour PAGE_TITLE_FONT_COL = wxColour(107, 107, 107);
|
||||
static wxColour GROUP_TITLE_FONT_COL = wxColour(172, 172, 172);
|
||||
|
@ -1176,7 +1177,7 @@ void StatusPanel::create_tasklist_info()
|
|||
m_tasklist_caption_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_text_tasklist_caption = new wxStaticText(this, wxID_ANY, _L("Printing List"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_text_tasklist_caption->Wrap(-1);
|
||||
m_text_tasklist_caption->SetFont(GROUP_TITLE_FONT);
|
||||
m_text_tasklist_caption->SetFont(Label::Body_16);
|
||||
m_text_tasklist_caption->SetForegroundColour(GROUP_TITLE_FONT_COL);
|
||||
|
||||
m_tasklist_caption_sizer->Add(m_text_tasklist_caption, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, GROUP_TITLE_LEFT_MARGIN);
|
||||
|
@ -1222,7 +1223,13 @@ void StatusPanel::on_subtask_pause_resume(wxCommandEvent &event)
|
|||
|
||||
void StatusPanel::on_subtask_abort(wxCommandEvent &event)
|
||||
{
|
||||
if (obj) obj->command_task_abort();
|
||||
ConfirmHintDialog* abort_dlg = new ConfirmHintDialog(this, wxID_ANY, _L("Cancel print"));
|
||||
abort_dlg->SetHint(_L("Are you sure you want to cancel this print?"));
|
||||
abort_dlg->Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
|
||||
if (obj) obj->command_task_abort();
|
||||
});
|
||||
if(abort_dlg->ShowModal())
|
||||
delete abort_dlg;
|
||||
}
|
||||
|
||||
void StatusPanel::error_info_reset()
|
||||
|
|
|
@ -218,7 +218,7 @@ void Tab::create_preset_tab()
|
|||
restore_last_select_item();
|
||||
});
|
||||
|
||||
add_scaled_button(panel, &m_btn_compare_preset, "compare");
|
||||
//add_scaled_button(panel, &m_btn_compare_preset, "compare");
|
||||
add_scaled_button(m_top_panel, &m_btn_save_preset, "save");
|
||||
add_scaled_button(m_top_panel, &m_btn_delete_preset, "cross");
|
||||
//if (m_type == Preset::Type::TYPE_PRINTER)
|
||||
|
@ -230,9 +230,9 @@ void Tab::create_preset_tab()
|
|||
|
||||
//add_scaled_button(panel, &m_btn_hide_incompatible_presets, m_bmp_hide_incompatible_presets.name());
|
||||
|
||||
m_btn_compare_preset->SetToolTip(_L("Compare presets"));
|
||||
//m_btn_compare_preset->SetToolTip(_L("Compare presets"));
|
||||
// TRN "Save current Settings"
|
||||
m_btn_save_preset->SetToolTip(from_u8((boost::format(_utf8(L("Save current %s"))) % m_title).str()));
|
||||
m_btn_save_preset->SetToolTip(wxString::Format(_L("Save current %s"), m_title));
|
||||
m_btn_delete_preset->SetToolTip(_(L("Delete this preset")));
|
||||
m_btn_delete_preset->Hide();
|
||||
|
||||
|
@ -256,6 +256,7 @@ void Tab::create_preset_tab()
|
|||
add_scaled_button(m_top_panel, &m_undo_btn, m_bmp_white_bullet.name());
|
||||
add_scaled_button(m_top_panel, &m_undo_to_sys_btn, m_bmp_white_bullet.name());
|
||||
add_scaled_button(m_top_panel, &m_btn_search, "search");
|
||||
m_btn_search->SetToolTip(_L("Search in preset"));
|
||||
|
||||
//search input
|
||||
m_search_item = new RoundedRectangle(m_top_panel, wxColour(238, 238, 238), wxDefaultPosition, wxSize(m_top_panel->GetSize().GetWidth(), 3 * wxGetApp().em_unit()), 8);
|
||||
|
@ -268,7 +269,8 @@ void Tab::create_preset_tab()
|
|||
|
||||
search_sizer->Add(new wxWindow(m_search_item, wxID_ANY, wxDefaultPosition, wxSize(0, 0)), 0, wxEXPAND | wxLEFT, 16);
|
||||
search_sizer->Add(m_search_input, 1, wxEXPAND | wxALL, wxGetApp().em_unit() / 2);
|
||||
search_sizer->Add(new wxWindow(m_search_input, wxID_ANY, wxDefaultPosition, wxSize(0, 0)), 0, wxEXPAND | wxLEFT, 16);
|
||||
//bbl for linux
|
||||
//search_sizer->Add(new wxWindow(m_search_input, wxID_ANY, wxDefaultPosition, wxSize(0, 0)), 0, wxEXPAND | wxLEFT, 16);
|
||||
|
||||
|
||||
m_search_item->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
|
||||
|
@ -494,7 +496,7 @@ void Tab::create_preset_tab()
|
|||
m_page_view->SetScrollbars(1, 20, 1, 2);
|
||||
m_hsizer->Add(m_page_view, 1, wxEXPAND | wxLEFT, 5);*/
|
||||
|
||||
m_btn_compare_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { compare_preset(); }));
|
||||
//m_btn_compare_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { compare_preset(); }));
|
||||
m_btn_save_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { save_preset(); }));
|
||||
m_btn_delete_preset->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) { delete_preset(); }));
|
||||
/*m_btn_hide_incompatible_presets->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) {
|
||||
|
@ -994,7 +996,7 @@ void Tab::update_undo_buttons()
|
|||
m_undo_btn-> SetBitmap_(m_presets->get_edited_preset().is_dirty ? m_bmp_value_revert: m_bmp_white_bullet);
|
||||
m_undo_to_sys_btn-> SetBitmap_(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock);
|
||||
|
||||
m_undo_btn->SetToolTip(m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet);
|
||||
m_undo_btn->SetToolTip(m_presets->get_edited_preset().is_dirty ? _L("Click to reset all settings to the last saved preset.") : m_ttg_white_bullet);
|
||||
m_undo_to_sys_btn->SetToolTip(m_is_nonsys_values ? *m_ttg_non_system : m_ttg_value_lock);
|
||||
}
|
||||
|
||||
|
@ -1747,12 +1749,12 @@ void TabPrint::build()
|
|||
load_initial_data();
|
||||
|
||||
auto page = add_options_page(L("Quality"), "empty");
|
||||
auto optgroup = page->new_optgroup(L("Layer height"));
|
||||
auto optgroup = page->new_optgroup(L("Layer height"), L"param_layer_height");
|
||||
optgroup->append_single_option_line("layer_height");
|
||||
optgroup->append_single_option_line("initial_layer_print_height");
|
||||
optgroup->append_single_option_line("adaptive_layer_height", "adaptive-layer-height");
|
||||
|
||||
optgroup = page->new_optgroup(L("Line width"));
|
||||
optgroup = page->new_optgroup(L("Line width"), L"param_line_width");
|
||||
optgroup->append_single_option_line("line_width");
|
||||
optgroup->append_single_option_line("initial_layer_line_width");
|
||||
optgroup->append_single_option_line("outer_wall_line_width");
|
||||
|
@ -1762,10 +1764,10 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("internal_solid_infill_line_width");
|
||||
optgroup->append_single_option_line("support_line_width");
|
||||
|
||||
optgroup = page->new_optgroup(L("Seam"));
|
||||
optgroup = page->new_optgroup(L("Seam"), L"param_seam");
|
||||
optgroup->append_single_option_line("seam_position", "Seam");
|
||||
|
||||
optgroup = page->new_optgroup(L("Precision"));
|
||||
optgroup = page->new_optgroup(L("Precision"), L"param_precision");
|
||||
optgroup->append_single_option_line("slice_closing_radius");
|
||||
optgroup->append_single_option_line("resolution");
|
||||
optgroup->append_single_option_line("enable_arc_fitting");
|
||||
|
@ -1773,17 +1775,18 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("xy_contour_compensation");
|
||||
optgroup->append_single_option_line("elefant_foot_compensation");
|
||||
|
||||
optgroup = page->new_optgroup(L("Ironing"));
|
||||
optgroup = page->new_optgroup(L("Ironing"), L"param_ironing");
|
||||
optgroup->append_single_option_line("ironing_type");
|
||||
optgroup->append_single_option_line("ironing_speed");
|
||||
optgroup->append_single_option_line("ironing_flow");
|
||||
optgroup->append_single_option_line("ironing_spacing");
|
||||
|
||||
optgroup = page->new_optgroup(L("Advanced"));
|
||||
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
|
||||
optgroup->append_single_option_line("wall_infill_order");
|
||||
optgroup->append_single_option_line("bridge_flow");
|
||||
optgroup->append_single_option_line("top_solid_infill_flow_ratio");
|
||||
optgroup->append_single_option_line("bottom_solid_infill_flow_ratio");
|
||||
optgroup->append_single_option_line("thick_bridges");
|
||||
optgroup->append_single_option_line("only_one_wall_top");
|
||||
optgroup->append_single_option_line("only_one_wall_first_layer");
|
||||
optgroup->append_single_option_line("detect_overhang_wall");
|
||||
|
@ -1791,23 +1794,23 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("max_travel_detour_distance");
|
||||
|
||||
page = add_options_page(L("Strength"), "empty");
|
||||
optgroup = page->new_optgroup(L("Walls"));
|
||||
optgroup = page->new_optgroup(L("Walls"), L"param_wall");
|
||||
optgroup->append_single_option_line("wall_loops");
|
||||
optgroup->append_single_option_line("detect_thin_wall");
|
||||
|
||||
optgroup = page->new_optgroup(L("Top/bottom shells"));
|
||||
optgroup = page->new_optgroup(L("Top/bottom shells"), L"param_shell");
|
||||
optgroup->append_single_option_line("top_shell_layers");
|
||||
optgroup->append_single_option_line("top_shell_thickness");
|
||||
optgroup->append_single_option_line("bottom_shell_layers");
|
||||
optgroup->append_single_option_line("bottom_shell_thickness");
|
||||
|
||||
optgroup = page->new_optgroup(L("Infill"));
|
||||
optgroup = page->new_optgroup(L("Infill"), L"param_infill");
|
||||
optgroup->append_single_option_line("sparse_infill_density");
|
||||
optgroup->append_single_option_line("sparse_infill_pattern");
|
||||
optgroup->append_single_option_line("top_surface_pattern");
|
||||
optgroup->append_single_option_line("bottom_surface_pattern");
|
||||
|
||||
optgroup = page->new_optgroup(L("Advanced"));
|
||||
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
|
||||
optgroup->append_single_option_line("infill_wall_overlap");
|
||||
optgroup->append_single_option_line("infill_direction");
|
||||
optgroup->append_single_option_line("minimum_sparse_infill_area");
|
||||
|
@ -1815,10 +1818,10 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("detect_narrow_internal_solid_infill");
|
||||
|
||||
page = add_options_page(L("Speed"), "empty");
|
||||
optgroup = page->new_optgroup(L("Initial layer speed"), 15);
|
||||
optgroup = page->new_optgroup(L("Initial layer speed"), L"param_speed_first", 15);
|
||||
optgroup->append_single_option_line("initial_layer_speed");
|
||||
optgroup->append_single_option_line("initial_layer_infill_speed");
|
||||
optgroup = page->new_optgroup(L("Other layers speed"), 15);
|
||||
optgroup = page->new_optgroup(L("Other layers speed"), L"param_speed", 15);
|
||||
optgroup->append_single_option_line("outer_wall_speed");
|
||||
optgroup->append_single_option_line("inner_wall_speed");
|
||||
optgroup->append_single_option_line("sparse_infill_speed");
|
||||
|
@ -1837,10 +1840,10 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("support_speed");
|
||||
optgroup->append_single_option_line("support_interface_speed");
|
||||
|
||||
optgroup = page->new_optgroup(L("Travel speed"), 15);
|
||||
optgroup = page->new_optgroup(L("Travel speed"), L"param_travel_speed", 15);
|
||||
optgroup->append_single_option_line("travel_speed");
|
||||
|
||||
optgroup = page->new_optgroup(L("Acceleration"), 15);
|
||||
optgroup = page->new_optgroup(L("Acceleration"), L"param_acceleration", 15);
|
||||
optgroup->append_single_option_line("default_acceleration");
|
||||
optgroup->append_single_option_line("outer_wall_acceleration");
|
||||
optgroup->append_single_option_line("inner_wall_acceleration");
|
||||
|
@ -1848,7 +1851,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("top_surface_acceleration");
|
||||
optgroup->append_single_option_line("travel_acceleration");
|
||||
|
||||
optgroup = page->new_optgroup(L("Jerk(XY)"), 15);
|
||||
optgroup = page->new_optgroup(L("Jerk(XY)"));
|
||||
optgroup->append_single_option_line("default_jerk");
|
||||
optgroup->append_single_option_line("outer_wall_jerk");
|
||||
optgroup->append_single_option_line("inner_wall_jerk");
|
||||
|
@ -1862,14 +1865,15 @@ void TabPrint::build()
|
|||
#endif /* HAS_PRESSURE_EQUALIZER */
|
||||
|
||||
page = add_options_page(L("Support"), "support");
|
||||
optgroup = page->new_optgroup(L("Support"));
|
||||
optgroup = page->new_optgroup(L("Support"), L"param_support");
|
||||
optgroup->append_single_option_line("enable_support", "support");
|
||||
optgroup->append_single_option_line("support_type", "support#support-types");
|
||||
optgroup->append_single_option_line("support_threshold_angle", "support#threshold-angle");
|
||||
optgroup->append_single_option_line("support_on_build_plate_only");
|
||||
optgroup->append_single_option_line("support_critical_regions_only");
|
||||
//optgroup->append_single_option_line("enforce_support_layers");
|
||||
|
||||
optgroup = page->new_optgroup(L("Support filament"));
|
||||
optgroup = page->new_optgroup(L("Support filament"), L"param_support_filament");
|
||||
optgroup->append_single_option_line("support_filament", "support#support-filament");
|
||||
optgroup->append_single_option_line("support_interface_filament", "support#support-filament");
|
||||
|
||||
|
@ -1877,7 +1881,7 @@ void TabPrint::build()
|
|||
//optgroup->append_single_option_line("support_style");
|
||||
|
||||
//BBS
|
||||
optgroup = page->new_optgroup(L("Advanced"));
|
||||
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
|
||||
optgroup->append_single_option_line("tree_support_branch_distance", "support#tree-support-only-options");
|
||||
optgroup->append_single_option_line("tree_support_branch_diameter", "support#tree-support-only-options");
|
||||
optgroup->append_single_option_line("tree_support_branch_angle", "support#tree-support-only-options");
|
||||
|
@ -1897,11 +1901,10 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("support_object_xy_distance", "support#supportobject-xy-distance");
|
||||
optgroup->append_single_option_line("bridge_no_support", "support#base-pattern");
|
||||
optgroup->append_single_option_line("max_bridge_length", "support#base-pattern");
|
||||
optgroup->append_single_option_line("thick_bridges", "support#base-pattern");
|
||||
//optgroup->append_single_option_line("independent_support_layer_height");
|
||||
|
||||
page = add_options_page(L("Others"), "advanced");
|
||||
optgroup = page->new_optgroup(L("Bed adhension"));
|
||||
optgroup = page->new_optgroup(L("Bed adhension"), L"param_adhension");
|
||||
optgroup->append_single_option_line("skirt_loops");
|
||||
optgroup->append_single_option_line("skirt_distance");
|
||||
//optgroup->append_single_option_line("draft_shield");
|
||||
|
@ -1912,18 +1915,18 @@ void TabPrint::build()
|
|||
//optgroup->append_single_option_line("raft_first_layer_density");
|
||||
//optgroup->append_single_option_line("raft_first_layer_expansion");
|
||||
|
||||
optgroup = page->new_optgroup(L("Prime tower"));
|
||||
optgroup = page->new_optgroup(L("Prime tower"), L"param_tower");
|
||||
optgroup->append_single_option_line("enable_prime_tower");
|
||||
optgroup->append_single_option_line("prime_tower_width");
|
||||
optgroup->append_single_option_line("prime_volume");
|
||||
optgroup->append_single_option_line("prime_tower_brim_width");
|
||||
|
||||
optgroup = page->new_optgroup(L("Flush options"));
|
||||
optgroup = page->new_optgroup(L("Flush options"), L"param_flush");
|
||||
optgroup->append_single_option_line("flush_into_infill", "reduce-wasting-during-filament-change#wipe-into-infill");
|
||||
optgroup->append_single_option_line("flush_into_objects", "reduce-wasting-during-filament-change#wipe-into-object");
|
||||
optgroup->append_single_option_line("flush_into_support", "reduce-wasting-during-filament-change#wipe-into-support-enabled-by-default");
|
||||
|
||||
optgroup = page->new_optgroup(L("Special mode"));
|
||||
optgroup = page->new_optgroup(L("Special mode"), L"param_special");
|
||||
optgroup->append_single_option_line("print_sequence");
|
||||
optgroup->append_single_option_line("spiral_mode", "spiral-vase");
|
||||
optgroup->append_single_option_line("timelapse_type", "Timelapse");
|
||||
|
@ -1945,7 +1948,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("fuzzy_skin_thickness");
|
||||
|
||||
|
||||
optgroup = page->new_optgroup(L("G-code output"));
|
||||
optgroup = page->new_optgroup(L("G-code output"), L"param_gcode");
|
||||
optgroup->append_single_option_line("reduce_infill_retraction");
|
||||
optgroup->append_single_option_line("gcode_add_line_number");
|
||||
Option option = optgroup->get_option("filename_format");
|
||||
|
@ -2336,7 +2339,7 @@ void TabFilament::add_filament_overrides_page()
|
|||
{
|
||||
//BBS
|
||||
PageShp page = add_options_page(L("Setting Overrides"), "empty");
|
||||
ConfigOptionsGroupShp optgroup = page->new_optgroup(L("Retraction"));
|
||||
ConfigOptionsGroupShp optgroup = page->new_optgroup(L("Retraction"), L"param_retraction");
|
||||
|
||||
auto append_single_option_line = [optgroup, this](const std::string& opt_key, int opt_index)
|
||||
{
|
||||
|
@ -2440,7 +2443,7 @@ void TabFilament::build()
|
|||
page->m_split_multi_line = true;
|
||||
page->m_option_label_at_right = true;
|
||||
//BBS
|
||||
auto optgroup = page->new_optgroup(L("Basic information"));
|
||||
auto optgroup = page->new_optgroup(L("Basic information"), L"param_information");
|
||||
// Set size as all another fields for a better alignment
|
||||
Option option = optgroup->get_option("filament_type");
|
||||
option.opt.width = Field::def_width();
|
||||
|
@ -2464,10 +2467,10 @@ void TabFilament::build()
|
|||
line.append_option(optgroup->get_option("nozzle_temperature_range_high"));
|
||||
optgroup->append_line(line);
|
||||
|
||||
optgroup = page->new_optgroup(L("Recommended temperature range"));
|
||||
optgroup = page->new_optgroup(L("Recommended temperature range"), L"param_temperature");
|
||||
optgroup->append_single_option_line("bed_temperature_difference");
|
||||
|
||||
optgroup = page->new_optgroup(L("Print temperature"));
|
||||
optgroup = page->new_optgroup(L("Print temperature"), L"param_temperature");
|
||||
optgroup->split_multi_line = true;
|
||||
optgroup->option_label_at_right = true;
|
||||
line = { L("Chamber temperature"), L("Chamber temperature") };
|
||||
|
@ -2527,7 +2530,7 @@ void TabFilament::build()
|
|||
};
|
||||
|
||||
//BBS
|
||||
optgroup = page->new_optgroup(L("Volumetric speed limitation"));
|
||||
optgroup = page->new_optgroup(L("Volumetric speed limitation"), L"param_volumetric_speed");
|
||||
optgroup->append_single_option_line("filament_max_volumetric_speed");
|
||||
|
||||
//line = { "", "" };
|
||||
|
@ -2545,11 +2548,11 @@ void TabFilament::build()
|
|||
// return description_line_widget(parent, &m_cooling_description_line);
|
||||
//};
|
||||
//optgroup->append_line(line);
|
||||
optgroup = page->new_optgroup(L("Cooling for specific layer"));
|
||||
optgroup = page->new_optgroup(L("Cooling for specific layer"), L"param_cooling");
|
||||
optgroup->append_single_option_line("close_fan_the_first_x_layers", "auto-cooling");
|
||||
//optgroup->append_single_option_line("full_fan_speed_layer");
|
||||
|
||||
optgroup = page->new_optgroup(L("Part cooling fan"));
|
||||
optgroup = page->new_optgroup(L("Part cooling fan"), L"param_cooling_fan");
|
||||
line = { L("Min fan speed threshold"), L("Part cooling fan speed will start to run at min speed when the estimated layer time is no longer than the layer time in setting. When layer time is shorter than threshold, fan speed is interpolated between the minimum and maximum fan speed according to layer printing time") };
|
||||
line.label_path = "auto-cooling";
|
||||
line.append_option(optgroup->get_option("fan_min_speed"));
|
||||
|
@ -2568,7 +2571,7 @@ void TabFilament::build()
|
|||
optgroup->append_single_option_line("overhang_fan_threshold", "auto-cooling");
|
||||
optgroup->append_single_option_line("overhang_fan_speed", "auto-cooling");
|
||||
|
||||
optgroup = page->new_optgroup(L("Auxiliary part cooling fan"));
|
||||
optgroup = page->new_optgroup(L("Auxiliary part cooling fan"), L"param_cooling_fan");
|
||||
optgroup->append_single_option_line("additional_cooling_fan_speed");
|
||||
|
||||
//BBS
|
||||
|
@ -2582,7 +2585,7 @@ void TabFilament::build()
|
|||
const int gcode_field_height = 15; // 150
|
||||
|
||||
page = add_options_page(L("Advanced"), "advanced");
|
||||
optgroup = page->new_optgroup(L("Filament start G-code"), 0);
|
||||
optgroup = page->new_optgroup(L("Filament start G-code"), L"param_gcode", 0);
|
||||
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
|
||||
validate_custom_gcode_cb(this, optgroup, opt_key, value);
|
||||
};
|
||||
|
@ -2592,7 +2595,7 @@ void TabFilament::build()
|
|||
option.opt.height = gcode_field_height;// 150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Filament end G-code"), 0);
|
||||
optgroup = page->new_optgroup(L("Filament end G-code"), L"param_gcode", 0);
|
||||
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
|
||||
validate_custom_gcode_cb(this, optgroup, opt_key, value);
|
||||
};
|
||||
|
@ -2766,7 +2769,7 @@ void TabPrinter::build_fff()
|
|||
static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size();
|
||||
|
||||
auto page = add_options_page(L("Basic information"), "printer");
|
||||
auto optgroup = page->new_optgroup(L("Printable space"));
|
||||
auto optgroup = page->new_optgroup(L("Printable space")/*, L"param_printable_space"*/);
|
||||
|
||||
//create_line_with_widget(optgroup.get(), "printable_area", "custom-svg-and-png-bed-textures_124612", [this](wxWindow* parent) {
|
||||
// return create_bed_shape_widget(parent);
|
||||
|
@ -2872,20 +2875,20 @@ void TabPrinter::build_fff()
|
|||
//};
|
||||
#endif
|
||||
|
||||
optgroup = page->new_optgroup(L("Advanced"));
|
||||
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
|
||||
optgroup->append_single_option_line("gcode_flavor");
|
||||
optgroup->append_single_option_line("scan_first_layer");
|
||||
// optgroup->append_single_option_line("spaghetti_detector");
|
||||
optgroup->append_single_option_line("machine_load_filament_time");
|
||||
optgroup->append_single_option_line("machine_unload_filament_time");
|
||||
|
||||
optgroup = page->new_optgroup(L("Accessory"));
|
||||
optgroup = page->new_optgroup(L("Accessory") /*, L"param_accessory"*/);
|
||||
optgroup->append_single_option_line("nozzle_type");
|
||||
optgroup->append_single_option_line("auxiliary_fan");
|
||||
|
||||
const int gcode_field_height = 15; // 150
|
||||
page = add_options_page(L("Machine gcode"), "cog");
|
||||
optgroup = page->new_optgroup(L("Machine start G-code"), 0);
|
||||
optgroup = page->new_optgroup(L("Machine start G-code"), L"param_gcode", 0);
|
||||
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
|
||||
validate_custom_gcode_cb(this, optgroup, opt_key, value);
|
||||
};
|
||||
|
@ -2895,7 +2898,7 @@ void TabPrinter::build_fff()
|
|||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Machine end G-code"), 0);
|
||||
optgroup = page->new_optgroup(L("Machine end G-code"), L"param_gcode", 0);
|
||||
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
|
||||
validate_custom_gcode_cb(this, optgroup, opt_key, value);
|
||||
};
|
||||
|
@ -2916,7 +2919,7 @@ void TabPrinter::build_fff()
|
|||
optgroup->append_single_option_line(option);
|
||||
#endif
|
||||
|
||||
optgroup = page->new_optgroup(L("Layer change G-code"), 0);
|
||||
optgroup = page->new_optgroup(L("Layer change G-code"), L"param_gcode", 0);
|
||||
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
|
||||
validate_custom_gcode_cb(this, optgroup, opt_key, value);
|
||||
};
|
||||
|
@ -2926,7 +2929,7 @@ void TabPrinter::build_fff()
|
|||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Change filament G-code"), 0);
|
||||
optgroup = page->new_optgroup(L("Change filament G-code"), L"param_gcode", 0);
|
||||
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
|
||||
validate_custom_gcode_cb(this, optgroup, opt_key, value);
|
||||
};
|
||||
|
@ -2936,7 +2939,7 @@ void TabPrinter::build_fff()
|
|||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Pause G-code"), 0);
|
||||
optgroup = page->new_optgroup(L("Pause G-code"), L"param_gcode", 0);
|
||||
optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) {
|
||||
validate_custom_gcode_cb(this, optgroup, opt_key, value);
|
||||
};
|
||||
|
@ -3087,13 +3090,13 @@ PageShp TabPrinter::build_kinematics_page()
|
|||
"machine_max_speed_z",
|
||||
"machine_max_speed_e"
|
||||
};
|
||||
auto optgroup = page->new_optgroup(L("Speed limitation"));
|
||||
auto optgroup = page->new_optgroup(L("Speed limitation"), "param_speed");
|
||||
for (const std::string &speed_axis : speed_axes) {
|
||||
append_option_line(optgroup, speed_axis);
|
||||
}
|
||||
|
||||
const std::vector<std::string> axes{ "x", "y", "z", "e" };
|
||||
optgroup = page->new_optgroup(L("Acceleration limitation"));
|
||||
optgroup = page->new_optgroup(L("Acceleration limitation"), "param_acceleration");
|
||||
for (const std::string &axis : axes) {
|
||||
append_option_line(optgroup, "machine_max_acceleration_" + axis);
|
||||
}
|
||||
|
@ -3205,7 +3208,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
|
|||
auto page = add_options_page(page_name, "empty", true);
|
||||
m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page);
|
||||
|
||||
auto optgroup = page->new_optgroup(L("Size"), -1, true);
|
||||
auto optgroup = page->new_optgroup(L("Size"), L"param_diameter", -1, true);
|
||||
optgroup->append_single_option_line("nozzle_diameter", "", extruder_idx);
|
||||
|
||||
optgroup->m_on_change = [this, extruder_idx](const t_config_option_key& opt_key, boost::any value)
|
||||
|
@ -3244,15 +3247,15 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
|
|||
update();
|
||||
};
|
||||
|
||||
optgroup = page->new_optgroup(L("Layer height limits"), -1, true);
|
||||
optgroup = page->new_optgroup(L("Layer height limits"), L"param_layer_height", -1, true);
|
||||
optgroup->append_single_option_line("min_layer_height", "", extruder_idx);
|
||||
optgroup->append_single_option_line("max_layer_height", "", extruder_idx);
|
||||
|
||||
optgroup = page->new_optgroup(L("Position"), -1, true);
|
||||
optgroup = page->new_optgroup(L("Position"), L"param_retraction", -1, true);
|
||||
optgroup->append_single_option_line("extruder_offset", "", extruder_idx);
|
||||
|
||||
//BBS: don't show retract related config menu in machine page
|
||||
optgroup = page->new_optgroup(L("Retraction"));
|
||||
optgroup = page->new_optgroup(L("Retraction"), L"param_retraction");
|
||||
optgroup->append_single_option_line("retraction_length", "", extruder_idx);
|
||||
optgroup->append_single_option_line("z_hop", "", extruder_idx);
|
||||
optgroup->append_single_option_line("retraction_speed", "", extruder_idx);
|
||||
|
@ -3264,7 +3267,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
|
|||
optgroup->append_single_option_line("wipe_distance", "", extruder_idx);
|
||||
optgroup->append_single_option_line("retract_before_wipe", "", extruder_idx);
|
||||
|
||||
optgroup = page->new_optgroup(L("Retraction when switching material"), -1, true);
|
||||
optgroup = page->new_optgroup(L("Retraction when switching material"), L"param_retraction", -1, true);
|
||||
optgroup->append_single_option_line("retract_length_toolchange", "", extruder_idx);
|
||||
optgroup->append_single_option_line("retract_restart_extra_toolchange", "", extruder_idx);
|
||||
|
||||
|
@ -4885,11 +4888,11 @@ bool Page::set_value(const t_config_option_key &opt_key, const boost::any &value
|
|||
}
|
||||
|
||||
// package Slic3r::GUI::Tab::Page;
|
||||
ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_label_width /*= -1*/, bool is_extruder_og /* false */)
|
||||
ConfigOptionsGroupShp Page::new_optgroup(const wxString &title, const wxString &icon, int noncommon_label_width /*= -1*/, bool is_extruder_og /* false */)
|
||||
{
|
||||
//! config_ have to be "right"
|
||||
ConfigOptionsGroupShp optgroup = is_extruder_og ? std::make_shared<ExtruderOptionsGroup>(m_parent, title, m_config, true)
|
||||
: std::make_shared<ConfigOptionsGroup>(m_parent, title, m_config, true);
|
||||
: std::make_shared<ConfigOptionsGroup>(m_parent, title, icon, m_config, true);
|
||||
optgroup->split_multi_line = this->m_split_multi_line;
|
||||
optgroup->option_label_at_right = this->m_option_label_at_right;
|
||||
if (noncommon_label_width >= 0)
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
Line * get_line(const t_config_option_key &opt_key);
|
||||
bool set_value(const t_config_option_key& opt_key, const boost::any& value);
|
||||
// BBS. Add is_extruder_og parameter.
|
||||
ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1, bool is_extruder_og = false);
|
||||
ConfigOptionsGroupShp new_optgroup(const wxString& title, const wxString& icon = wxEmptyString, int noncommon_label_width = -1, bool is_extruder_og = false);
|
||||
const ConfigOptionsGroupShp get_optgroup(const wxString& title) const;
|
||||
|
||||
bool set_item_colour(const wxColour *clr) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "GUI_App.hpp"
|
||||
#include "libslic3r/Thread.hpp"
|
||||
#include "ReleaseNote.hpp"
|
||||
#include "ConfirmHintDialog.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
@ -12,6 +13,10 @@ namespace GUI {
|
|||
static const wxColour TEXT_NORMAL_CLR = wxColour(0, 174, 66);
|
||||
static const wxColour TEXT_FAILED_CLR = wxColour(255, 111, 0);
|
||||
|
||||
wxString normal_upgrade_hint = _L("Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating.");
|
||||
wxString force_upgrade_hint = _L("An important update was detected and needs to be run before printing can continue. Do you want to update now? You can also update later from 'Upgrade firmware'.");
|
||||
wxString consistency_upgrade_hint = _L("The firmware version is abnormal. Repairing and updating are required before printing. Do you want to update now? You can also update later on printer or update next time starting the studio.");
|
||||
|
||||
MachineInfoPanel::MachineInfoPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
|
||||
:wxPanel(parent, id, pos, size, style)
|
||||
{
|
||||
|
@ -312,7 +317,6 @@ void MachineInfoPanel::update(MachineObject* obj)
|
|||
m_staticText_upgrading_percent->SetLabelText(wxString::Format("%d%%", upgrade_percent));
|
||||
} else if (obj->upgrade_display_state == (int) MachineObject::UpgradingDisplayState::UpgradingFinished) {
|
||||
wxString result_text = obj->get_upgrade_result_str(obj->upgrade_err_code);
|
||||
m_staticText_upgrading_info->SetLabelText(result_text);
|
||||
m_upgrade_progress->SetValue(upgrade_percent);
|
||||
m_staticText_upgrading_percent->SetLabelText(wxString::Format("%d%%", upgrade_percent));
|
||||
}
|
||||
|
@ -575,7 +579,7 @@ void MachineInfoPanel::show_status(int status, std::string upgrade_status_str)
|
|||
BOOST_LOG_TRIVIAL(trace) << "MachineInfoPanel: show_status = " << status << ", str = " << upgrade_status_str;
|
||||
|
||||
Freeze();
|
||||
|
||||
|
||||
if (status == (int)MachineObject::UpgradingDisplayState::UpgradingUnavaliable) {
|
||||
m_button_upgrade_firmware->Show();
|
||||
m_button_upgrade_firmware->Disable();
|
||||
|
@ -593,7 +597,7 @@ void MachineInfoPanel::show_status(int status, std::string upgrade_status_str)
|
|||
m_staticText_upgrading_info->Hide();
|
||||
m_staticText_upgrading_percent->Hide();
|
||||
} else if (status == (int) MachineObject::UpgradingDisplayState::UpgradingInProgress) {
|
||||
m_button_upgrade_firmware->Hide();
|
||||
m_button_upgrade_firmware->Disable();
|
||||
for (size_t i = 0; i < m_upgrading_sizer->GetItemCount(); i++) { m_upgrading_sizer->Show(true); }
|
||||
m_upgrade_retry_img->Hide();
|
||||
m_staticText_upgrading_info->Show();
|
||||
|
@ -606,17 +610,18 @@ void MachineInfoPanel::show_status(int status, std::string upgrade_status_str)
|
|||
m_staticText_upgrading_info->SetLabel(_L("Upgrading failed"));
|
||||
m_staticText_upgrading_info->SetForegroundColour(TEXT_FAILED_CLR);
|
||||
for (size_t i = 0; i < m_upgrading_sizer->GetItemCount(); i++) { m_upgrading_sizer->Show(true); }
|
||||
m_button_upgrade_firmware->Hide();
|
||||
m_button_upgrade_firmware->Disable();
|
||||
m_staticText_upgrading_info->Show();
|
||||
m_staticText_upgrading_percent->Hide();
|
||||
m_staticText_upgrading_percent->Show();
|
||||
m_upgrade_retry_img->Show();
|
||||
} else {
|
||||
for (size_t i = 0; i < m_upgrading_sizer->GetItemCount(); i++) { m_upgrading_sizer->Show(true); }
|
||||
m_button_upgrade_firmware->Hide();
|
||||
m_staticText_upgrading_info->SetLabel(_L("Upgrading success"));
|
||||
m_staticText_upgrading_info->SetLabel(_L("Upgrading successful"));
|
||||
m_staticText_upgrading_info->Show();
|
||||
for (size_t i = 0; i < m_upgrading_sizer->GetItemCount(); i++) { m_upgrading_sizer->Show(true); }
|
||||
m_button_upgrade_firmware->Disable();
|
||||
m_staticText_upgrading_info->SetForegroundColour(TEXT_NORMAL_CLR);
|
||||
m_staticText_upgrading_percent->SetForegroundColour(TEXT_NORMAL_CLR);
|
||||
m_staticText_upgrading_percent->Show();
|
||||
m_upgrade_retry_img->Hide();
|
||||
}
|
||||
} else {
|
||||
|
@ -652,8 +657,28 @@ void MachineInfoPanel::upgrade_firmware_internal() {
|
|||
|
||||
void MachineInfoPanel::on_upgrade_firmware(wxCommandEvent &event)
|
||||
{
|
||||
if (m_obj)
|
||||
m_obj->command_upgrade_confirm();
|
||||
ConfirmHintDialog* confirm_dlg = new ConfirmHintDialog(this->GetParent(), wxID_ANY, _L("Upgrade firmware"));
|
||||
confirm_dlg->SetHint(normal_upgrade_hint);
|
||||
confirm_dlg->Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
|
||||
if (m_obj){
|
||||
m_obj->command_upgrade_confirm();
|
||||
}
|
||||
});
|
||||
if(confirm_dlg->ShowModal())
|
||||
delete confirm_dlg;
|
||||
}
|
||||
|
||||
void MachineInfoPanel::on_consisitency_upgrade_firmware(wxCommandEvent &event)
|
||||
{
|
||||
ConfirmHintDialog* confirm_dlg = new ConfirmHintDialog(this->GetParent(), wxID_ANY, _L("Upgrade firmware"));
|
||||
confirm_dlg->SetHint(normal_upgrade_hint);
|
||||
confirm_dlg->Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
|
||||
if (m_obj){
|
||||
m_obj->command_consistency_upgrade_confirm();
|
||||
}
|
||||
});
|
||||
if(confirm_dlg->ShowModal())
|
||||
delete confirm_dlg;
|
||||
}
|
||||
|
||||
void MachineInfoPanel::on_show_release_note(wxMouseEvent &event)
|
||||
|
@ -759,6 +784,39 @@ void UpgradePanel::update(MachineObject *obj)
|
|||
}
|
||||
}
|
||||
|
||||
//force upgrade
|
||||
//unlock hint
|
||||
if (m_obj && (m_obj->upgrade_display_state == (int) MachineObject::UpgradingDisplayState::UpgradingFinished) && (last_forced_hint_status != m_obj->upgrade_display_state)) {
|
||||
last_forced_hint_status = m_obj->upgrade_display_state;
|
||||
m_show_forced_hint = true;
|
||||
}
|
||||
if (m_obj && m_show_forced_hint) {
|
||||
if (m_obj->upgrade_force_upgrade) {
|
||||
m_show_forced_hint = false; //lock hint
|
||||
ConfirmHintDialog* force_dlg = new ConfirmHintDialog(m_scrolledWindow, wxID_ANY, _L("Upgrade firmware"));
|
||||
force_dlg->SetHint(force_upgrade_hint);
|
||||
force_dlg->Bind(EVT_CONFIRM_HINT, &MachineInfoPanel::on_upgrade_firmware, m_push_upgrade_panel);
|
||||
if (force_dlg->ShowModal())
|
||||
delete force_dlg;
|
||||
}
|
||||
}
|
||||
|
||||
//consistency upgrade
|
||||
if (m_obj && (m_obj->upgrade_display_state == (int) MachineObject::UpgradingDisplayState::UpgradingFinished) && (last_consistency_hint_status != m_obj->upgrade_display_state)) {
|
||||
last_consistency_hint_status = m_obj->upgrade_display_state;
|
||||
m_show_consistency_hint = true;
|
||||
}
|
||||
if (m_obj && m_show_consistency_hint) {
|
||||
if (m_obj->upgrade_consistency_request) {
|
||||
m_show_consistency_hint = false;
|
||||
ConfirmHintDialog* consistency_dlg = new ConfirmHintDialog(m_scrolledWindow, wxID_ANY, _L("Upgrade firmware"));
|
||||
consistency_dlg->SetHint(consistency_upgrade_hint);
|
||||
consistency_dlg->Bind(EVT_CONFIRM_HINT, &MachineInfoPanel::on_consisitency_upgrade_firmware, m_push_upgrade_panel);
|
||||
if (consistency_dlg->ShowModal())
|
||||
delete consistency_dlg;
|
||||
}
|
||||
}
|
||||
|
||||
//update panels
|
||||
if (m_push_upgrade_panel) {
|
||||
m_push_upgrade_panel->update(obj);
|
||||
|
|
|
@ -78,7 +78,6 @@ protected:
|
|||
std::string last_status_str = "";
|
||||
|
||||
void upgrade_firmware_internal();
|
||||
void on_upgrade_firmware(wxCommandEvent &event);
|
||||
void on_show_release_note(wxMouseEvent &event);
|
||||
|
||||
public:
|
||||
|
@ -98,6 +97,9 @@ public:
|
|||
void show_status(int status, std::string upgrade_status_str = "");
|
||||
void show_ams(bool show = false, bool force_update = false);
|
||||
|
||||
void on_upgrade_firmware(wxCommandEvent &event);
|
||||
void on_consisitency_upgrade_firmware(wxCommandEvent &event);
|
||||
|
||||
MachineObject *m_obj{nullptr};
|
||||
FirmwareInfo m_ota_info;
|
||||
FirmwareInfo m_ams_info;
|
||||
|
@ -129,6 +131,11 @@ protected:
|
|||
//enable_select_firmware only in debug mode
|
||||
bool enable_select_firmware = false;
|
||||
bool m_need_update = false;
|
||||
//hint of force upgrade or consistency upgrade
|
||||
int last_forced_hint_status = -1;
|
||||
int last_consistency_hint_status = -1;
|
||||
bool m_show_forced_hint = true;
|
||||
bool m_show_consistency_hint = true;
|
||||
|
||||
public:
|
||||
UpgradePanel(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
|
||||
|
|
|
@ -27,9 +27,9 @@ Button::Button()
|
|||
{
|
||||
background_color = StateColor(
|
||||
std::make_pair(0xF0F0F0, (int) StateColor::Disabled),
|
||||
std::make_pair(0x37EE7C, (int) StateColor::Hovered | StateColor::Checked),
|
||||
std::make_pair(0x00AE42, (int) StateColor::Checked),
|
||||
std::make_pair(*wxLIGHT_GREY, (int) StateColor::Hovered),
|
||||
std::make_pair(0x37EE7C, (int) StateColor::Hovered | StateColor::Checked),
|
||||
std::make_pair(*wxWHITE, (int) StateColor::Normal));
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ wxString ComboBox::GetTextLabel() const
|
|||
|
||||
bool ComboBox::SetFont(wxFont const& font)
|
||||
{
|
||||
if (GetTextCtrl()->IsShown())
|
||||
if (GetTextCtrl() && GetTextCtrl()->IsShown())
|
||||
return GetTextCtrl()->SetFont(font);
|
||||
else
|
||||
return TextInput::SetFont(font);
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
|
||||
wxFont Label::sysFont(int size, bool bold)
|
||||
{
|
||||
#ifdef __linux__
|
||||
return wxFont{};
|
||||
#endif
|
||||
#ifdef __WIN32__
|
||||
//#ifdef __linux__
|
||||
// return wxFont{};
|
||||
//#endif
|
||||
#ifndef __APPLE__
|
||||
size = size * 4 / 5;
|
||||
#endif
|
||||
|
||||
auto face = wxString::FromUTF8("HarmonyOS Sans SC");
|
||||
wxFont font{size, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL, false, face};
|
||||
font.SetFaceName(face);
|
||||
|
@ -19,24 +20,46 @@ wxFont Label::sysFont(int size, bool bold)
|
|||
}
|
||||
return font;
|
||||
}
|
||||
wxFont Label::Head_24 = Label::sysFont(24, true);
|
||||
wxFont Label::Head_20 = Label::sysFont(20, true);
|
||||
wxFont Label::Head_18 = Label::sysFont(18, true);
|
||||
wxFont Label::Head_16 = Label::sysFont(16, true);
|
||||
wxFont Label::Head_15 = Label::sysFont(15, true);
|
||||
wxFont Label::Head_14 = Label::sysFont(14, true);
|
||||
wxFont Label::Head_13 = Label::sysFont(13, true);
|
||||
wxFont Label::Head_12 = Label::sysFont(12, true);
|
||||
wxFont Label::Head_10 = Label::sysFont(10, true);
|
||||
wxFont Label::Head_24;
|
||||
wxFont Label::Head_20;
|
||||
wxFont Label::Head_18;
|
||||
wxFont Label::Head_16;
|
||||
wxFont Label::Head_15;
|
||||
wxFont Label::Head_14;
|
||||
wxFont Label::Head_13;
|
||||
wxFont Label::Head_12;
|
||||
wxFont Label::Head_10;
|
||||
|
||||
wxFont Label::Body_16 = Label::sysFont(16, false);
|
||||
wxFont Label::Body_15 = Label::sysFont(15, false);
|
||||
wxFont Label::Body_14 = Label::sysFont(14, false);
|
||||
wxFont Label::Body_13 = Label::sysFont(13, false);
|
||||
wxFont Label::Body_12 = Label::sysFont(12, false);
|
||||
wxFont Label::Body_11 = Label::sysFont(11, false);
|
||||
wxFont Label::Body_10 = Label::sysFont(10, false);
|
||||
wxFont Label::Body_9 = Label::sysFont(9, false);
|
||||
wxFont Label::Body_16;
|
||||
wxFont Label::Body_15;
|
||||
wxFont Label::Body_14;
|
||||
wxFont Label::Body_13;
|
||||
wxFont Label::Body_12;
|
||||
wxFont Label::Body_11;
|
||||
wxFont Label::Body_10;
|
||||
wxFont Label::Body_9;
|
||||
|
||||
void Label::initSysFont()
|
||||
{
|
||||
Head_24 = Label::sysFont(24, true);
|
||||
Head_20 = Label::sysFont(20, true);
|
||||
Head_18 = Label::sysFont(18, true);
|
||||
Head_16 = Label::sysFont(16, true);
|
||||
Head_15 = Label::sysFont(15, true);
|
||||
Head_14 = Label::sysFont(14, true);
|
||||
Head_13 = Label::sysFont(13, true);
|
||||
Head_12 = Label::sysFont(12, true);
|
||||
Head_10 = Label::sysFont(10, true);
|
||||
|
||||
Body_16 = Label::sysFont(16, false);
|
||||
Body_15 = Label::sysFont(15, false);
|
||||
Body_14 = Label::sysFont(14, false);
|
||||
Body_13 = Label::sysFont(13, false);
|
||||
Body_12 = Label::sysFont(12, false);
|
||||
Body_11 = Label::sysFont(11, false);
|
||||
Body_10 = Label::sysFont(10, false);
|
||||
Body_9 = Label::sysFont(9, false);
|
||||
}
|
||||
|
||||
wxSize Label::split_lines(wxDC &dc, int width, const wxString &text, wxString &multiline_text)
|
||||
{
|
||||
|
@ -64,11 +87,36 @@ wxSize Label::split_lines(wxDC &dc, int width, const wxString &text, wxString &m
|
|||
return dc.GetMultiLineTextExtent(multiline_text);
|
||||
}
|
||||
|
||||
Label::Label(wxWindow *parent, wxString const &text) : Label(parent, Body_14, text) {}
|
||||
Label::Label(wxWindow *parent, wxString const &text, long style) : Label(parent, Body_14, text, style) {}
|
||||
|
||||
Label::Label(wxWindow *parent, wxFont const &font, wxString const &text)
|
||||
: wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, 0)
|
||||
Label::Label(wxWindow *parent, wxFont const &font, wxString const &text, long style)
|
||||
: wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, style)
|
||||
{
|
||||
this->font = font;
|
||||
SetFont(font);
|
||||
SetBackgroundColour(StaticBox::GetParentBackgroundColor(parent));
|
||||
Bind(wxEVT_ENTER_WINDOW, [this](auto &e) {
|
||||
if (GetWindowStyle() & LB_HYPERLINK) {
|
||||
SetFont(this->font.Underlined());
|
||||
Refresh();
|
||||
}
|
||||
});
|
||||
Bind(wxEVT_LEAVE_WINDOW, [this](auto &e) {
|
||||
SetFont(this->font);
|
||||
Refresh();
|
||||
});
|
||||
}
|
||||
|
||||
void Label::SetWindowStyleFlag(long style)
|
||||
{
|
||||
wxStaticText::SetWindowStyleFlag(style);
|
||||
if (style & LB_HYPERLINK) {
|
||||
this->color = GetForegroundColour();
|
||||
static wxColor clr_url("#00AE42");
|
||||
SetForegroundColour(clr_url);
|
||||
} else {
|
||||
SetForegroundColour(this->color);
|
||||
SetFont(this->font);
|
||||
}
|
||||
Refresh();
|
||||
}
|
||||
|
|
|
@ -3,12 +3,21 @@
|
|||
|
||||
#include <wx/stattext.h>
|
||||
|
||||
#define LB_HYPERLINK 0x0001
|
||||
|
||||
|
||||
class Label : public wxStaticText
|
||||
{
|
||||
public:
|
||||
Label(wxWindow *parent, wxString const &text = {});
|
||||
Label(wxWindow *parent, wxString const &text = {}, long style = 0);
|
||||
|
||||
Label(wxWindow *parent, wxFont const &font, wxString const &text = {});
|
||||
Label(wxWindow *parent, wxFont const &font, wxString const &text = {}, long style = 0);
|
||||
|
||||
void SetWindowStyleFlag(long style) override;
|
||||
|
||||
private:
|
||||
wxFont font;
|
||||
wxColour color;
|
||||
|
||||
public:
|
||||
static wxFont Head_24;
|
||||
|
@ -29,6 +38,8 @@ public:
|
|||
static wxFont Body_10;
|
||||
static wxFont Body_11;
|
||||
static wxFont Body_9;
|
||||
|
||||
static void initSysFont();
|
||||
|
||||
static wxFont sysFont(int size, bool bold = false);
|
||||
|
||||
|
|
|
@ -237,6 +237,7 @@ Button *SpinInput::createButton(bool inc)
|
|||
});
|
||||
btn->Bind(wxEVT_LEFT_DCLICK, [=](auto &e) {
|
||||
delta = inc ? 1 : -1;
|
||||
btn->CaptureMouse();
|
||||
SetValue(val + delta);
|
||||
sendSpinEvent();
|
||||
});
|
||||
|
|
|
@ -34,6 +34,8 @@ StaticBox::StaticBox(wxWindow* parent,
|
|||
|
||||
bool StaticBox::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
|
||||
{
|
||||
if (style & wxBORDER_NONE)
|
||||
border_width = 0;
|
||||
wxWindow::Create(parent, id, pos, size, style);
|
||||
state_handler.attach({&border_color, &background_color, &background_color2});
|
||||
state_handler.update_binds();
|
||||
|
@ -150,7 +152,7 @@ void StaticBox::doRender(wxDC& dc)
|
|||
if (background_color2.count() == 0) {
|
||||
if ((border_width && border_color.count() > 0) || background_color.count() > 0) {
|
||||
wxRect rc(0, 0, size.x, size.y);
|
||||
if (border_width && border_color.count() > 0 && (GetWindowStyle() & wxBORDER_NONE) == 0) {
|
||||
if (border_width && border_color.count() > 0) {
|
||||
if (dc.GetContentScaleFactor() == 1.0) {
|
||||
int d = floor(border_width / 2.0);
|
||||
int d2 = floor(border_width - 1);
|
||||
|
|
|
@ -10,7 +10,7 @@ EVT_PAINT(StaticLine::paintEvent)
|
|||
|
||||
END_EVENT_TABLE()
|
||||
|
||||
StaticLine::StaticLine(wxWindow* parent, bool vertical, const wxString& label)
|
||||
StaticLine::StaticLine(wxWindow *parent, bool vertical, const wxString &label, const wxString &icon)
|
||||
: wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)
|
||||
, vertical(vertical)
|
||||
{
|
||||
|
@ -18,22 +18,22 @@ StaticLine::StaticLine(wxWindow* parent, bool vertical, const wxString& label)
|
|||
this->pen = wxPen(wxColour("#EEEEEE"));
|
||||
DisableFocusFromKeyboard();
|
||||
SetFont(Label::Body_14);
|
||||
SetLabel(label);
|
||||
wxWindow::SetLabel(label);
|
||||
SetIcon(icon);
|
||||
}
|
||||
|
||||
void StaticLine::SetLabel(const wxString& label)
|
||||
{
|
||||
wxWindow::SetLabel(label);
|
||||
int s = 1;
|
||||
if (!label.IsEmpty()) {
|
||||
wxClientDC dc(this);
|
||||
auto size = dc.GetTextExtent(label);
|
||||
s = vertical ? size.x : size.y;
|
||||
}
|
||||
if (vertical)
|
||||
SetMinSize({s, -1});
|
||||
else
|
||||
SetMinSize({-1, s});
|
||||
messureSize();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void StaticLine::SetIcon(const wxString &icon)
|
||||
{
|
||||
this->icon = icon.IsEmpty() ? ScalableBitmap()
|
||||
: ScalableBitmap(this, icon.ToStdString(), 18);
|
||||
messureSize();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,13 @@ void StaticLine::SetLineColour(wxColour color)
|
|||
this->pen = wxPen(color);
|
||||
}
|
||||
|
||||
void StaticLine::Rescale()
|
||||
{
|
||||
if (this->icon.bmp().IsOk())
|
||||
this->icon.msw_rescale();
|
||||
messureSize();
|
||||
}
|
||||
|
||||
void StaticLine::paintEvent(wxPaintEvent& evt)
|
||||
{
|
||||
// depending on your system you may need to look at double-buffered dcs
|
||||
|
@ -49,6 +56,27 @@ void StaticLine::paintEvent(wxPaintEvent& evt)
|
|||
render(dc);
|
||||
}
|
||||
|
||||
void StaticLine::messureSize()
|
||||
{
|
||||
wxClientDC dc(this);
|
||||
wxSize textSize = dc.GetTextExtent(GetLabel());
|
||||
wxSize szContent = textSize;
|
||||
if (this->icon.bmp().IsOk()) {
|
||||
if (szContent.y > 0) {
|
||||
// BBS norrow size between text and icon
|
||||
szContent.x += 5;
|
||||
}
|
||||
wxSize szIcon = this->icon.GetBmpSize();
|
||||
szContent.x += szIcon.x;
|
||||
if (szIcon.y > szContent.y) szContent.y = szIcon.y;
|
||||
}
|
||||
if (vertical)
|
||||
szContent.y += 10;
|
||||
else
|
||||
szContent.x += 10;
|
||||
SetMinSize(szContent);
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we do the actual rendering. I put it in a separate
|
||||
* method so that it can work no matter what type of DC
|
||||
|
@ -57,22 +85,29 @@ void StaticLine::paintEvent(wxPaintEvent& evt)
|
|||
void StaticLine::render(wxDC& dc)
|
||||
{
|
||||
wxSize size = GetSize();
|
||||
wxSize size2 {0, 0};
|
||||
auto label = GetLabel();
|
||||
wxSize textSize;
|
||||
auto label = GetLabel();
|
||||
if (!label.IsEmpty()) textSize = dc.GetTextExtent(label);
|
||||
wxRect titleRect{{0, 0}, size};
|
||||
titleRect.height = wxMax(icon.GetBmpHeight(), textSize.GetHeight());
|
||||
int contentWidth = icon.GetBmpWidth() + ((icon.bmp().IsOk() && textSize.GetWidth() > 0) ? 5 : 0) +
|
||||
textSize.GetWidth();
|
||||
if (vertical) titleRect.Deflate((size.GetWidth() - contentWidth) / 2, 0);
|
||||
if (icon.bmp().IsOk()) {
|
||||
dc.DrawBitmap(icon.bmp(), {0, (size.y - icon.GetBmpHeight()) / 2});
|
||||
titleRect.x += icon.GetBmpWidth() + 5;
|
||||
}
|
||||
if (!label.IsEmpty()) {
|
||||
size2 = dc.GetTextExtent(label);
|
||||
dc.DrawText(label, 0, 0);
|
||||
if (vertical)
|
||||
size2.y += 5;
|
||||
else
|
||||
size2.x += 5;
|
||||
dc.DrawText(label, titleRect.x, (size.GetHeight() - textSize.GetHeight()) / 2);
|
||||
titleRect.x += textSize.GetWidth() + 5;
|
||||
}
|
||||
dc.SetPen(pen);
|
||||
if (vertical) {
|
||||
size.x /= 2;
|
||||
dc.DrawLine(size.x, size2.y, size.x, size.y);
|
||||
if (titleRect.y > 0) titleRect.y += 5;
|
||||
dc.DrawLine(size.x, titleRect.y, size.x, size.y);
|
||||
} else {
|
||||
size.y /= 2;
|
||||
dc.DrawLine(size2.x, size.y, size.x, size.y);
|
||||
dc.DrawLine(titleRect.x, size.y, size.x, size.y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,34 @@
|
|||
#ifndef slic3r_GUI_StaticLine_hpp_
|
||||
#define slic3r_GUI_StaticLine_hpp_
|
||||
|
||||
#include "../wxExtensions.hpp"
|
||||
#include "wx/window.h"
|
||||
|
||||
class StaticLine : public wxWindow
|
||||
{
|
||||
public:
|
||||
StaticLine(wxWindow* parent, bool vertical = false, const wxString& label = {});
|
||||
StaticLine(wxWindow *parent, bool vertical = false, const wxString &label = {}, const wxString &icon = {});
|
||||
|
||||
public:
|
||||
void SetLabel(const wxString& label) override;
|
||||
|
||||
void SetIcon(const wxString& icon);
|
||||
|
||||
void SetLineColour(wxColour color);
|
||||
|
||||
void Rescale();
|
||||
|
||||
private:
|
||||
wxPen pen;
|
||||
bool vertical;
|
||||
ScalableBitmap icon;
|
||||
|
||||
private:
|
||||
void paintEvent(wxPaintEvent& evt);
|
||||
|
||||
void render(wxDC& dc);
|
||||
void messureSize();
|
||||
|
||||
void render(wxDC &dc);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
|
|
@ -10,6 +10,25 @@
|
|||
|
||||
#ifdef __WIN32__
|
||||
#include "../WebView2.h"
|
||||
#elif defined __linux__
|
||||
#include <gtk/gtk.h>
|
||||
#define WEBKIT_API
|
||||
struct WebKitWebView;
|
||||
struct WebKitJavascriptResult;
|
||||
extern "C" {
|
||||
WEBKIT_API void
|
||||
webkit_web_view_run_javascript (WebKitWebView *web_view,
|
||||
const gchar *script,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
WEBKIT_API WebKitJavascriptResult *
|
||||
webkit_web_view_run_javascript_finish (WebKitWebView *web_view,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
WEBKIT_API void
|
||||
webkit_javascript_result_unref (WebKitJavascriptResult *js_result);
|
||||
}
|
||||
#endif
|
||||
|
||||
class FakeWebView : public wxWebView
|
||||
|
@ -85,13 +104,13 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, wxString const & url)
|
|||
webView->Create(parent, wxID_ANY, url2, wxDefaultPosition, wxDefaultSize);
|
||||
webView->SetUserAgent(wxString::Format("BBL-Slicer/v%s", SLIC3R_VERSION));
|
||||
#endif
|
||||
#ifdef __WXMAC__
|
||||
#ifndef __WIN32__
|
||||
Slic3r::GUI::wxGetApp().CallAfter([webView] {
|
||||
#endif
|
||||
if (!webView->AddScriptMessageHandler("wx"))
|
||||
wxLogError("Could not add script message handler");
|
||||
#ifdef __WXMAC__
|
||||
});
|
||||
#ifndef __WIN32__
|
||||
});
|
||||
#endif
|
||||
webView->EnableContextMenu(false);
|
||||
} else {
|
||||
|
@ -132,8 +151,18 @@ bool WebView::RunScript(wxWebView *webView, wxString const &javascript)
|
|||
Slic3r::GUI::WKWebView_evaluateJavaScript(wkWebView, wrapJS.GetWrappedCode(), nullptr);
|
||||
return true;
|
||||
#else
|
||||
wxString result;
|
||||
return webView->RunScript(javascript, &result);
|
||||
WebKitWebView *wkWebView = (WebKitWebView *) webView->GetNativeBackend();
|
||||
webkit_web_view_run_javascript(
|
||||
wkWebView, javascript.utf8_str(), NULL,
|
||||
[](GObject *wkWebView, GAsyncResult *res, void *) {
|
||||
GError * error = NULL;
|
||||
auto result = webkit_web_view_run_javascript_finish((WebKitWebView*)wkWebView, res, &error);
|
||||
if (!result)
|
||||
g_error_free (error);
|
||||
else
|
||||
webkit_javascript_result_unref (result);
|
||||
}, NULL);
|
||||
return true;
|
||||
#endif
|
||||
} catch (std::exception &e) {
|
||||
return false;
|
||||
|
|
|
@ -38,7 +38,7 @@ void wxMediaCtrl2::Load(wxURI url)
|
|||
wxExecute("cmd /c start " + url, wxEXEC_HIDE_CONSOLE);
|
||||
}
|
||||
});
|
||||
m_error = 2;
|
||||
m_error = 100;
|
||||
wxMediaEvent event(wxEVT_MEDIA_STATECHANGED);
|
||||
event.SetId(GetId());
|
||||
event.SetEventObject(this);
|
||||
|
@ -56,7 +56,7 @@ void wxMediaCtrl2::Load(wxURI url)
|
|||
wxMessageBox(_L("Missing BambuSource component registered for media playing! Please re-install BambuStutio or seek after-sales help."), _L("Error"),
|
||||
wxOK);
|
||||
});
|
||||
m_error = clsid.IsEmpty() ? 100 : clsid != L"{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}" ? 101 : 102;
|
||||
m_error = clsid != L"{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}" ? 101 : path.empty() ? 102 : 103;
|
||||
wxMediaEvent event(wxEVT_MEDIA_STATECHANGED);
|
||||
event.SetId(GetId());
|
||||
event.SetEventObject(this);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue