mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-21 15:51:10 -06:00
Merge branch 'master-remote' into feature/merge_remote_1.3
# Conflicts: # bbl/i18n/zh_cn/BambuStudio_zh_CN.po # resources/i18n/zh_cn/BambuStudio.mo # resources/profiles/Voron.json # resources/profiles/Voron/filament/Voron Generic ABS.json # resources/profiles/Voron/filament/Voron Generic ASA.json # resources/profiles/Voron/filament/Voron Generic PA-CF.json # resources/profiles/Voron/filament/Voron Generic PA.json # resources/profiles/Voron/filament/Voron Generic PC.json # resources/profiles/Voron/filament/Voron Generic PETG.json # resources/profiles/Voron/filament/Voron Generic PLA-CF.json # resources/profiles/Voron/filament/Voron Generic PLA.json # resources/profiles/Voron/filament/Voron Generic PVA.json # resources/profiles/Voron/filament/Voron Generic TPU.json # resources/profiles/Voron/filament/fdm_filament_abs.json # resources/profiles/Voron/filament/fdm_filament_asa.json # resources/profiles/Voron/filament/fdm_filament_common.json # resources/profiles/Voron/filament/fdm_filament_pa.json # resources/profiles/Voron/filament/fdm_filament_pc.json # resources/profiles/Voron/filament/fdm_filament_pet.json # resources/profiles/Voron/filament/fdm_filament_pla.json # resources/profiles/Voron/filament/fdm_filament_pva.json # resources/profiles/Voron/filament/fdm_filament_tpu.json # resources/profiles/Voron/machine/Voron 0.1 0.4 nozzle.json # resources/profiles/Voron/machine/Voron 0.1.json # resources/profiles/Voron/machine/Voron 2.4 250 0.4 nozzle.json # resources/profiles/Voron/machine/Voron 2.4 250.json # resources/profiles/Voron/machine/Voron 2.4 300 0.4 nozzle.json # resources/profiles/Voron/machine/Voron 2.4 300.json # resources/profiles/Voron/machine/Voron 2.4 350 0.4 nozzle.json # resources/profiles/Voron/machine/Voron 2.4 350.json # resources/profiles/Voron/machine/Voron Trident 250 0.4 nozzle.json # resources/profiles/Voron/machine/Voron Trident 250.json # resources/profiles/Voron/machine/Voron Trident 300 0.4 nozzle.json # resources/profiles/Voron/machine/Voron Trident 300.json # resources/profiles/Voron/machine/Voron Trident 350 0.4 nozzle.json # resources/profiles/Voron/machine/Voron Trident 350.json # resources/profiles/Voron/machine/fdm_klipper_common.json # resources/profiles/Voron/process/0.08mm Extra Fine @Voron.json # resources/profiles/Voron/process/0.12mm Fine @Voron.json # resources/profiles/Voron/process/0.15mm Optimal @Voron.json # resources/profiles/Voron/process/0.20mm Standard @Voron.json # resources/profiles/Voron/process/0.24mm Draft @Voron.json # resources/profiles/Voron/process/0.28mm Extra Draft @Voron.json # resources/profiles/Voron/process/fdm_process_voron_common.json # src/libslic3r/Preset.cpp # src/libslic3r/PrintConfig.cpp # src/libslic3r/PrintConfig.hpp # src/libslic3r/PrintObject.cpp # src/slic3r/GUI/BackgroundSlicingProcess.cpp # src/slic3r/GUI/Field.cpp # src/slic3r/GUI/GLToolbar.cpp # src/slic3r/GUI/GLToolbar.hpp # src/slic3r/GUI/MainFrame.cpp # src/slic3r/GUI/MainFrame.hpp # src/slic3r/GUI/NotificationManager.cpp # src/slic3r/GUI/PhysicalPrinterDialog.cpp # src/slic3r/GUI/PhysicalPrinterDialog.hpp # src/slic3r/GUI/Plater.cpp # src/slic3r/GUI/Plater.hpp # src/slic3r/GUI/PrintHostDialogs.cpp # src/slic3r/GUI/PrintHostDialogs.hpp # src/slic3r/Utils/PrintHost.cpp
This commit is contained in:
commit
35455e6533
278 changed files with 14888 additions and 2414 deletions
|
@ -251,7 +251,9 @@ bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_heig
|
|||
m_extended_bounding_box = this->calc_extended_bounding_box(false);
|
||||
|
||||
//BBS: add part plate logic
|
||||
/*#if 0
|
||||
|
||||
//BBS add default bed
|
||||
#if 1
|
||||
ExPolygon poly{ Polygon::new_scale(printable_area) };
|
||||
#else
|
||||
ExPolygon poly;
|
||||
|
@ -265,7 +267,7 @@ bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_heig
|
|||
const BoundingBox& bed_bbox = poly.contour.bounding_box();
|
||||
calc_gridlines(poly, bed_bbox);
|
||||
|
||||
m_polygon = offset(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5))[0];*/
|
||||
m_polygon = offset(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5))[0];
|
||||
|
||||
if (with_reset) {
|
||||
this->release_VBOs();
|
||||
|
@ -375,7 +377,7 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box(bool consider_model_offset) cons
|
|||
return out;
|
||||
}
|
||||
|
||||
/*void Bed3D::calc_triangles(const ExPolygon& poly)
|
||||
void Bed3D::calc_triangles(const ExPolygon& poly)
|
||||
{
|
||||
if (! m_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z))
|
||||
BOOST_LOG_TRIVIAL(error) << "Unable to create bed triangles";
|
||||
|
@ -406,7 +408,7 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
|
|||
|
||||
if (!m_gridlines.set_from_lines(gridlines, GROUND_Z))
|
||||
BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n";
|
||||
}*/
|
||||
}
|
||||
|
||||
// Try to match the print bed shape with the shape of an active profile. If such a match exists,
|
||||
// return the print bed model.
|
||||
|
@ -611,6 +613,36 @@ void Bed3D::update_model_offset() const
|
|||
const_cast<BoundingBoxf3&>(m_extended_bounding_box) = calc_extended_bounding_box();
|
||||
}
|
||||
|
||||
GeometryBuffer Bed3D::update_bed_triangles() const
|
||||
{
|
||||
GeometryBuffer new_triangles;
|
||||
Vec3d shift = m_extended_bounding_box.center();
|
||||
shift(2) = -0.03;
|
||||
Vec3d* model_offset_ptr = const_cast<Vec3d*>(&m_model_offset);
|
||||
*model_offset_ptr = shift;
|
||||
//BBS: TODO: hack for default bed
|
||||
BoundingBoxf3 build_volume;
|
||||
|
||||
if (!m_build_volume.valid()) return new_triangles;
|
||||
|
||||
(*model_offset_ptr)(0) = m_build_volume.bounding_volume2d().min.x();
|
||||
(*model_offset_ptr)(1) = m_build_volume.bounding_volume2d().min.y();
|
||||
(*model_offset_ptr)(2) = -0.41 + GROUND_Z;
|
||||
|
||||
std::vector<Vec2d> new_bed_shape;
|
||||
for (auto point: m_bed_shape) {
|
||||
Vec2d new_point(point.x() + model_offset_ptr->x(), point.y() + model_offset_ptr->y());
|
||||
new_bed_shape.push_back(new_point);
|
||||
}
|
||||
ExPolygon poly{ Polygon::new_scale(new_bed_shape) };
|
||||
if (!new_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z)) {
|
||||
;
|
||||
}
|
||||
// update extended bounding box
|
||||
const_cast<BoundingBoxf3&>(m_extended_bounding_box) = calc_extended_bounding_box();
|
||||
return new_triangles;
|
||||
}
|
||||
|
||||
void Bed3D::render_model() const
|
||||
{
|
||||
if (m_model_filename.empty())
|
||||
|
@ -654,9 +686,11 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom) const
|
|||
|
||||
void Bed3D::render_default(bool bottom) const
|
||||
{
|
||||
/*const_cast<GLTexture*>(&m_texture)->reset();
|
||||
bool picking = false;
|
||||
const_cast<GLTexture*>(&m_texture)->reset();
|
||||
|
||||
unsigned int triangles_vcount = m_triangles.get_vertices_count();
|
||||
GeometryBuffer default_triangles = update_bed_triangles();
|
||||
if (triangles_vcount > 0) {
|
||||
bool has_model = !m_model.get_filename().empty();
|
||||
|
||||
|
@ -671,7 +705,7 @@ void Bed3D::render_default(bool bottom) const
|
|||
glsafe(::glDepthMask(GL_FALSE));
|
||||
glsafe(::glColor4fv(picking ? PICKING_MODEL_COLOR.data() : DEFAULT_MODEL_COLOR.data()));
|
||||
glsafe(::glNormal3d(0.0f, 0.0f, 1.0f));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data()));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, default_triangles.get_vertex_data_size(), (GLvoid*)default_triangles.get_vertices_data()));
|
||||
glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount));
|
||||
glsafe(::glDepthMask(GL_TRUE));
|
||||
}
|
||||
|
@ -683,14 +717,14 @@ void Bed3D::render_default(bool bottom) const
|
|||
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 1.0f));
|
||||
else
|
||||
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data()));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, default_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data()));
|
||||
glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count()));
|
||||
}
|
||||
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void Bed3D::release_VBOs()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef slic3r_3DBed_hpp_
|
||||
#define slic3r_3DBed_hpp_
|
||||
|
||||
//#include "GLTexture.hpp"
|
||||
#include "GLTexture.hpp"
|
||||
#include "3DScene.hpp"
|
||||
#include "GLModel.hpp"
|
||||
|
||||
|
@ -90,10 +90,10 @@ private:
|
|||
// Print volume bounding box exteded with axes and model.
|
||||
BoundingBoxf3 m_extended_bounding_box;
|
||||
// Slightly expanded print bed polygon, for collision detection.
|
||||
//Polygon m_polygon;
|
||||
//GeometryBuffer m_triangles;
|
||||
//GeometryBuffer m_gridlines;
|
||||
//GLTexture m_texture;
|
||||
Polygon m_polygon;
|
||||
GeometryBuffer m_triangles;
|
||||
GeometryBuffer m_gridlines;
|
||||
GLTexture m_texture;
|
||||
// temporary texture shown until the main texture has still no levels compressed
|
||||
//GLTexture m_temp_texture;
|
||||
GLModel m_model;
|
||||
|
@ -148,6 +148,8 @@ private:
|
|||
void calc_triangles(const ExPolygon& poly);
|
||||
void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
|
||||
void update_model_offset() const;
|
||||
//BBS: with offset
|
||||
GeometryBuffer update_bed_triangles() const;
|
||||
static std::tuple<Type, std::string, std::string> detect_type(const Pointfs& shape);
|
||||
void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||
bool show_axes);
|
||||
|
|
|
@ -869,6 +869,10 @@ void GLVolume::render(bool with_outline) const
|
|||
std::array<float, 4> body_color = { 1.0f, 1.0f, 1.0f, 1.0f }; //red
|
||||
|
||||
shader->set_uniform("uniform_color", body_color);
|
||||
//if (GUI::wxGetApp().plater()->is_show_wireframe())
|
||||
// shader->set_uniform("show_wireframe", true);
|
||||
//else
|
||||
// shader->set_uniform("show_wireframe", false);
|
||||
shader->set_uniform("is_outline", true);
|
||||
glsafe(::glPopMatrix());
|
||||
glsafe(::glPushMatrix());
|
||||
|
|
|
@ -244,7 +244,11 @@ AboutDialog::AboutDialog()
|
|||
// version
|
||||
{
|
||||
vesizer->Add(0, FromDIP(165), 1, wxEXPAND, FromDIP(5));
|
||||
#if BBL_INTERNAL_TESTING
|
||||
auto version_string = _L("Internal Version") + " " + std::string(SLIC3R_VERSION);
|
||||
#else
|
||||
auto version_string = _L("Version") + " " + std::string(SLIC3R_VERSION);
|
||||
#endif
|
||||
wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
|
||||
wxFont version_font = GetFont();
|
||||
#ifdef __WXMSW__
|
||||
|
|
|
@ -139,6 +139,8 @@ void AuFile::enter_rename_mode()
|
|||
{
|
||||
m_input_name->Show();
|
||||
m_text_name->Hide();
|
||||
auto name = m_file_name.SubString(0, (m_file_name.Find(".") - 1));
|
||||
m_input_name->GetTextCtrl()->SetLabelText(name);
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ void CalibrationDialog::on_dpi_changed(const wxRect &suggested_rect) {}
|
|||
void CalibrationDialog::update_cali(MachineObject *obj)
|
||||
{
|
||||
if (!obj) return;
|
||||
if (obj->is_in_calibration() || obj->is_calibration_done()) {
|
||||
if (obj->is_calibration_running() || obj->is_calibration_done()) {
|
||||
if (obj->is_calibration_done()) {
|
||||
m_calibration_btn->Enable();
|
||||
m_calibration_btn->SetLabel(_L("Completed"));
|
||||
|
|
|
@ -560,9 +560,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
for (auto el : { "ironing_flow", "ironing_spacing", "ironing_speed" })
|
||||
toggle_field(el, has_ironing);
|
||||
|
||||
bool have_sequential_printing = (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
|
||||
for (auto el : { "extruder_clearance_radius", "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid" })
|
||||
toggle_field(el, have_sequential_printing);
|
||||
// bool have_sequential_printing = (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
|
||||
// for (auto el : { "extruder_clearance_radius", "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid" })
|
||||
// toggle_field(el, have_sequential_printing);
|
||||
|
||||
bool have_ooze_prevention = config->opt_bool("ooze_prevention");
|
||||
toggle_field("standby_temperature_delta", have_ooze_prevention);
|
||||
|
|
|
@ -9,7 +9,7 @@ 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)
|
||||
ConfirmHintDialog::ConfirmHintDialog(wxWindow* parent, wxWindowID id, const wxString& title, enum ButtonStyle btn_style, 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();
|
||||
|
@ -46,6 +46,11 @@ ConfirmHintDialog::ConfirmHintDialog(wxWindow* parent, wxWindowID id, const wxSt
|
|||
button_sizer->AddSpacer(FromDIP(20));
|
||||
button_sizer->Add(m_button_close);
|
||||
|
||||
if (btn_style == CONFIRM_AND_CANCEL)
|
||||
m_button_close->Show();
|
||||
else
|
||||
m_button_close->Hide();
|
||||
|
||||
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));
|
||||
|
@ -99,8 +104,13 @@ void ConfirmHintDialog::render(wxDC& dc) {
|
|||
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')
|
||||
if (firm_up_hint[i] == ' ') {
|
||||
new_line_pos = i;
|
||||
} else if (firm_up_hint[i] == '\n') {
|
||||
fisrt_line = firm_up_hint.SubString(0, i);
|
||||
remaining_line = firm_up_hint.SubString(i + 1, firm_up_hint.length());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!is_ch) {
|
||||
|
@ -109,7 +119,7 @@ void ConfirmHintDialog::render(wxDC& dc) {
|
|||
break;
|
||||
}
|
||||
else {
|
||||
fisrt_line = firm_up_hint.SubString(0, i);
|
||||
fisrt_line = firm_up_hint.SubString(0, i - 1);
|
||||
remaining_line = firm_up_hint.SubString(i, firm_up_hint.length());
|
||||
break;
|
||||
}
|
||||
|
@ -118,7 +128,6 @@ void ConfirmHintDialog::render(wxDC& dc) {
|
|||
}
|
||||
dc.DrawText(fisrt_line, pos_firm_up_hint);
|
||||
|
||||
|
||||
count_txt = "";
|
||||
new_line_pos = 0;
|
||||
for (int i = 0; i < remaining_line.length(); i++) {
|
||||
|
@ -162,11 +171,19 @@ void ConfirmHintDialog::on_button_close(wxCommandEvent& event) {
|
|||
this->Close();
|
||||
}
|
||||
|
||||
bool ConfirmHintDialog::Show(bool show)
|
||||
{
|
||||
if (show) { CentreOnParent(); }
|
||||
return DPIDialog::Show(show);
|
||||
}
|
||||
|
||||
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));
|
||||
if (m_button_close->IsShown()) {
|
||||
m_button_close->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_close->SetCornerRadius(FromDIP(12));
|
||||
}
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,16 @@ private:
|
|||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
|
||||
public:
|
||||
enum ButtonStyle {
|
||||
ONLY_CONFIRM = 0,
|
||||
CONFIRM_AND_CANCEL = 1,
|
||||
MAX_STYLE_NUM = 2
|
||||
};
|
||||
|
||||
ConfirmHintDialog(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxEmptyString,
|
||||
enum ButtonStyle btn_style = CONFIRM_AND_CANCEL,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxCLOSE_BOX | wxCAPTION);
|
||||
|
@ -38,6 +45,8 @@ public:
|
|||
|
||||
void SetHint(const wxString &hint);
|
||||
|
||||
bool Show(bool show) override;
|
||||
|
||||
~ConfirmHintDialog();
|
||||
};
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
@ -358,6 +358,7 @@ MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string
|
|||
mc_print_sub_stage = 0;
|
||||
mc_left_time = 0;
|
||||
home_flag = -1;
|
||||
hw_switch_state = 0;
|
||||
printing_speed_lvl = PrintingSpeedLevel::SPEED_LEVEL_INVALID;
|
||||
}
|
||||
|
||||
|
@ -1046,6 +1047,18 @@ bool MachineObject::is_axis_at_home(std::string axis)
|
|||
}
|
||||
}
|
||||
|
||||
bool MachineObject::is_filament_at_extruder()
|
||||
{
|
||||
if (hw_switch_state == 1)
|
||||
return true;
|
||||
else if (hw_switch_state == 0)
|
||||
return false;
|
||||
else {
|
||||
//default
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
wxString MachineObject::get_curr_stage()
|
||||
{
|
||||
if (stage_list_info.empty()) {
|
||||
|
@ -1359,6 +1372,19 @@ int MachineObject::command_ams_select_tray(std::string tray_id)
|
|||
return this->publish_gcode(gcode_cmd);
|
||||
}
|
||||
|
||||
int MachineObject::command_ams_control(std::string action)
|
||||
{
|
||||
//valid actions
|
||||
if (action == "resume" || action == "reset" || action == "pause") {
|
||||
json j;
|
||||
j["print"]["command"] = "ams_control";
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["print"]["param"] = action;
|
||||
return this->publish_json(j.dump());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int MachineObject::command_set_chamber_light(LIGHT_EFFECT effect, int on_time, int off_time, int loops, int interval)
|
||||
{
|
||||
|
@ -1726,6 +1752,12 @@ bool MachineObject::is_function_supported(PrinterFunction func)
|
|||
return DeviceManager::is_function_supported(printer_type, func_name);
|
||||
}
|
||||
|
||||
bool MachineObject::is_support_print_with_timelapse()
|
||||
{
|
||||
//TODO version check, set true by default
|
||||
return true;
|
||||
}
|
||||
|
||||
int MachineObject::publish_json(std::string json_str, int qos)
|
||||
{
|
||||
if (is_lan_mode_printer()) {
|
||||
|
@ -1820,6 +1852,9 @@ int MachineObject::parse_json(std::string payload)
|
|||
if (jj.contains("home_flag")) {
|
||||
home_flag = jj["home_flag"].get<int>();
|
||||
}
|
||||
if (jj.contains("hw_switch_state")) {
|
||||
hw_switch_state = jj["hw_switch_state"].get<int>();
|
||||
}
|
||||
|
||||
if (jj.contains("mc_remaining_time")) {
|
||||
if (jj["mc_remaining_time"].is_string())
|
||||
|
|
|
@ -466,6 +466,7 @@ public:
|
|||
int mc_left_time; /* left time in seconds */
|
||||
int last_mc_print_stage;
|
||||
int home_flag;
|
||||
int hw_switch_state;
|
||||
bool is_system_printing();
|
||||
int print_error;
|
||||
|
||||
|
@ -476,6 +477,8 @@ public:
|
|||
|
||||
bool is_axis_at_home(std::string axis);
|
||||
|
||||
bool is_filament_at_extruder();
|
||||
|
||||
wxString get_curr_stage();
|
||||
// return curr stage index of stage list
|
||||
int get_curr_stage_idx();
|
||||
|
@ -561,6 +564,7 @@ public:
|
|||
int command_ams_filament_settings(int ams_id, int tray_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max);
|
||||
int command_ams_select_tray(std::string tray_id);
|
||||
int command_ams_refresh_rfid(std::string tray_id);
|
||||
int command_ams_control(std::string action);
|
||||
int command_set_chamber_light(LIGHT_EFFECT effect, int on_time = 500, int off_time = 500, int loops = 1, int interval = 1000);
|
||||
int command_set_work_light(LIGHT_EFFECT effect, int on_time = 500, int off_time = 500, int loops = 1, int interval = 1000);
|
||||
|
||||
|
@ -605,6 +609,7 @@ public:
|
|||
bool is_online() { return m_is_online; }
|
||||
bool is_info_ready();
|
||||
bool is_function_supported(PrinterFunction func);
|
||||
bool is_support_print_with_timelapse();
|
||||
|
||||
|
||||
/* Msg for display MsgFn */
|
||||
|
|
|
@ -31,6 +31,13 @@ namespace GUI {
|
|||
DownloadProgressDialog::DownloadProgressDialog(wxString title)
|
||||
: DPIDialog(static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
|
||||
{
|
||||
wxString download_failed_url = wxT("https://wiki.bambulab.com/e/en/software/bambu-studio/failed-to-get-network-plugin");
|
||||
wxString install_failed_url = wxT("https://wiki.bambulab.com/e/en/software/bambu-studio/failed-to-get-network-plugin");
|
||||
|
||||
wxString download_failed_msg = _L("Failed to download the plug-in. Please check your firewall settings and vpn software, check and retry.");
|
||||
wxString install_failed_msg = _L("Failed to install the plug-in. Please check whether it is blocked or deleted by anti-virus software.");
|
||||
|
||||
|
||||
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
|
||||
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
|
||||
|
||||
|
@ -39,14 +46,68 @@ DownloadProgressDialog::DownloadProgressDialog(wxString title)
|
|||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
m_status_bar = std::make_shared<BBLStatusBarSend>(this);
|
||||
|
||||
|
||||
m_simplebook_status = new wxSimplebook(this);
|
||||
m_simplebook_status->SetSize(wxSize(FromDIP(400), FromDIP(70)));
|
||||
m_simplebook_status->SetMinSize(wxSize(FromDIP(400), FromDIP(70)));
|
||||
m_simplebook_status->SetMaxSize(wxSize(FromDIP(400), FromDIP(70)));
|
||||
|
||||
//mode normal
|
||||
m_status_bar = std::make_shared<BBLStatusBarSend>(m_simplebook_status);
|
||||
m_panel_download = m_status_bar->get_panel();
|
||||
m_panel_download->SetSize(wxSize(FromDIP(340), -1));
|
||||
m_panel_download->SetMinSize(wxSize(FromDIP(340), -1));
|
||||
m_panel_download->SetMaxSize(wxSize(FromDIP(340), -1));
|
||||
m_sizer_main->Add(m_panel_download, 0, wxALL, FromDIP(20));
|
||||
m_panel_download->SetSize(wxSize(FromDIP(400), FromDIP(70)));
|
||||
m_panel_download->SetMinSize(wxSize(FromDIP(400), FromDIP(70)));
|
||||
m_panel_download->SetMaxSize(wxSize(FromDIP(400), FromDIP(70)));
|
||||
|
||||
|
||||
//mode Download Failed
|
||||
auto m_panel_download_failed = new wxPanel(m_simplebook_status, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
|
||||
wxBoxSizer* sizer_download_failed = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto m_statictext_download_failed = new wxStaticText(m_panel_download_failed, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_statictext_download_failed->SetLabel(format_text(m_statictext_download_failed, download_failed_msg, FromDIP(360)));
|
||||
m_statictext_download_failed->Wrap(FromDIP(360));
|
||||
|
||||
sizer_download_failed->Add(m_statictext_download_failed, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
auto m_download_hyperlink = new wxHyperlinkCtrl(m_panel_download_failed, wxID_ANY, _L("click here to see more info"), download_failed_url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
|
||||
sizer_download_failed->Add(m_download_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
|
||||
m_panel_download_failed->SetSizer(sizer_download_failed);
|
||||
m_panel_download_failed->Layout();
|
||||
sizer_download_failed->Fit(m_panel_download_failed);
|
||||
|
||||
|
||||
//mode Installed failed
|
||||
auto m_panel_install_failed = new wxPanel(m_simplebook_status, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
|
||||
wxBoxSizer* sizer_install_failed = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto m_statictext_install_failed = new wxStaticText(m_panel_install_failed, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_statictext_install_failed->SetLabel(format_text(m_statictext_install_failed, install_failed_msg,FromDIP(360)));
|
||||
m_statictext_install_failed->Wrap(FromDIP(360));
|
||||
|
||||
sizer_install_failed->Add(m_statictext_install_failed, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
auto m_install_hyperlink = new wxHyperlinkCtrl(m_panel_install_failed, wxID_ANY, _L("click here to see more info"), install_failed_url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
|
||||
sizer_install_failed->Add(m_install_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
|
||||
m_panel_download_failed->SetSizer(sizer_install_failed);
|
||||
m_panel_download_failed->Layout();
|
||||
sizer_install_failed->Fit(m_panel_install_failed);
|
||||
|
||||
m_sizer_main->Add(m_simplebook_status, 0, wxALL, FromDIP(20));
|
||||
m_sizer_main->Add(0, 0, 1, wxBOTTOM, 10);
|
||||
|
||||
|
||||
m_simplebook_status->AddPage(m_status_bar->get_panel(), wxEmptyString, true);
|
||||
m_simplebook_status->AddPage(m_panel_download_failed, wxEmptyString, false);
|
||||
m_simplebook_status->AddPage(m_panel_install_failed, wxEmptyString, false);
|
||||
|
||||
SetSizer(m_sizer_main);
|
||||
Layout();
|
||||
Fit();
|
||||
|
@ -55,9 +116,31 @@ DownloadProgressDialog::DownloadProgressDialog(wxString title)
|
|||
Bind(wxEVT_CLOSE_WINDOW, &DownloadProgressDialog::on_close, this);
|
||||
}
|
||||
|
||||
wxString DownloadProgressDialog::format_text(wxStaticText* st, wxString str, int warp)
|
||||
{
|
||||
if (wxGetApp().app_config->get("language") != "zh_CN") { return str; }
|
||||
|
||||
wxString out_txt = str;
|
||||
wxString count_txt = "";
|
||||
int new_line_pos = 0;
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
auto text_size = st->GetTextExtent(count_txt);
|
||||
if (text_size.x < warp) {
|
||||
count_txt += str[i];
|
||||
}
|
||||
else {
|
||||
out_txt.insert(i - 1, '\n');
|
||||
count_txt = "";
|
||||
}
|
||||
}
|
||||
return out_txt;
|
||||
}
|
||||
|
||||
bool DownloadProgressDialog::Show(bool show)
|
||||
{
|
||||
if (show) {
|
||||
m_simplebook_status->SetSelection(0);
|
||||
m_upgrade_job = std::make_shared<UpgradeNetworkJob>(m_status_bar);
|
||||
m_upgrade_job->set_event_handle(this);
|
||||
m_status_bar->set_progress(0);
|
||||
|
@ -71,9 +154,23 @@ bool DownloadProgressDialog::Show(bool show)
|
|||
);
|
||||
});
|
||||
|
||||
Bind(EVT_UPGRADE_NETWORK_FAILED, [this](wxCommandEvent& evt) {
|
||||
//download failed
|
||||
Bind(EVT_DOWNLOAD_NETWORK_FAILED, [this](wxCommandEvent& evt) {
|
||||
m_status_bar->change_button_label(_L("Close"));
|
||||
m_status_bar->set_progress(0);
|
||||
this->m_simplebook_status->SetSelection(1);
|
||||
m_status_bar->set_cancel_callback_fina(
|
||||
[this]() {
|
||||
this->Close();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
//install failed
|
||||
Bind(EVT_INSTALL_NETWORK_FAILED, [this](wxCommandEvent& evt) {
|
||||
m_status_bar->change_button_label(_L("Close"));
|
||||
m_status_bar->set_progress(0);
|
||||
this->m_simplebook_status->SetSelection(2);
|
||||
m_status_bar->set_cancel_callback_fina(
|
||||
[this]() {
|
||||
this->Close();
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <wx/richmsgdlg.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/simplebook.h>
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "BBLStatusBar.hpp"
|
||||
#include "BBLStatusBarSend.hpp"
|
||||
|
@ -37,11 +38,14 @@ protected:
|
|||
|
||||
public:
|
||||
DownloadProgressDialog(wxString title);
|
||||
wxString format_text(wxStaticText* st, wxString str, int warp);
|
||||
~DownloadProgressDialog();
|
||||
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
void update_release_note(std::string release_note, std::string version);
|
||||
|
||||
wxSimplebook* m_simplebook_status{nullptr};
|
||||
|
||||
std::shared_ptr<BBLStatusBarSend> m_status_bar;
|
||||
std::shared_ptr<UpgradeNetworkJob> m_upgrade_job { nullptr };
|
||||
wxPanel * m_panel_download;
|
||||
|
|
|
@ -1235,7 +1235,9 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
|||
// BBS
|
||||
case coEnums: {
|
||||
int val = boost::any_cast<int>(value);
|
||||
if (m_opt_id.compare("host_type") == 0 && val != 0 &&
|
||||
|
||||
// Support ThirdPartyPrinter
|
||||
if (m_opt_id.compare("host_type") == 0 && val != 0 &&
|
||||
m_opt.enum_values.size() > field->GetCount()) // for case, when PrusaLink isn't used as a HostType
|
||||
val--;
|
||||
if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "sparse_infill_pattern")
|
||||
|
@ -1317,15 +1319,15 @@ boost::any& Choice::get_value()
|
|||
// BBS
|
||||
if (m_opt.type == coEnum || m_opt.type == coEnums)
|
||||
{
|
||||
if (m_opt_id.compare("host_type") == 0 && m_opt.enum_values.size() > field->GetCount()) {
|
||||
// for case, when PrusaLink isn't used as a HostType
|
||||
m_value = field->GetSelection()+1;
|
||||
}
|
||||
else if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "sparse_infill_pattern") {
|
||||
if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "sparse_infill_pattern") {
|
||||
const std::string& key = m_opt.enum_values[field->GetSelection()];
|
||||
m_value = int(ConfigOptionEnum<InfillPattern>::get_enum_values().at(key));
|
||||
}
|
||||
else
|
||||
// Support ThirdPartyPrinter
|
||||
else if (m_opt_id.compare("host_type") == 0 && m_opt.enum_values.size() > field->GetCount()) {
|
||||
// for case, when PrusaLink isn't used as a HostType
|
||||
m_value = field->GetSelection() + 1;
|
||||
} else
|
||||
m_value = field->GetSelection();
|
||||
}
|
||||
else if (m_opt.gui_type == ConfigOptionDef::GUIType::f_enum_open || m_opt.gui_type == ConfigOptionDef::GUIType::i_enum_open) {
|
||||
|
|
|
@ -334,6 +334,13 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
static const ImU32 text_value_clr = IM_COL32(144, 144, 144, 255);
|
||||
static const ImU32 window_bg_clr = IM_COL32(255, 255, 255, 255);
|
||||
|
||||
auto it = std::find_if(moves.begin(), moves.end(), [&curr_line_id](auto move) {
|
||||
return move.gcode_id == curr_line_id;
|
||||
});
|
||||
if (it == moves.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -352,19 +359,101 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
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 height = ImGui::ColorMarkerStart + _u8L("Height: ") + ImGui::ColorMarkerEnd;
|
||||
std::string width = ImGui::ColorMarkerStart + _u8L("Width: ") + ImGui::ColorMarkerEnd;
|
||||
std::string speed = ImGui::ColorMarkerStart + _u8L("Speed: ") + ImGui::ColorMarkerEnd;
|
||||
std::string flow = ImGui::ColorMarkerStart + _u8L("Flow: ") + ImGui::ColorMarkerEnd;
|
||||
const float item_size = imgui.calc_text_size("X: 000.000 ").x;
|
||||
const float item_spacing = imgui.get_item_spacing().x;
|
||||
const float window_padding = ImGui::GetStyle().WindowPadding.x;
|
||||
|
||||
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()) {
|
||||
switch (view_type){
|
||||
case EViewType::Height: {
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine(window_padding + item_size + item_spacing);
|
||||
sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
sprintf(buf, "%s%.3f", z.c_str(), position.z());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine(window_padding + item_size + item_spacing);
|
||||
sprintf(buf, "%s%.2f", height.c_str(), it->height);
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
case EViewType::Width: {
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine(window_padding + item_size + item_spacing);
|
||||
sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
sprintf(buf, "%s%.3f", z.c_str(), position.z());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine(window_padding + item_size + item_spacing);
|
||||
sprintf(buf, "%s%.2f", width.c_str(), it->width);
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
case EViewType::Feedrate: {
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine(window_padding + item_size + item_spacing);
|
||||
sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
sprintf(buf, "%s%.3f", z.c_str(), position.z());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine(window_padding + item_size + item_spacing);
|
||||
sprintf(buf, "%s%.2f", speed.c_str(), it->feedrate);
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
case EViewType::VolumetricRate: {
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine(window_padding + item_size + item_spacing);
|
||||
sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
sprintf(buf, "%s%.3f", z.c_str(), position.z());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
ImGui::SameLine(window_padding + item_size + item_spacing);
|
||||
sprintf(buf, "%s%.2f", flow.c_str(), it->volumetric_rate());
|
||||
ImGui::PushItemWidth(item_size);
|
||||
imgui.text(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x());
|
||||
imgui.text(buf);
|
||||
|
||||
|
@ -372,54 +461,16 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
|
|||
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);
|
||||
|
||||
ImGui::SameLine();
|
||||
sprintf(buf, "%s%.f", speed.c_str(), it->feedrate);
|
||||
imgui.text(buf);
|
||||
}
|
||||
}
|
||||
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();
|
||||
float window_width = ImGui::GetWindowWidth();
|
||||
//size_t length = strlen(buf);
|
||||
if (width != last_window_width /*|| length != last_text_length*/) {
|
||||
last_window_width = width;
|
||||
if (window_width != last_window_width /*|| length != last_text_length*/) {
|
||||
last_window_width = window_width;
|
||||
//last_text_length = length;
|
||||
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
|
||||
imgui.set_requires_extra_frame();
|
||||
|
@ -3085,8 +3136,8 @@ void GCodeViewer::load_shells(const Print& print, bool initialized, bool force_p
|
|||
|
||||
const double max_z = print.objects()[0]->model_object()->get_model()->bounding_box().max(2);
|
||||
const PrintConfig& config = print.config();
|
||||
if (print.enable_timelapse_print()
|
||||
|| (extruders_count > 1 && config.enable_prime_tower && (config.print_sequence == PrintSequence::ByLayer))) {
|
||||
if (config.enable_prime_tower &&
|
||||
(print.enable_timelapse_print() || (extruders_count > 1 && (config.print_sequence == PrintSequence::ByLayer)))) {
|
||||
const float depth = print.wipe_tower_data(extruders_count).depth;
|
||||
const float brim_width = print.wipe_tower_data(extruders_count).brim_width;
|
||||
|
||||
|
@ -4703,7 +4754,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
|||
append_option_item(item,offsets);
|
||||
|
||||
//BBS display filament change times
|
||||
if (m_print_statistics.total_filamentchanges > 0) {
|
||||
if (m_print_statistics.total_filamentchanges > 0 && ( total_flushed_filament_m > 0 || total_flushed_filament_g > 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");
|
||||
|
|
|
@ -1935,7 +1935,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
auto timelapse_type = dconfig.option<ConfigOptionEnum<TimelapseType>>("timelapse_type");
|
||||
bool timelapse_enabled = timelapse_type ? (timelapse_type->value == TimelapseType::tlSmooth) : false;
|
||||
|
||||
if (timelapse_enabled || (filaments_count > 1 && wt && co != nullptr && co->value != PrintSequence::ByObject)) {
|
||||
if ((timelapse_enabled && wt) || (filaments_count > 1 && wt && co != nullptr && co->value != PrintSequence::ByObject)) {
|
||||
for (int plate_id = 0; plate_id < n_plates; plate_id++) {
|
||||
DynamicPrintConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
||||
float x = dynamic_cast<const ConfigOptionFloats*>(proj_cfg.option("wipe_tower_x"))->get_at(plate_id);
|
||||
|
@ -1978,6 +1978,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
m_selection.volumes_changed(map_glvolume_old_to_new);
|
||||
|
||||
m_gizmos.update_data();
|
||||
m_gizmos.update_assemble_view_data();
|
||||
m_gizmos.refresh_on_off_state();
|
||||
|
||||
// Update the toolbar
|
||||
|
@ -2409,6 +2410,10 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
|||
{
|
||||
//case WXK_BACK:
|
||||
case WXK_DELETE: { post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; }
|
||||
// BBS
|
||||
#ifdef __APPLE__
|
||||
case WXK_BACK: { post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; }
|
||||
#endif
|
||||
case WXK_ESCAPE: { deselect_all(); break; }
|
||||
//case WXK_F5: {
|
||||
// if ((wxGetApp().is_editor() && !wxGetApp().plater()->model().objects.empty()) ||
|
||||
|
@ -2661,6 +2666,12 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
wxGetApp().plater()->toggle_render_statistic_dialog();
|
||||
m_dirty = true;
|
||||
#endif
|
||||
}
|
||||
else if (evt.ShiftDown() && evt.ControlDown() && keyCode == WXK_RETURN) {
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
wxGetApp().plater()->toggle_show_wireframe();
|
||||
m_dirty = true;
|
||||
#endif
|
||||
}
|
||||
else if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) {
|
||||
|
@ -2694,7 +2705,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
}
|
||||
else if (keyCode == WXK_CONTROL)
|
||||
m_dirty = true;
|
||||
else if (m_gizmos.is_enabled() && !m_selection.is_empty()) {
|
||||
else if (m_gizmos.is_enabled() && !m_selection.is_empty() && m_canvas_type != CanvasAssembleView) {
|
||||
translationProcessor.process(evt);
|
||||
|
||||
//switch (keyCode)
|
||||
|
@ -2774,7 +2785,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
}
|
||||
else if (keyCode == WXK_CONTROL)
|
||||
m_dirty = true;
|
||||
else if (m_gizmos.is_enabled() && !m_selection.is_empty()) {
|
||||
else if (m_gizmos.is_enabled() && !m_selection.is_empty() && m_canvas_type != CanvasAssembleView) {
|
||||
// auto do_rotate = [this](double angle_z_rad) {
|
||||
// m_selection.start_dragging();
|
||||
// m_selection.rotate(Vec3d(0.0, 0.0, angle_z_rad), TransformationType(TransformationType::World_Relative_Joint));
|
||||
|
@ -3351,6 +3362,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
//BBS do not limit rotate in assemble view
|
||||
camera.rotate_local_with_target(Vec3d(rot.y(), rot.x(), 0.), rotate_target);
|
||||
//camera.rotate_on_sphere_with_target(rot.x(), rot.y(), false, rotate_target);
|
||||
auto clp_dist = m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position();
|
||||
m_gizmos.m_assemble_view_data->model_objects_clipper()->set_position(clp_dist, true);
|
||||
}
|
||||
else {
|
||||
#ifdef SUPPORT_FEEE_CAMERA
|
||||
|
@ -5720,7 +5733,12 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
else
|
||||
m_volumes.set_z_range(-FLT_MAX, FLT_MAX);
|
||||
|
||||
m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
|
||||
if (m_canvas_type == CanvasAssembleView) {
|
||||
m_volumes.set_clipping_plane(m_gizmos.get_assemble_view_clipping_plane().get_data());
|
||||
}
|
||||
else {
|
||||
m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
|
||||
}
|
||||
//BBS: remove sinking logic
|
||||
//m_volumes.set_show_sinking_contours(! m_gizmos.is_hiding_instances());
|
||||
|
||||
|
@ -5761,6 +5779,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
shader->start_using();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case GLVolumeCollection::ERenderType::Transparent:
|
||||
|
@ -5774,6 +5793,12 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
return true;
|
||||
}
|
||||
}, with_outline);
|
||||
if (m_canvas_type == CanvasAssembleView) {
|
||||
const GLGizmosManager& gm = get_gizmos_manager();
|
||||
shader->stop_using();
|
||||
gm.render_painter_assemble_view();
|
||||
shader->start_using();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5959,7 +5984,7 @@ void GLCanvas3D::_render_overlays()
|
|||
|
||||
_check_and_update_toolbar_icon_scale();
|
||||
|
||||
_render_explosion_control();
|
||||
_render_assemble_control();
|
||||
_render_assemble_info();
|
||||
|
||||
// main toolbar and undoredo toolbar need to be both updated before rendering because both their sizes are needed
|
||||
|
@ -6167,6 +6192,8 @@ void GLCanvas3D::_render_gizmos_overlay()
|
|||
const float size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale());
|
||||
m_gizmos.set_overlay_icon_size(size); //! #ys_FIXME_experiment
|
||||
#endif /* __WXMSW__ */
|
||||
if (m_canvas_type == CanvasAssembleView)
|
||||
return;
|
||||
|
||||
m_gizmos.render_overlay();
|
||||
|
||||
|
@ -6664,7 +6691,7 @@ void GLCanvas3D::_render_paint_toolbar() const
|
|||
}
|
||||
|
||||
//BBS
|
||||
void GLCanvas3D::_render_explosion_control() const
|
||||
void GLCanvas3D::_render_assemble_control() const
|
||||
{
|
||||
if (m_canvas_type != ECanvasType::CanvasAssembleView) {
|
||||
GLVolume::explosion_ratio = m_explosion_ratio = 1.0;
|
||||
|
@ -6679,26 +6706,45 @@ void GLCanvas3D::_render_explosion_control() const
|
|||
auto canvas_h = float(get_canvas_size().get_height());
|
||||
|
||||
const float text_padding = 7.0f;
|
||||
ImVec2 text_size = imgui->calc_text_size(_L("Explosion Ratio"));
|
||||
const float slider_width = 130.0f;
|
||||
const float text_size_x = std::max(imgui->calc_text_size(_L("Explosion Ratio")).x, imgui->calc_text_size(_L("Section View")).x);
|
||||
const float slider_width = 75.0f;
|
||||
const float value_size = imgui->calc_text_size("3.00").x + text_padding * 2;
|
||||
const float item_spacing = imgui->get_item_spacing().x;
|
||||
ImVec2 window_padding = ImGui::GetStyle().WindowPadding;
|
||||
ImVec2 window_size = ImVec2(text_size.x + slider_width + value_size + item_spacing * 2 + window_padding.x * 2, window_padding.y * 2 + text_size.y);
|
||||
|
||||
// 13.0f is bottom margin
|
||||
imgui->set_next_window_pos(canvas_w * 0.5 - window_size.x * 0.5, canvas_h - window_size.y - 13.0f, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
imgui->begin(_L("Explosion Ratio"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||
imgui->set_next_window_pos(canvas_w / 2, canvas_h - 13.0f * get_scale(), ImGuiCond_Always, 0.5f, 1.0f);
|
||||
imgui->begin(_L("Assemble Control"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
imgui->text(_L("Explosion Ratio"));
|
||||
ImGui::SameLine(window_padding.x + text_size.x + item_spacing);
|
||||
ImGui::PushItemWidth(slider_width);
|
||||
bool slider_changed = imgui->bbl_slider_float_style("##ratio_slider", &m_explosion_ratio, 1.0f, 3.0f, "%1.2f");
|
||||
|
||||
ImGui::SameLine(window_padding.x + text_size.x + slider_width + item_spacing * 2);
|
||||
ImGui::PushItemWidth(value_size);
|
||||
bool input_changed = ImGui::BBLDragFloat("##ratio_input", &m_explosion_ratio, 0.1f, 1.0f, 3.0f, "%1.2f");
|
||||
{
|
||||
imgui->text(_L("Section View"));
|
||||
|
||||
ImGui::SameLine(window_padding.x + text_size_x + item_spacing);
|
||||
ImGui::PushItemWidth(slider_width);
|
||||
static float clp_dist = 0.f;
|
||||
bool view_slider_changed = imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true);
|
||||
|
||||
ImGui::SameLine(window_padding.x + text_size_x + slider_width + item_spacing * 2);
|
||||
ImGui::PushItemWidth(value_size);
|
||||
bool view_input_changed = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f");
|
||||
|
||||
if (view_slider_changed || view_input_changed)
|
||||
m_gizmos.m_assemble_view_data->model_objects_clipper()->set_position(clp_dist, true);
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::SameLine(window_padding.x + text_size_x + slider_width + item_spacing * 6 + value_size);
|
||||
imgui->text(_L("Explosion Ratio"));
|
||||
|
||||
ImGui::SameLine(window_padding.x + 2 * text_size_x + slider_width + item_spacing * 7 + value_size);
|
||||
ImGui::PushItemWidth(slider_width);
|
||||
bool explosion_slider_changed = imgui->bbl_slider_float_style("##ratio_slider", &m_explosion_ratio, 1.0f, 3.0f, "%1.2f");
|
||||
|
||||
ImGui::SameLine(window_padding.x + 2 * text_size_x + 2 * slider_width + item_spacing * 8 + value_size);
|
||||
ImGui::PushItemWidth(value_size);
|
||||
bool explosion_input_changed = ImGui::BBLDragFloat("##ratio_input", &m_explosion_ratio, 0.1f, 1.0f, 3.0f, "%1.2f");
|
||||
}
|
||||
|
||||
imgui->end();
|
||||
|
||||
|
|
|
@ -978,7 +978,7 @@ private:
|
|||
// BBS
|
||||
//void _render_view_toolbar() const;
|
||||
void _render_paint_toolbar() const;
|
||||
void _render_explosion_control() const;
|
||||
void _render_assemble_control() const;
|
||||
void _render_assemble_info() const;
|
||||
#if ENABLE_SHOW_CAMERA_TARGET
|
||||
void _render_camera_target() const;
|
||||
|
|
|
@ -45,11 +45,20 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
// used to render extrusion and travel paths as lines in gcode preview
|
||||
valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" });
|
||||
// used to render objects in 3d editor
|
||||
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
|
||||
if (0) {
|
||||
valid &= append_shader("gouraud", { "gouraud_130.vs", "gouraud_130.fs" }
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
, { "ENABLE_ENVIRONMENT_MAP"sv }
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
);
|
||||
}
|
||||
else {
|
||||
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
, { "ENABLE_ENVIRONMENT_MAP"sv }
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
);
|
||||
}
|
||||
// used to render variable layers heights in 3d editor
|
||||
valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" });
|
||||
// used to render highlight contour around selected triangles inside the multi-material gizmo
|
||||
|
|
|
@ -25,8 +25,10 @@ wxDEFINE_EVENT(EVT_GLTOOLBAR_PRINT_ALL, SimpleEvent);
|
|||
wxDEFINE_EVENT(EVT_GLTOOLBAR_PRINT_PLATE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_EXPORT_GCODE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_SEND_GCODE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_UPLOAD_GCODE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_EXPORT_SLICED_FILE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_PRINT_SELECT, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER, SimpleEvent);
|
||||
|
||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
||||
|
|
|
@ -25,8 +25,10 @@ wxDECLARE_EVENT(EVT_GLTOOLBAR_PRINT_ALL, SimpleEvent);
|
|||
wxDECLARE_EVENT(EVT_GLTOOLBAR_PRINT_PLATE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_EXPORT_GCODE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_SEND_GCODE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_UPLOAD_GCODE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_EXPORT_SLICED_FILE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_PRINT_SELECT, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER, SimpleEvent);
|
||||
|
||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
||||
|
|
|
@ -280,6 +280,15 @@ public:
|
|||
memDc.SetTextForeground(wxColor(134, 134, 134));
|
||||
memDc.DrawLabel(m_constant_text.version, version_rect, wxALIGN_LEFT | wxALIGN_BOTTOM);
|
||||
|
||||
#if BBL_INTERNAL_TESTING
|
||||
wxSize text_rect = memDc.GetTextExtent("Internal Version");
|
||||
int start_x = (title_rect.GetLeft() + version_rect.GetRight()) / 2 - text_rect.GetWidth();
|
||||
int start_y = version_rect.GetBottom() + 10;
|
||||
wxRect internal_sign_rect(wxPoint(start_x, start_y), wxSize(text_rect));
|
||||
memDc.SetFont(m_constant_text.title_font);
|
||||
memDc.DrawLabel("Internal Version", internal_sign_rect, wxALIGN_TOP | wxALIGN_LEFT);
|
||||
#endif
|
||||
|
||||
// load bitmap for logo
|
||||
BitmapCache bmp_cache;
|
||||
int logo_margin = FromDIP(72 * m_scale);
|
||||
|
@ -545,7 +554,11 @@ private:
|
|||
title = wxGetApp().is_editor() ? SLIC3R_APP_FULL_NAME : GCODEVIEWER_APP_NAME;
|
||||
|
||||
// dynamically get the version to display
|
||||
#if BBL_INTERNAL_TESTING
|
||||
version = _L("Internal Version") + " " + std::string(SLIC3R_VERSION);
|
||||
#else
|
||||
version = _L("Version") + " " + std::string(SLIC3R_VERSION);
|
||||
#endif
|
||||
|
||||
// credits infornation
|
||||
credits = title;
|
||||
|
@ -1052,9 +1065,9 @@ void GUI_App::post_init()
|
|||
}*/
|
||||
|
||||
// BBS: to be checked
|
||||
#if SUPPORT_SHOW_HINTS
|
||||
#if 1
|
||||
// show "Did you know" notification
|
||||
if (app_config->get("show_hints") == "1" && ! is_gcode_viewer())
|
||||
if (app_config->get("show_hints") == "true" && ! is_gcode_viewer())
|
||||
plater_->get_notification_manager()->push_hint_notification(true);
|
||||
#endif
|
||||
|
||||
|
@ -1176,13 +1189,14 @@ GUI_App::GUI_App()
|
|||
{
|
||||
//app config initializes early becasuse it is used in instance checking in BambuStudio.cpp
|
||||
this->init_app_config();
|
||||
this->init_download_path();
|
||||
|
||||
reset_to_active();
|
||||
}
|
||||
|
||||
void GUI_App::shutdown()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "shutdown";
|
||||
BOOST_LOG_TRIVIAL(info) << "GUI_App::shutdown enter";
|
||||
|
||||
if (m_removable_drive_manager) {
|
||||
removable_drive_manager()->shutdown();
|
||||
|
@ -1202,6 +1216,7 @@ void GUI_App::shutdown()
|
|||
delete m_agent;
|
||||
m_agent = nullptr;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "GUI_App::shutdown exit";
|
||||
}
|
||||
|
||||
|
||||
|
@ -1608,6 +1623,8 @@ void GUI_App::init_networking_callbacks()
|
|||
return;
|
||||
}
|
||||
GUI::wxGetApp().CallAfter([this] {
|
||||
if (m_is_closing)
|
||||
return;
|
||||
BOOST_LOG_TRIVIAL(trace) << "static: server connected";
|
||||
m_agent->set_user_selected_machine(m_agent->get_user_selected_machine());
|
||||
});
|
||||
|
@ -1618,6 +1635,8 @@ void GUI_App::init_networking_callbacks()
|
|||
return;
|
||||
}
|
||||
GUI::wxGetApp().CallAfter([this, dev_id] {
|
||||
if (m_is_closing)
|
||||
return;
|
||||
/* request_pushing */
|
||||
MachineObject* obj = m_device_manager->get_my_machine(dev_id);
|
||||
if (obj) {
|
||||
|
@ -1677,6 +1696,8 @@ void GUI_App::init_networking_callbacks()
|
|||
return;
|
||||
}
|
||||
CallAfter([this, dev_id, msg] {
|
||||
if (m_is_closing)
|
||||
return;
|
||||
MachineObject* obj = this->m_device_manager->get_user_machine(dev_id);
|
||||
if (obj) {
|
||||
obj->is_ams_need_update = false;
|
||||
|
@ -1696,6 +1717,8 @@ void GUI_App::init_networking_callbacks()
|
|||
return;
|
||||
}
|
||||
CallAfter([this, dev_id, msg] {
|
||||
if (m_is_closing)
|
||||
return;
|
||||
MachineObject* obj = m_device_manager->get_my_machine(dev_id);
|
||||
if (!obj) {
|
||||
obj = m_device_manager->get_local_machine(dev_id);
|
||||
|
@ -1766,6 +1789,26 @@ static boost::optional<Semver> parse_semver_from_ini(std::string path)
|
|||
return Semver::parse(body);
|
||||
}
|
||||
|
||||
void GUI_App::init_download_path()
|
||||
{
|
||||
std::string down_path = app_config->get("download_path");
|
||||
|
||||
if (down_path.empty()) {
|
||||
std::string user_down_path = wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Downloads).ToUTF8().data();
|
||||
app_config->set("download_path", user_down_path);
|
||||
}
|
||||
else {
|
||||
fs::path dp(down_path);
|
||||
if (!fs::exists(dp)) {
|
||||
|
||||
if (!fs::create_directory(dp)) {
|
||||
std::string user_down_path = wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Downloads).ToUTF8().data();
|
||||
app_config->set("download_path", user_down_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GUI_App::init_app_config()
|
||||
{
|
||||
// Profiles for the alpha are stored into the PrusaSlicer-alpha directory to not mix with the current release.
|
||||
|
@ -1899,7 +1942,8 @@ bool GUI_App::on_init_inner()
|
|||
std::time_t t = std::time(0);
|
||||
std::tm* now_time = std::localtime(&t);
|
||||
std::stringstream buf;
|
||||
buf << std::put_time(now_time, "debug_%a_%b_%d_%H_%M_%S.log");
|
||||
buf << std::put_time(now_time, "debug_%a_%b_%d_%H_%M_%S_");
|
||||
buf << get_current_pid() << ".log";
|
||||
std::string log_filename = buf.str();
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
set_log_path_and_level(log_filename, 5);
|
||||
|
@ -1929,6 +1973,7 @@ bool GUI_App::on_init_inner()
|
|||
#endif
|
||||
|
||||
wxGetApp().Bind(wxEVT_QUERY_END_SESSION, [this](auto & e) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< "received wxEVT_QUERY_END_SESSION";
|
||||
if (mainframe) {
|
||||
wxCloseEvent e2(wxEVT_CLOSE_WINDOW);
|
||||
e2.SetCanVeto(true);
|
||||
|
@ -2097,8 +2142,9 @@ bool GUI_App::on_init_inner()
|
|||
if (!skip_this_version
|
||||
|| evt.GetInt() != 0) {
|
||||
UpdateVersionDialog dialog(this->mainframe);
|
||||
//dialog.update_version_info(extmsg, version_info.version_str);
|
||||
dialog.update_version_info(version_info.description);
|
||||
wxString extmsg = wxString::FromUTF8(version_info.description);
|
||||
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();
|
||||
}
|
||||
|
@ -2719,6 +2765,7 @@ void GUI_App::check_printer_presets()
|
|||
|
||||
void GUI_App::recreate_GUI(const wxString& msg_name)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "recreate_GUI enter";
|
||||
m_is_recreating_gui = true;
|
||||
|
||||
mainframe->shutdown();
|
||||
|
@ -2766,6 +2813,8 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
|
|||
// });
|
||||
|
||||
m_is_recreating_gui = false;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "recreate_GUI exit";
|
||||
}
|
||||
|
||||
void GUI_App::system_info()
|
||||
|
@ -2925,6 +2974,7 @@ void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_max
|
|||
const std::string name = into_u8(window->GetName());
|
||||
|
||||
window->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent &event) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ": received wxEVT_CLOSE_WINDOW, trigger save for window_mainframe";
|
||||
window_pos_save(window, "mainframe");
|
||||
event.Skip();
|
||||
});
|
||||
|
|
|
@ -305,7 +305,8 @@ public:
|
|||
wxGLContext* init_glcontext(wxGLCanvas& canvas);
|
||||
bool init_opengl();
|
||||
|
||||
static unsigned get_colour_approx_luma(const wxColour &colour);
|
||||
void init_download_path();
|
||||
static unsigned get_colour_approx_luma(const wxColour& colour);
|
||||
static bool dark_mode();
|
||||
const wxColour get_label_default_clr_system();
|
||||
const wxColour get_label_default_clr_modified();
|
||||
|
|
|
@ -181,8 +181,7 @@ ObjectList::ObjectList(wxWindow* parent) :
|
|||
entries[index++].Set(wxACCEL_CTRL, (int)'A', wxID_SELECTALL);
|
||||
entries[index++].Set(wxACCEL_CTRL, (int)'Z', wxID_UNDO);
|
||||
entries[index++].Set(wxACCEL_CTRL, (int)'Y', wxID_REDO);
|
||||
entries[index++].Set(wxACCEL_NORMAL, WXK_DELETE, wxID_DELETE);
|
||||
//entries[index++].Set(wxACCEL_NORMAL, WXK_BACK, wxID_DELETE);
|
||||
entries[index++].Set(wxACCEL_NORMAL, WXK_BACK, wxID_DELETE);
|
||||
//entries[index++].Set(wxACCEL_NORMAL, int('+'), wxID_ADD);
|
||||
//entries[index++].Set(wxACCEL_NORMAL, WXK_NUMPAD_ADD, wxID_ADD);
|
||||
//entries[index++].Set(wxACCEL_NORMAL, int('-'), wxID_REMOVE);
|
||||
|
@ -5041,6 +5040,15 @@ void ObjectList::apply_object_instance_transfrom_to_all_volumes(ModelObject *mod
|
|||
const Geometry::Transformation &instance_transformation = model_object->instances[0]->get_transformation();
|
||||
Vec3d original_instance_center = instance_transformation.get_offset();
|
||||
|
||||
// apply the instance_transform(except offset) to assemble_transform
|
||||
Geometry::Transformation instance_transformation_copy = instance_transformation;
|
||||
instance_transformation_copy.set_offset(Vec3d(0, 0, 0)); // remove the effect of offset
|
||||
const Transform3d & instance_inverse_matrix = instance_transformation_copy.get_matrix().inverse();
|
||||
const Transform3d & assemble_matrix = model_object->instances[0]->get_assemble_transformation().get_matrix();
|
||||
Transform3d new_assemble_transform = assemble_matrix * instance_inverse_matrix;
|
||||
model_object->instances[0]->set_assemble_from_transform(new_assemble_transform);
|
||||
|
||||
// apply the instance_transform to volumn
|
||||
const Transform3d &transformation_matrix = instance_transformation.get_matrix();
|
||||
for (ModelVolume *volume : model_object->volumes) {
|
||||
const Transform3d &volume_matrix = volume->get_matrix();
|
||||
|
|
|
@ -2681,6 +2681,7 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi
|
|||
SetSize(wxSize(-1, FromDIP(450)));
|
||||
SetMinSize(wxSize(-1, FromDIP(450)));
|
||||
SetMaxSize(wxSize(-1, FromDIP(450)));
|
||||
|
||||
|
||||
//m_search_line = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
|
||||
|
||||
|
@ -3228,7 +3229,7 @@ void ObjectTablePanel::resetAllValuesInSideWindow(int row, bool is_object, Model
|
|||
// ObjectTableDialog
|
||||
// ----------------------------------------------------------------------------
|
||||
ObjectTableDialog::ObjectTableDialog(wxWindow* parent, Plater* platerObj, Model *modelObj, wxSize maxSize)
|
||||
: GUI::DPIDialog(parent, wxID_ANY, _L("Object/Part Setting"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
|
||||
: GUI::DPIDialog(parent, wxID_ANY, _L("Object/Part Setting"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER)
|
||||
,
|
||||
m_model(modelObj), m_plater(platerObj)
|
||||
{
|
||||
|
@ -3369,12 +3370,27 @@ void ObjectTableDialog::OnText(wxKeyEvent &evt)
|
|||
|
||||
void ObjectTableDialog::OnSize(wxSizeEvent& event)
|
||||
{
|
||||
wxSize new_size = event.GetSize();
|
||||
/* wxSize new_size = event.GetSize();
|
||||
if ((new_size.GetWidth() > g_dialog_max_width) || (new_size.GetHeight() > g_dialog_max_height)) {
|
||||
int width = (new_size.GetWidth() > g_dialog_max_width) ? new_size.GetWidth() : g_dialog_max_width;
|
||||
int width = (new_size.GetWidth() > g_dialog_max_width) ? new_size.GetWidth() : g_dialog_max_width;
|
||||
int height = (new_size.GetHeight() > g_dialog_max_height) ? new_size.GetHeight() : g_dialog_max_height;
|
||||
this->SetMaxSize(wxSize(width, height));
|
||||
}*/
|
||||
|
||||
if (event.GetSize().y <= FromDIP(450)) {
|
||||
SetMaxSize(wxSize(GetSize().x, -1));
|
||||
SetMinSize(wxSize(GetSize().x, -1));
|
||||
SetSize(wxSize(GetSize().x, -1));
|
||||
return;
|
||||
}
|
||||
SetMaxSize(wxSize(GetSize().x, -1));
|
||||
SetMinSize(wxSize(GetSize().x, -1));
|
||||
SetSize(wxSize(GetSize().x, -1));
|
||||
|
||||
m_obj_panel->SetSize(wxSize(-1, GetSize().y));
|
||||
m_obj_panel->SetMinSize(wxSize(-1, GetSize().y));
|
||||
m_obj_panel->SetMaxSize(wxSize(-1, GetSize().y));
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
|
|
@ -506,7 +506,8 @@ void Preview::update_layers_slider_from_canvas(wxKeyEvent &event)
|
|||
IMSlider *m_layers_slider = m_canvas->get_gcode_viewer().get_layers_slider();
|
||||
IMSlider *m_moves_slider = m_canvas->get_gcode_viewer().get_moves_slider();
|
||||
if (key == 'L') {
|
||||
m_layers_slider->switch_one_layer_mode();
|
||||
if(!m_layers_slider->switch_one_layer_mode())
|
||||
event.Skip();
|
||||
m_canvas->set_as_dirty();
|
||||
}
|
||||
/*else if (key == WXK_SHIFT)
|
||||
|
@ -767,7 +768,7 @@ bool AssembleView::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrint
|
|||
m_canvas->set_process(process);
|
||||
m_canvas->set_type(GLCanvas3D::ECanvasType::CanvasAssembleView);
|
||||
m_canvas->set_config(config);
|
||||
m_canvas->enable_gizmos(false);
|
||||
m_canvas->enable_gizmos(true);
|
||||
m_canvas->enable_selection(true);
|
||||
m_canvas->enable_main_toolbar(false);
|
||||
m_canvas->enable_labels(false);
|
||||
|
|
|
@ -438,7 +438,7 @@ void GLGizmoAdvancedCut::on_render_input_window(float x, float y, float bottom_l
|
|||
|
||||
// Rotation input box
|
||||
ImGui::PushItemWidth(caption_size);
|
||||
m_imgui->text(_L("Rotation:"));
|
||||
m_imgui->text(_L("Rotation") + " ");
|
||||
ImGui::SameLine(caption_size + 1 * space_size);
|
||||
ImGui::PushItemWidth(unit_size);
|
||||
ImGui::BBLInputDouble("##cut_rotation_x", &rotation[0], 0.0f, 0.0f, "%.2f");
|
||||
|
@ -471,7 +471,7 @@ void GLGizmoAdvancedCut::on_render_input_window(float x, float y, float bottom_l
|
|||
double movement = m_movement;
|
||||
ImGui::PushItemWidth(caption_size);
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(_L("Movement:"));
|
||||
m_imgui->text(_L("Movement") + " ");
|
||||
ImGui::SameLine(caption_size + 1 * space_size);
|
||||
ImGui::PushItemWidth(3 * unit_size + 2 * space_size);
|
||||
ImGui::BBLInputDouble("##cut_movement", &movement, 0.0f, 0.0f, "%.2f");
|
||||
|
@ -497,7 +497,7 @@ void GLGizmoAdvancedCut::on_render_input_window(float x, float y, float bottom_l
|
|||
double height = m_height;
|
||||
ImGui::PushItemWidth(caption_size);
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(_L("Height:"));
|
||||
m_imgui->text(_L("Height") + " ");
|
||||
ImGui::SameLine(caption_size + 1 * space_size);
|
||||
ImGui::PushItemWidth(3 * unit_size + 2 * space_size);
|
||||
ImGui::BBLInputDouble("##cut_height", &height, 0.0f, 0.0f, "%.2f");
|
||||
|
|
|
@ -79,23 +79,25 @@ bool GLGizmoFdmSupports::on_init()
|
|||
// BBS
|
||||
m_shortcut_key = WXK_CONTROL_L;
|
||||
|
||||
m_desc["clipping_of_view"] = _L("Section view") + ": ";
|
||||
m_desc["cursor_size"] = _L("Pen size") + ": ";
|
||||
m_desc["enforce_caption"] = _L("Left mouse button") + ": ";
|
||||
m_desc["clipping_of_view_caption"] = _L("Alt + Mouse wheel");
|
||||
m_desc["clipping_of_view"] = _L("Section view");
|
||||
m_desc["cursor_size_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["cursor_size"] = _L("Pen size");
|
||||
m_desc["enforce_caption"] = _L("Left mouse button");
|
||||
m_desc["enforce"] = _L("Enforce supports");
|
||||
m_desc["block_caption"] = _L("Right mouse button") + ": ";
|
||||
m_desc["block_caption"] = _L("Right mouse button");
|
||||
m_desc["block"] = _L("Block supports");
|
||||
m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": ";
|
||||
m_desc["remove"] = _L("Erase painting");
|
||||
m_desc["remove_caption"] = _L("Shift + Left mouse button");
|
||||
m_desc["remove"] = _L("Erase");
|
||||
m_desc["remove_all"] = _L("Erase all painting");
|
||||
m_desc["highlight_by_angle"] = _L("Highlight overhang areas") + ": ";
|
||||
m_desc["highlight_by_angle"] = _L("Highlight overhang areas");
|
||||
m_desc["gap_fill"] = _L("Gap fill");
|
||||
m_desc["perform"] = _L("Perform");
|
||||
m_desc["gap_area_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["gap_area"] = _L("Gap area");
|
||||
m_desc["brush_size"] = _L("Set pen size");
|
||||
m_desc["brush_size_caption"] = _L("Ctrl + Mouse wheel") + ": ";
|
||||
m_desc["tool_type"] = _L("Tool type");
|
||||
m_desc["smart_fill_angle"] = _L("Smart fill angle") + ": ";
|
||||
m_desc["smart_fill_angle_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["smart_fill_angle"] = _L("Smart fill angle");
|
||||
|
||||
memset(&m_print_instance, sizeof(m_print_instance), 0);
|
||||
return true;
|
||||
|
@ -224,7 +226,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
|
||||
float caption_max = 0.f;
|
||||
float total_text_max = 0.f;
|
||||
for (const auto &t : std::array<std::string, 4>{"enforce", "block", "remove", "brush_size"}) {
|
||||
for (const auto &t : std::array<std::string, 5>{"enforce", "block", "remove", "cursor_size", "clipping_of_view"}) {
|
||||
caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x);
|
||||
total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x);
|
||||
}
|
||||
|
@ -461,6 +463,8 @@ void GLGizmoFdmSupports::show_tooltip_information(float caption_max, float x, fl
|
|||
ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP);
|
||||
ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER);
|
||||
|
||||
caption_max += m_imgui->calc_text_size(": ").x + 15.f;
|
||||
|
||||
float font_size = ImGui::GetFontSize();
|
||||
ImVec2 button_size = ImVec2(font_size * 1.8, font_size * 1.3);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
|
||||
|
@ -475,7 +479,24 @@ void GLGizmoFdmSupports::show_tooltip_information(float caption_max, float x, fl
|
|||
m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text);
|
||||
};
|
||||
|
||||
for (const auto &t : std::array<std::string, 4>{"enforce", "block", "remove", "brush_size"}) draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t));
|
||||
std::vector<std::string> tip_items;
|
||||
switch (m_tool_type) {
|
||||
case ToolType::BRUSH:
|
||||
tip_items = {"enforce", "block", "remove", "cursor_size", "clipping_of_view"};
|
||||
break;
|
||||
case ToolType::BUCKET_FILL:
|
||||
break;
|
||||
case ToolType::SMART_FILL:
|
||||
tip_items = {"enforce", "block", "remove", "smart_fill_angle", "clipping_of_view"};
|
||||
break;
|
||||
case ToolType::GAP_FILL:
|
||||
tip_items = {"gap_area"};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (const auto &t : tip_items) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t));
|
||||
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
|
|
|
@ -97,18 +97,20 @@ bool GLGizmoMmuSegmentation::on_init()
|
|||
// BBS
|
||||
m_shortcut_key = WXK_CONTROL_N;
|
||||
|
||||
m_desc["clipping_of_view"] = _L("Section view") + ": ";
|
||||
m_desc["cursor_size"] = _L("Pen size") + ": ";
|
||||
m_desc["clipping_of_view_caption"] = _L("Alt + Mouse wheel");
|
||||
m_desc["clipping_of_view"] = _L("Section view");
|
||||
m_desc["cursor_size_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["cursor_size"] = _L("Pen size");
|
||||
m_desc["cursor_type"] = _L("Pen shape");
|
||||
|
||||
// BBS
|
||||
m_desc["paint_caption"] = _L("Left mouse button") + ": ";
|
||||
m_desc["paint_caption"] = _L("Left mouse button");
|
||||
m_desc["paint"] = _L("Paint");
|
||||
m_desc["erase_caption"] = _L("Right mouse button") + ": ";
|
||||
m_desc["erase_caption"] = _L("Shift + Left mouse button");
|
||||
m_desc["erase"] = _L("Erase");
|
||||
m_desc["shortcut_key_caption"] = _L("Key 1~9") + ": ";
|
||||
m_desc["shortcut_key_caption"] = _L("Key 1~9");
|
||||
m_desc["shortcut_key"] = _L("Choose filament");
|
||||
m_desc["edge_detection"] = _L("Edge detection");
|
||||
m_desc["gap_area_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["gap_area"] = _L("Gap area");
|
||||
m_desc["perform"] = _L("Perform");
|
||||
|
||||
|
@ -123,12 +125,10 @@ bool GLGizmoMmuSegmentation::on_init()
|
|||
m_desc["tool_smart_fill"] = _L("Smart fill");
|
||||
m_desc["tool_bucket_fill"] = _L("Bucket fill");
|
||||
|
||||
m_desc["smart_fill_angle_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["smart_fill_angle"] = _L("Smart fill angle");
|
||||
|
||||
m_desc["brush_size"] = _L("Set pen size");
|
||||
m_desc["brush_size_caption"] = _L("Ctrl + Mouse wheel") + ": ";
|
||||
|
||||
// BBS
|
||||
m_desc["height_range_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["height_range"] = _L("Height range");
|
||||
|
||||
init_extruders_data();
|
||||
|
@ -297,6 +297,8 @@ void GLGizmoMmuSegmentation::show_tooltip_information(float caption_max, float x
|
|||
ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP);
|
||||
ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER);
|
||||
|
||||
caption_max += m_imgui->calc_text_size(": ").x + 15.f;
|
||||
|
||||
float font_size = ImGui::GetFontSize();
|
||||
ImVec2 button_size = ImVec2(font_size * 1.8, font_size * 1.3);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
|
||||
|
@ -310,7 +312,24 @@ void GLGizmoMmuSegmentation::show_tooltip_information(float caption_max, float x
|
|||
m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text);
|
||||
};
|
||||
|
||||
for (const auto &t : std::array<std::string, 3>{"paint", "erase", "brush_size"}) draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t));
|
||||
std::vector<std::string> tip_items;
|
||||
switch (m_tool_type) {
|
||||
case ToolType::BRUSH:
|
||||
tip_items = {"paint", "erase", "cursor_size", "clipping_of_view"};
|
||||
break;
|
||||
case ToolType::BUCKET_FILL:
|
||||
tip_items = {"paint", "erase", "smart_fill_angle", "clipping_of_view"};
|
||||
break;
|
||||
case ToolType::SMART_FILL:
|
||||
// TODO:
|
||||
break;
|
||||
case ToolType::GAP_FILL:
|
||||
tip_items = {"gap_area"};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (const auto &t : tip_items) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
|
@ -347,7 +366,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||
|
||||
float caption_max = 0.f;
|
||||
float total_text_max = 0.f;
|
||||
for (const auto &t : std::array<std::string, 3>{"paint", "erase", "brush_size"}) {
|
||||
for (const auto &t : std::array<std::string, 6>{"paint", "erase", "cursor_size", "smart_fill_angle", "height_range", "clipping_of_view"}) {
|
||||
caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x);
|
||||
total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x);
|
||||
}
|
||||
|
@ -537,7 +556,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
|
|||
|
||||
if (m_detect_geometry_edge) {
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(m_desc["smart_fill_angle"] + ":");
|
||||
m_imgui->text(m_desc["smart_fill_angle"]);
|
||||
std::string format_str = std::string("%.f") + I18N::translate_utf8("°", "Face angle threshold,"
|
||||
"placed after the number with no whitespace in between.");
|
||||
ImGui::SameLine(sliders_left_width);
|
||||
|
|
|
@ -90,7 +90,7 @@ protected:
|
|||
void on_set_state() override;
|
||||
|
||||
EnforcerBlockerType get_left_button_state_type() const override { return EnforcerBlockerType(m_selected_extruder_idx + 1); }
|
||||
EnforcerBlockerType get_right_button_state_type() const override { return EnforcerBlockerType::NONE; }
|
||||
EnforcerBlockerType get_right_button_state_type() const override { return EnforcerBlockerType(-1); }
|
||||
|
||||
void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||
std::string on_get_name() const override;
|
||||
|
|
|
@ -495,21 +495,22 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
if (action == SLAGizmoEventType::MouseWheelUp
|
||||
|| action == SLAGizmoEventType::MouseWheelDown) {
|
||||
if (control_down) {
|
||||
//BBS
|
||||
if (m_tool_type == ToolType::BRUSH && m_cursor_type == TriangleSelector::CursorType::HEIGHT_RANGE) {
|
||||
m_cursor_height = action == SLAGizmoEventType::MouseWheelDown ? std::max(m_cursor_height - this->get_cursor_height_step(), this->get_cursor_height_min()) :
|
||||
std::min(m_cursor_height + this->get_cursor_height_step(), this->get_cursor_height_max());
|
||||
m_parent.set_as_dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_tool_type == ToolType::BRUSH && (m_cursor_type == TriangleSelector::CursorType::SPHERE || m_cursor_type == TriangleSelector::CursorType::CIRCLE)) {
|
||||
m_cursor_radius = action == SLAGizmoEventType::MouseWheelDown ? std::max(m_cursor_radius - this->get_cursor_radius_step(), this->get_cursor_radius_min()) :
|
||||
std::min(m_cursor_radius + this->get_cursor_radius_step(), this->get_cursor_radius_max());
|
||||
m_parent.set_as_dirty();
|
||||
return true;
|
||||
}
|
||||
double pos = m_c->object_clipper()->get_position();
|
||||
pos = action == SLAGizmoEventType::MouseWheelDown
|
||||
? std::max(0., pos - 0.01)
|
||||
: std::min(1., pos + 0.01);
|
||||
m_c->object_clipper()->set_position(pos, true);
|
||||
return true;
|
||||
}
|
||||
else if (alt_down) {
|
||||
if (m_tool_type == ToolType::SMART_FILL) {
|
||||
|
||||
if (m_tool_type == ToolType::BUCKET_FILL || m_tool_type == ToolType::SMART_FILL) {
|
||||
m_smart_fill_angle = action == SLAGizmoEventType::MouseWheelDown ? std::max(m_smart_fill_angle - SmartFillAngleStep, SmartFillAngleMin)
|
||||
: std::min(m_smart_fill_angle + SmartFillAngleStep, SmartFillAngleMax);
|
||||
m_parent.set_as_dirty();
|
||||
|
@ -527,7 +528,22 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (m_tool_type == ToolType::GAP_FILL) {
|
||||
TriangleSelectorPatch::gap_area = action == SLAGizmoEventType::MouseWheelDown ?
|
||||
std::max(TriangleSelectorPatch::gap_area - TriangleSelectorPatch::GapAreaStep, TriangleSelectorPatch::GapAreaMin) :
|
||||
std::min(TriangleSelectorPatch::gap_area + TriangleSelectorPatch::GapAreaStep, TriangleSelectorPatch::GapAreaMax);
|
||||
m_parent.set_as_dirty();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (alt_down) {
|
||||
// BBS
|
||||
double pos = m_c->object_clipper()->get_position();
|
||||
pos = action == SLAGizmoEventType::MouseWheelDown
|
||||
? std::max(0., pos - 0.01)
|
||||
: std::min(1., pos + 0.01);
|
||||
m_c->object_clipper()->set_position(pos, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,6 +560,16 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
return false;
|
||||
|
||||
EnforcerBlockerType new_state = EnforcerBlockerType::NONE;
|
||||
// BBS
|
||||
if (action == SLAGizmoEventType::Dragging) {
|
||||
if (m_button_down == Button::Right && this->get_right_button_state_type() == EnforcerBlockerType(-1))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (action == SLAGizmoEventType::RightDown && this->get_right_button_state_type() == EnforcerBlockerType(-1))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! shift_down) {
|
||||
if (action == SLAGizmoEventType::Dragging)
|
||||
new_state = m_button_down == Button::Left ? this->get_left_button_state_type() : this->get_right_button_state_type();
|
||||
|
|
|
@ -142,6 +142,7 @@ public:
|
|||
|
||||
constexpr static float GapAreaMin = 0.f;
|
||||
constexpr static float GapAreaMax = 5.f;
|
||||
constexpr static float GapAreaStep = 0.2f;
|
||||
|
||||
// BBS: fix me
|
||||
static float gap_area;
|
||||
|
|
|
@ -120,16 +120,6 @@ 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))
|
||||
|
|
|
@ -29,16 +29,18 @@ bool GLGizmoSeam::on_init()
|
|||
{
|
||||
m_shortcut_key = WXK_CONTROL_P;
|
||||
|
||||
m_desc["clipping_of_view"] = _L("Section view") + ": ";
|
||||
m_desc["clipping_of_view_caption"] = _L("Alt + Mouse wheel");
|
||||
m_desc["clipping_of_view"] = _L("Section view");
|
||||
m_desc["reset_direction"] = _L("Reset direction");
|
||||
m_desc["cursor_size"] = _L("Brush size") + ": ";
|
||||
m_desc["cursor_type"] = _L("Brush shape") + ": ";
|
||||
m_desc["enforce_caption"] = _L("Left mouse button") + ": ";
|
||||
m_desc["cursor_size_caption"] = _L("Ctrl + Mouse wheel");
|
||||
m_desc["cursor_size"] = _L("Brush size");
|
||||
m_desc["cursor_type"] = _L("Brush shape");
|
||||
m_desc["enforce_caption"] = _L("Left mouse button");
|
||||
m_desc["enforce"] = _L("Enforce seam");
|
||||
m_desc["block_caption"] = _L("Right mouse button") + ": ";
|
||||
m_desc["block_caption"] = _L("Right mouse button");
|
||||
m_desc["block"] = _L("Block seam");
|
||||
m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": ";
|
||||
m_desc["remove"] = _L("Remove selection");
|
||||
m_desc["remove_caption"] = _L("Shift + Left mouse button");
|
||||
m_desc["remove"] = _L("Erase");
|
||||
m_desc["remove_all"] = _L("Erase all painting");
|
||||
m_desc["circle"] = _L("Circle");
|
||||
m_desc["sphere"] = _L("Sphere");
|
||||
|
@ -125,6 +127,8 @@ void GLGizmoSeam::show_tooltip_information(float caption_max, float x, float y)
|
|||
ImTextureID normal_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP);
|
||||
ImTextureID hover_id = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER);
|
||||
|
||||
caption_max += m_imgui->calc_text_size(": ").x + 35.f;
|
||||
|
||||
float font_size = ImGui::GetFontSize();
|
||||
ImVec2 button_size = ImVec2(font_size * 1.8, font_size * 1.3);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
|
||||
|
@ -138,7 +142,7 @@ void GLGizmoSeam::show_tooltip_information(float caption_max, float x, float y)
|
|||
m_imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text);
|
||||
};
|
||||
|
||||
for (const auto &t : std::array<std::string, 3>{"enforce", "block", "remove"}) draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t));
|
||||
for (const auto &t : std::array<std::string, 5>{"enforce", "block", "remove", "cursor_size", "clipping_of_view"}) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
|
@ -187,7 +191,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||
|
||||
float caption_max = 0.f;
|
||||
float total_text_max = 0.f;
|
||||
for (const auto &t : std::array<std::string, 3>{"enforce", "block", "remove"}) {
|
||||
for (const auto &t : std::array<std::string, 6>{"enforce", "block", "remove", "cursor_size", "clipping_of_view"}) {
|
||||
caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x);
|
||||
total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x);
|
||||
}
|
||||
|
|
|
@ -141,35 +141,6 @@ std::string GLGizmoSimplify::on_get_name() const
|
|||
return _u8L("Simplify");
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::push_simplify_style()
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowTitleAlign, ImVec2(0.05f, 0.50f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(50 / 255.0f, 58 / 255.0f, 61 / 255.0f, 1.00f)); // 1
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGuiWrapper::COL_WINDOW_BG); // 2
|
||||
ImGui::PushStyleColor(ImGuiCol_TitleBg, ImGuiWrapper::COL_TITLE_BG); // 3
|
||||
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImGuiWrapper::COL_TITLE_BG); // 4
|
||||
ImGui::PushStyleColor(ImGuiCol_Separator, ImGuiWrapper::COL_SEPARATOR); // 5
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.00f, 1.00f, 1.00f, 1.00f)); // 6
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); // 7
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); // 8
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.00f)); // 9
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.00f)); // 10
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 0.00f)); // 11
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.00f, 1.00f, 1.00f, 1.00f)); // 12
|
||||
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, ImGuiWrapper::COL_GREEN_LIGHT);
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.00f, 0.68f, 0.26f, 1.00f));
|
||||
|
||||
}
|
||||
void GLGizmoSimplify::pop_simplify_style()
|
||||
{
|
||||
ImGui::PopStyleColor(14);
|
||||
ImGui::PopStyleVar(5);
|
||||
}
|
||||
|
||||
void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limit)
|
||||
{
|
||||
create_gui_cfg();
|
||||
|
@ -260,7 +231,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
|
||||
float slider_width = m_imgui->scaled(5.0f);
|
||||
|
||||
push_simplify_style();
|
||||
m_imgui->push_common_window_style(m_parent.get_scale());
|
||||
int flag = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoCollapse;
|
||||
m_imgui->begin(on_get_name(), flag);
|
||||
|
@ -412,7 +383,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||
ImGui::PopStyleColor(1);
|
||||
|
||||
m_imgui->end();
|
||||
pop_simplify_style();
|
||||
m_imgui->pop_common_window_style();
|
||||
if (start_process)
|
||||
process();
|
||||
}
|
||||
|
|
|
@ -48,8 +48,6 @@ private:
|
|||
void process();
|
||||
void stop_worker_thread_request();
|
||||
void worker_finished();
|
||||
void push_simplify_style();
|
||||
void pop_simplify_style();
|
||||
|
||||
void create_gui_cfg();
|
||||
void request_rerender(bool force = false);
|
||||
|
|
|
@ -541,5 +541,172 @@ void SupportsClipper::render_cut() const
|
|||
}
|
||||
|
||||
|
||||
|
||||
using namespace AssembleViewDataObjects;
|
||||
AssembleViewDataPool::AssembleViewDataPool(GLCanvas3D* canvas)
|
||||
: m_canvas(canvas)
|
||||
{
|
||||
using c = AssembleViewDataID;
|
||||
m_data[c::ModelObjectsInfo].reset(new ModelObjectsInfo(this));
|
||||
m_data[c::ModelObjectsClipper].reset(new ModelObjectsClipper(this));
|
||||
}
|
||||
|
||||
void AssembleViewDataPool::update(AssembleViewDataID required)
|
||||
{
|
||||
assert(check_dependencies(required));
|
||||
for (auto& [id, data] : m_data) {
|
||||
if (int(required) & int(AssembleViewDataID(id)))
|
||||
data->update();
|
||||
else
|
||||
if (data->is_valid())
|
||||
data->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ModelObjectsInfo* AssembleViewDataPool::model_objects_info() const
|
||||
{
|
||||
ModelObjectsInfo* sel_info = dynamic_cast<ModelObjectsInfo*>(m_data.at(AssembleViewDataID::ModelObjectsInfo).get());
|
||||
assert(sel_info);
|
||||
return sel_info->is_valid() ? sel_info : nullptr;
|
||||
}
|
||||
|
||||
|
||||
ModelObjectsClipper* AssembleViewDataPool::model_objects_clipper() const
|
||||
{
|
||||
ModelObjectsClipper* oc = dynamic_cast<ModelObjectsClipper*>(m_data.at(AssembleViewDataID::ModelObjectsClipper).get());
|
||||
// ObjectClipper is used from outside the gizmos to report current clipping plane.
|
||||
// This function can be called when oc is nullptr.
|
||||
return (oc && oc->is_valid()) ? oc : nullptr;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Check the required resources one by one and return true if all
|
||||
// dependencies are met.
|
||||
bool AssembleViewDataPool::check_dependencies(AssembleViewDataID required) const
|
||||
{
|
||||
// This should iterate over currently required data. Each of them should
|
||||
// be asked about its dependencies and it must check that all dependencies
|
||||
// are also in required and before the current one.
|
||||
for (auto& [id, data] : m_data) {
|
||||
// in case we don't use this, the deps are irrelevant
|
||||
if (!(int(required) & int(AssembleViewDataID(id))))
|
||||
continue;
|
||||
|
||||
|
||||
AssembleViewDataID deps = data->get_dependencies();
|
||||
assert(int(deps) == (int(deps) & int(required)));
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
|
||||
|
||||
|
||||
void ModelObjectsInfo::on_update()
|
||||
{
|
||||
if (!get_pool()->get_canvas()->get_model()->objects.empty()) {
|
||||
m_model_objects = get_pool()->get_canvas()->get_model()->objects;
|
||||
}
|
||||
}
|
||||
|
||||
void ModelObjectsInfo::on_release()
|
||||
{
|
||||
m_model_objects.clear();
|
||||
}
|
||||
|
||||
//int ModelObjectsInfo::get_active_instance() const
|
||||
//{
|
||||
// const Selection& selection = get_pool()->get_canvas()->get_selection();
|
||||
// return selection.get_instance_idx();
|
||||
//}
|
||||
|
||||
|
||||
void ModelObjectsClipper::on_update()
|
||||
{
|
||||
const ModelObjectPtrs model_objects = get_pool()->model_objects_info()->model_objects();
|
||||
if (model_objects.empty())
|
||||
return;
|
||||
|
||||
// which mesh should be cut?
|
||||
std::vector<const TriangleMesh*> meshes;
|
||||
|
||||
if (meshes.empty())
|
||||
for (auto mo : model_objects) {
|
||||
for (const ModelVolume* mv : mo->volumes)
|
||||
meshes.push_back(&mv->mesh());
|
||||
}
|
||||
|
||||
if (meshes != m_old_meshes) {
|
||||
m_clippers.clear();
|
||||
for (const TriangleMesh* mesh : meshes) {
|
||||
m_clippers.emplace_back(new MeshClipper);
|
||||
m_clippers.back()->set_mesh(*mesh);
|
||||
}
|
||||
m_old_meshes = meshes;
|
||||
|
||||
m_active_inst_bb_radius = get_pool()->get_canvas()->volumes_bounding_box().radius();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ModelObjectsClipper::on_release()
|
||||
{
|
||||
m_clippers.clear();
|
||||
m_old_meshes.clear();
|
||||
m_clp.reset();
|
||||
m_clp_ratio = 0.;
|
||||
|
||||
}
|
||||
|
||||
void ModelObjectsClipper::render_cut() const
|
||||
{
|
||||
if (m_clp_ratio == 0.)
|
||||
return;
|
||||
const ModelObjectPtrs model_objects = get_pool()->model_objects_info()->model_objects();
|
||||
|
||||
size_t clipper_id = 0;
|
||||
for (const ModelObject* mo : model_objects) {
|
||||
Geometry::Transformation assemble_objects_trafo = mo->instances[0]->get_assemble_transformation();
|
||||
auto offset_to_assembly = mo->instances[0]->get_offset_to_assembly();
|
||||
for (const ModelVolume* mv : mo->volumes) {
|
||||
Geometry::Transformation vol_trafo = mv->get_transformation();
|
||||
Geometry::Transformation trafo = assemble_objects_trafo * vol_trafo;
|
||||
trafo.set_offset(trafo.get_offset() + vol_trafo.get_offset() * (GLVolume::explosion_ratio - 1.0) + offset_to_assembly * (GLVolume::explosion_ratio - 1.0));
|
||||
|
||||
auto& clipper = m_clippers[clipper_id];
|
||||
clipper->set_plane(*m_clp);
|
||||
clipper->set_transformation(trafo);
|
||||
glsafe(::glPushMatrix());
|
||||
// BBS
|
||||
glsafe(::glColor3f(0.25f, 0.25f, 0.25f));
|
||||
clipper->render_cut();
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
++clipper_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ModelObjectsClipper::set_position(double pos, bool keep_normal)
|
||||
{
|
||||
Vec3d camera_dir = wxGetApp().plater()->get_camera().get_dir_forward();
|
||||
Vec3d normal = -camera_dir;
|
||||
const Vec3d& center = get_pool()->get_canvas()->volumes_bounding_box().center();
|
||||
float dist = normal.dot(center);
|
||||
|
||||
if (pos < 0.)
|
||||
pos = m_clp_ratio;
|
||||
|
||||
m_clp_ratio = pos;
|
||||
m_clp.reset(new ClippingPlane(normal, (dist - (-m_active_inst_bb_radius * GLVolume::explosion_ratio) - m_clp_ratio * 2 * m_active_inst_bb_radius * GLVolume::explosion_ratio)));
|
||||
get_pool()->get_canvas()->set_as_dirty();
|
||||
}
|
||||
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -39,6 +39,7 @@ enum class SLAGizmoEventType : unsigned char {
|
|||
|
||||
|
||||
class CommonGizmosDataBase;
|
||||
class AssembleViewDataBase;
|
||||
namespace CommonGizmosDataObjects {
|
||||
class SelectionInfo;
|
||||
class InstancesHider;
|
||||
|
@ -48,6 +49,11 @@ namespace CommonGizmosDataObjects {
|
|||
class SupportsClipper;
|
||||
}
|
||||
|
||||
namespace AssembleViewDataObjects {
|
||||
class ModelObjectsInfo;
|
||||
class ModelObjectsClipper;
|
||||
}
|
||||
|
||||
// Some of the gizmos use the same data that need to be updated ocassionally.
|
||||
// It is also desirable that the data are not recalculated when the gizmos
|
||||
// are just switched, but on the other hand, they should be released when
|
||||
|
@ -306,9 +312,120 @@ private:
|
|||
} // namespace CommonGizmosDataObjects
|
||||
|
||||
|
||||
enum class AssembleViewDataID {
|
||||
None = 0,
|
||||
ModelObjectsInfo = 1 << 0,
|
||||
ModelObjectsClipper = 1 << 4,
|
||||
};
|
||||
|
||||
class AssembleViewDataPool {
|
||||
public:
|
||||
AssembleViewDataPool(GLCanvas3D* canvas);
|
||||
|
||||
// Update all resources and release what is not used.
|
||||
// Accepts a bitmask of currently required resources.
|
||||
void update(AssembleViewDataID required);
|
||||
|
||||
// Getters for the data that need to be accessed from the gizmos directly.
|
||||
AssembleViewDataObjects::ModelObjectsInfo* model_objects_info() const;
|
||||
AssembleViewDataObjects::ModelObjectsClipper* model_objects_clipper() const;
|
||||
|
||||
GLCanvas3D* get_canvas() const { return m_canvas; }
|
||||
|
||||
private:
|
||||
std::map<AssembleViewDataID, std::unique_ptr<AssembleViewDataBase>> m_data;
|
||||
GLCanvas3D* m_canvas;
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool check_dependencies(AssembleViewDataID required) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Base class for a wrapper object managing a single resource.
|
||||
// Each of the enum values above (safe None) will have an object of this kind.
|
||||
class AssembleViewDataBase {
|
||||
public:
|
||||
// Pass a backpointer to the pool, so the individual
|
||||
// objects can communicate with one another.
|
||||
explicit AssembleViewDataBase(AssembleViewDataPool* cgdp)
|
||||
: m_common{ cgdp } {}
|
||||
virtual ~AssembleViewDataBase() {}
|
||||
|
||||
// Update the resource.
|
||||
void update() { on_update(); m_is_valid = true; }
|
||||
|
||||
// Release any data that are stored internally.
|
||||
void release() { on_release(); m_is_valid = false; }
|
||||
|
||||
// Returns whether the resource is currently maintained.
|
||||
bool is_valid() const { return m_is_valid; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Return a bitmask of all resources that this one relies on.
|
||||
// The dependent resource must have higher ID than the one
|
||||
// it depends on.
|
||||
virtual AssembleViewDataID get_dependencies() const { return AssembleViewDataID::None; }
|
||||
#endif // NDEBUG
|
||||
|
||||
protected:
|
||||
virtual void on_release() = 0;
|
||||
virtual void on_update() = 0;
|
||||
AssembleViewDataPool* get_pool() const { return m_common; }
|
||||
|
||||
|
||||
private:
|
||||
bool m_is_valid = false;
|
||||
AssembleViewDataPool* m_common = nullptr;
|
||||
};
|
||||
|
||||
namespace AssembleViewDataObjects
|
||||
{
|
||||
class ModelObjectsInfo : public AssembleViewDataBase
|
||||
{
|
||||
public:
|
||||
explicit ModelObjectsInfo(AssembleViewDataPool* cgdp)
|
||||
: AssembleViewDataBase(cgdp) {}
|
||||
|
||||
ModelObjectPtrs model_objects() const { return m_model_objects; }
|
||||
//int get_active_instance() const;
|
||||
float get_sla_shift() const { return m_z_shift; }
|
||||
|
||||
protected:
|
||||
void on_update() override;
|
||||
void on_release() override;
|
||||
|
||||
private:
|
||||
ModelObjectPtrs m_model_objects;
|
||||
float m_z_shift = 0.f;
|
||||
};
|
||||
|
||||
class ModelObjectsClipper : public AssembleViewDataBase
|
||||
{
|
||||
public:
|
||||
explicit ModelObjectsClipper(AssembleViewDataPool* cgdp)
|
||||
: AssembleViewDataBase(cgdp) {}
|
||||
#ifndef NDEBUG
|
||||
AssembleViewDataID get_dependencies() const override { return AssembleViewDataID::ModelObjectsInfo; }
|
||||
#endif // NDEBUG
|
||||
|
||||
void set_position(double pos, bool keep_normal);
|
||||
double get_position() const { return m_clp_ratio; }
|
||||
ClippingPlane* get_clipping_plane() const { return m_clp.get(); }
|
||||
void render_cut() const;
|
||||
|
||||
|
||||
protected:
|
||||
void on_update() override;
|
||||
void on_release() override;
|
||||
|
||||
private:
|
||||
std::vector<const TriangleMesh*> m_old_meshes;
|
||||
std::vector<std::unique_ptr<MeshClipper>> m_clippers;
|
||||
std::unique_ptr<ClippingPlane> m_clp;
|
||||
double m_clp_ratio = 0.;
|
||||
double m_active_inst_bb_radius = 0.;
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -155,6 +155,7 @@ bool GLGizmosManager::init()
|
|||
//m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", sprite_id++));
|
||||
|
||||
m_common_gizmos_data.reset(new CommonGizmosDataPool(&m_parent));
|
||||
m_assemble_view_data.reset(new AssembleViewDataPool(&m_parent));
|
||||
|
||||
for (auto& gizmo : m_gizmos) {
|
||||
if (! gizmo->init()) {
|
||||
|
@ -341,6 +342,16 @@ void GLGizmosManager::update(const Linef3& mouse_ray, const Point& mouse_pos)
|
|||
curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos));
|
||||
}
|
||||
|
||||
void GLGizmosManager::update_assemble_view_data()
|
||||
{
|
||||
if (m_assemble_view_data) {
|
||||
if (m_parent.get_canvas_type() != GLCanvas3D::CanvasAssembleView)
|
||||
m_assemble_view_data->update(AssembleViewDataID(0));
|
||||
else
|
||||
m_assemble_view_data->update(AssembleViewDataID((int)AssembleViewDataID::ModelObjectsInfo | (int)AssembleViewDataID::ModelObjectsClipper));
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmosManager::update_data()
|
||||
{
|
||||
if (!m_enabled)
|
||||
|
@ -359,10 +370,11 @@ void GLGizmosManager::update_data()
|
|||
enable_grabber(Scale, i, enable_scale_xyz);
|
||||
}
|
||||
|
||||
if (m_common_gizmos_data)
|
||||
if (m_common_gizmos_data) {
|
||||
m_common_gizmos_data->update(get_current()
|
||||
? get_current()->get_requirements()
|
||||
: CommonGizmosDataID(0));
|
||||
? get_current()->get_requirements()
|
||||
: CommonGizmosDataID(0));
|
||||
}
|
||||
|
||||
if (selection.is_single_full_instance())
|
||||
{
|
||||
|
@ -587,6 +599,18 @@ ClippingPlane GLGizmosManager::get_clipping_plane() const
|
|||
}
|
||||
}
|
||||
|
||||
ClippingPlane GLGizmosManager::get_assemble_view_clipping_plane() const
|
||||
{
|
||||
if (!m_assemble_view_data
|
||||
|| !m_assemble_view_data->model_objects_clipper()
|
||||
|| m_assemble_view_data->model_objects_clipper()->get_position() == 0.)
|
||||
return ClippingPlane::ClipsNothing();
|
||||
else {
|
||||
const ClippingPlane& clp = *m_assemble_view_data->model_objects_clipper()->get_clipping_plane();
|
||||
return ClippingPlane(-clp.get_normal(), clp.get_data()[3]);
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmosManager::wants_reslice_supports_on_undo() const
|
||||
{
|
||||
return (m_current == SlaSupports
|
||||
|
@ -614,6 +638,12 @@ void GLGizmosManager::render_painter_gizmo() const
|
|||
gizmo->render_painter_gizmo();
|
||||
}
|
||||
|
||||
void GLGizmosManager::render_painter_assemble_view() const
|
||||
{
|
||||
if (m_assemble_view_data)
|
||||
m_assemble_view_data->model_objects_clipper()->render_cut();
|
||||
}
|
||||
|
||||
void GLGizmosManager::render_current_gizmo_for_picking_pass() const
|
||||
{
|
||||
if (! m_enabled || m_current == Undefined)
|
||||
|
@ -649,7 +679,14 @@ bool GLGizmosManager::on_mouse_wheel(wxMouseEvent& evt)
|
|||
|
||||
if (m_current == SlaSupports || m_current == Hollow || m_current == FdmSupports || m_current == Seam || m_current == MmuSegmentation) {
|
||||
float rot = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
|
||||
if (gizmo_event((rot > 0.f ? SLAGizmoEventType::MouseWheelUp : SLAGizmoEventType::MouseWheelDown), Vec2d::Zero(), evt.ShiftDown(), evt.AltDown(), evt.ControlDown()))
|
||||
if (gizmo_event((rot > 0.f ? SLAGizmoEventType::MouseWheelUp : SLAGizmoEventType::MouseWheelDown), Vec2d::Zero(), evt.ShiftDown(), evt.AltDown()
|
||||
// BBS
|
||||
#ifdef __WXOSX_MAC__
|
||||
, evt.RawControlDown()
|
||||
#else
|
||||
, evt.ControlDown()
|
||||
#endif
|
||||
))
|
||||
processed = true;
|
||||
}
|
||||
|
||||
|
@ -675,7 +712,8 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
|||
if (evt.Moving()) {
|
||||
m_tooltip = update_hover_state(mouse_pos);
|
||||
if (m_current == MmuSegmentation || m_current == FdmSupports)
|
||||
gizmo_event(SLAGizmoEventType::Moving, mouse_pos, evt.ShiftDown(), evt.AltDown());
|
||||
// BBS
|
||||
gizmo_event(SLAGizmoEventType::Moving, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown());
|
||||
} else if (evt.LeftUp()) {
|
||||
if (m_mouse_capture.left) {
|
||||
processed = true;
|
||||
|
|
|
@ -146,6 +146,7 @@ private:
|
|||
std::map<int, void*> icon_list;
|
||||
public:
|
||||
|
||||
std::unique_ptr<AssembleViewDataPool> m_assemble_view_data;
|
||||
enum MENU_ICON_NAME {
|
||||
IC_TOOLBAR_RESET = 0,
|
||||
IC_TOOLBAR_RESET_HOVER,
|
||||
|
@ -222,6 +223,7 @@ public:
|
|||
|
||||
void update(const Linef3& mouse_ray, const Point& mouse_pos);
|
||||
void update_data();
|
||||
void update_assemble_view_data();
|
||||
|
||||
EType get_current_type() const { return m_current; }
|
||||
GLGizmoBase* get_current() const;
|
||||
|
@ -265,6 +267,7 @@ public:
|
|||
|
||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false);
|
||||
ClippingPlane get_clipping_plane() const;
|
||||
ClippingPlane get_assemble_view_clipping_plane() const;
|
||||
bool wants_reslice_supports_on_undo() const;
|
||||
|
||||
bool is_in_editing_mode(bool error_notification = false) const;
|
||||
|
@ -273,6 +276,7 @@ public:
|
|||
void render_current_gizmo() const;
|
||||
void render_current_gizmo_for_picking_pass() const;
|
||||
void render_painter_gizmo() const;
|
||||
void render_painter_assemble_view() const;
|
||||
|
||||
void render_overlay() const;
|
||||
|
||||
|
|
|
@ -89,13 +89,6 @@ void GizmoObjectManipulation::update_settings_value(const Selection& selection)
|
|||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
m_new_position = volume->get_instance_offset();
|
||||
|
||||
// Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible.
|
||||
if (m_world_coordinates && ! m_uniform_scale &&
|
||||
! Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) {
|
||||
// Manipulating an instance in the world coordinate system, rotation is not multiples of ninety degrees, therefore enforce uniform scaling.
|
||||
m_uniform_scale = true;
|
||||
}
|
||||
|
||||
if (m_world_coordinates) {
|
||||
m_new_rotate_label_string = L("Rotate");
|
||||
m_new_rotation = volume->get_instance_rotation() * (180. / M_PI);
|
||||
|
@ -463,9 +456,6 @@ 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] = {
|
||||
|
@ -897,9 +887,6 @@ 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,7 +81,6 @@ 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;
|
||||
|
||||
|
|
1155
src/slic3r/GUI/HintNotification.cpp
Normal file
1155
src/slic3r/GUI/HintNotification.cpp
Normal file
File diff suppressed because it is too large
Load diff
122
src/slic3r/GUI/HintNotification.hpp
Normal file
122
src/slic3r/GUI/HintNotification.hpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
#ifndef slic3r_GUI_HintNotification_hpp_
|
||||
#define slic3r_GUI_HintNotification_hpp_
|
||||
|
||||
#include "NotificationManager.hpp"
|
||||
|
||||
namespace Slic3r {namespace GUI {
|
||||
|
||||
// Database of hints updatable
|
||||
struct HintData
|
||||
{
|
||||
std::string id_string;
|
||||
std::string text;
|
||||
size_t weight;
|
||||
bool was_displayed;
|
||||
std::string hypertext;
|
||||
std::string follow_text;
|
||||
std::string disabled_tags;
|
||||
std::string enabled_tags;
|
||||
bool runtime_disable; // if true - hyperlink will check before every click if not in disabled mode
|
||||
std::string documentation_link;
|
||||
std::function<void(void)> callback{ nullptr };
|
||||
};
|
||||
|
||||
class HintDatabase
|
||||
{
|
||||
public:
|
||||
static HintDatabase& get_instance()
|
||||
{
|
||||
static HintDatabase instance; // Guaranteed to be destroyed.
|
||||
// Instantiated on first use.
|
||||
return instance;
|
||||
}
|
||||
private:
|
||||
HintDatabase()
|
||||
: m_hint_id(0)
|
||||
{}
|
||||
public:
|
||||
~HintDatabase();
|
||||
HintDatabase(HintDatabase const&) = delete;
|
||||
void operator=(HintDatabase const&) = delete;
|
||||
|
||||
// return true if HintData filled;
|
||||
HintData* get_hint(bool new_hint = true);
|
||||
size_t get_count() {
|
||||
if (!m_initialized)
|
||||
return 0;
|
||||
return m_loaded_hints.size();
|
||||
}
|
||||
// resets m_initiailized to false and writes used if was initialized
|
||||
// used when reloading in runtime - like change language
|
||||
void uninit();
|
||||
private:
|
||||
void init();
|
||||
void load_hints_from_file(const boost::filesystem::path& path);
|
||||
bool is_used(const std::string& id);
|
||||
void set_used(const std::string& id);
|
||||
void clear_used();
|
||||
// Returns position in m_loaded_hints with next hint chosed randomly with weights
|
||||
size_t get_next();
|
||||
size_t m_hint_id;
|
||||
bool m_initialized{ false };
|
||||
std::vector<HintData> m_loaded_hints;
|
||||
bool m_sorted_hints{ false };
|
||||
std::vector<std::string> m_used_ids;
|
||||
bool m_used_ids_loaded{ false };
|
||||
};
|
||||
// Notification class - shows current Hint ("Did you know")
|
||||
class NotificationManager::HintNotification : public NotificationManager::PopNotification
|
||||
{
|
||||
public:
|
||||
HintNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, bool new_hint)
|
||||
: PopNotification(n, id_provider, evt_handler)
|
||||
{
|
||||
retrieve_data(new_hint);
|
||||
}
|
||||
virtual void init() override;
|
||||
void open_next() { retrieve_data(); }
|
||||
protected:
|
||||
virtual void set_next_window_size(ImGuiWrapper& imgui) override;
|
||||
virtual void count_spaces() override;
|
||||
virtual void count_lines() override;
|
||||
virtual bool on_text_click() override;
|
||||
virtual void render_text(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
virtual 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;
|
||||
virtual void render_minimize_button(ImGuiWrapper& imgui,
|
||||
const float win_pos_x, const float win_pos_y) override {}
|
||||
void render_preferences_button(ImGuiWrapper& imgui,
|
||||
const float win_pos_x, const float win_pos_y);
|
||||
void render_right_arrow_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y);
|
||||
void render_documentation_button(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y);
|
||||
void render_logo(ImGuiWrapper& imgui,
|
||||
const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y);
|
||||
// recursion counter -1 tells to retrieve same hint as last time
|
||||
void retrieve_data(bool new_hint = true);
|
||||
void open_documentation();
|
||||
|
||||
bool m_has_hint_data{ false };
|
||||
std::function<void(void)> m_hypertext_callback;
|
||||
std::string m_disabled_tags;
|
||||
std::string m_enabled_tags;
|
||||
bool m_runtime_disable;
|
||||
std::string m_documentation_link;
|
||||
float m_close_b_y{ 0 };
|
||||
float m_close_b_w{ 0 };
|
||||
// hover of buttons
|
||||
long m_docu_hover_time{ 0 };
|
||||
long m_prefe_hover_time{ 0 };
|
||||
};
|
||||
|
||||
} //namespace Slic3r
|
||||
} //namespace GUI
|
||||
|
||||
#endif //slic3r_GUI_HintNotification_hpp_
|
|
@ -88,14 +88,21 @@ bool check_color_change(PrintObject *object, size_t frst_layer_id, size_t layers
|
|||
|
||||
static std::string gcode(Type type)
|
||||
{
|
||||
const PrintConfig& config = GUI::wxGetApp().plater()->fff_print().config();
|
||||
Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config();
|
||||
switch (type) {
|
||||
//BBS
|
||||
//case ColorChange: return config.color_change_gcode;
|
||||
case PausePrint: return config.machine_pause_gcode;
|
||||
//case Template: return config.template_custom_gcode;
|
||||
case Template: return config.opt_string("template_custom_gcode");
|
||||
default: return "";
|
||||
}
|
||||
|
||||
//const PrintConfig& config = GUI::wxGetApp().plater()->fff_print().config();
|
||||
//switch (type) {
|
||||
////BBS
|
||||
////case ColorChange: return config.color_change_gcode;
|
||||
//case PausePrint: return config.machine_pause_gcode;
|
||||
//case Template: return config.template_custom_gcode;
|
||||
//default: return "";
|
||||
//}
|
||||
}
|
||||
|
||||
static std::string short_and_splitted_time(const std::string &time)
|
||||
|
@ -222,9 +229,9 @@ bool TickCodeInfo::add_tick(const int tick, Type type, const int extruder, doubl
|
|||
std::string extra;
|
||||
if (type == Custom) // custom Gcode
|
||||
{
|
||||
/*extra = get_custom_code(custom_gcode, print_z);
|
||||
if (extra.empty()) return false;
|
||||
custom_gcode = extra;*/
|
||||
//extra = get_custom_code(custom_gcode, print_z);
|
||||
//if (extra.empty()) return false;
|
||||
//custom_gcode = extra;
|
||||
} else if (type == PausePrint) {
|
||||
//BBS do not set pause extra message
|
||||
//extra = get_pause_print_msg(pause_print_msg, print_z);
|
||||
|
@ -262,9 +269,10 @@ bool TickCodeInfo::edit_tick(std::set<TickCode>::iterator it, double print_z)
|
|||
if (it->color == edited_value) return false;
|
||||
changed_tick.color = edited_value;
|
||||
} else if (it->type == Template) {
|
||||
if (gcode(Template) == edited_value) return false;
|
||||
changed_tick.extra = edited_value;
|
||||
changed_tick.type = Custom;
|
||||
//if (gcode(Template) == edited_value) return false;
|
||||
//changed_tick.extra = edited_value;
|
||||
//changed_tick.type = Custom;
|
||||
;
|
||||
} else if (it->type == Custom || it->type == PausePrint) {
|
||||
if (it->extra == edited_value) return false;
|
||||
changed_tick.extra = edited_value;
|
||||
|
@ -625,6 +633,21 @@ void IMSlider::post_ticks_changed_event(Type type)
|
|||
m_is_need_post_tick_changed_event = true;
|
||||
}
|
||||
|
||||
void IMSlider::add_custom_gcode(std::string custom_gcode)
|
||||
{
|
||||
if (m_selection == ssUndef) return;
|
||||
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
|
||||
|
||||
const auto it = m_ticks.ticks.find(TickCode{ tick });
|
||||
|
||||
if (it != m_ticks.ticks.end()) {
|
||||
m_ticks.ticks.erase(it);
|
||||
}
|
||||
m_ticks.ticks.emplace(TickCode{ tick, Custom, std::max<int>(1, m_only_extruder), "", custom_gcode });
|
||||
|
||||
post_ticks_changed_event(Custom);
|
||||
}
|
||||
|
||||
void IMSlider::add_code_as_tick(Type type, int selected_extruder)
|
||||
{
|
||||
if (m_selection == ssUndef) return;
|
||||
|
@ -682,8 +705,11 @@ bool IMSlider::check_ticks_changed_event(Type type)
|
|||
|
||||
|
||||
// switch on/off one layer mode
|
||||
void IMSlider::switch_one_layer_mode()
|
||||
bool IMSlider::switch_one_layer_mode()
|
||||
{
|
||||
if (m_show_custom_gcode_window)
|
||||
return false;
|
||||
|
||||
m_is_one_layer = !m_is_one_layer;
|
||||
if (!m_is_one_layer) {
|
||||
SetLowerValue(m_min_value);
|
||||
|
@ -692,6 +718,7 @@ void IMSlider::switch_one_layer_mode()
|
|||
m_selection == ssLower ? correct_lower_value() : correct_higher_value();
|
||||
if (m_selection == ssUndef) m_selection = ssHigher;
|
||||
set_as_dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
void IMSlider::draw_background(const ImRect& groove) {
|
||||
|
@ -1194,6 +1221,8 @@ bool IMSlider::render(int canvas_width, int canvas_height)
|
|||
|
||||
float scale = (float) wxGetApp().em_unit() / 10.0f;
|
||||
|
||||
render_input_custom_gcode();
|
||||
|
||||
if (is_horizontal()) {
|
||||
float pos_x = std::max(LEFT_MARGIN, 0.2f * canvas_width);
|
||||
float pos_y = (canvas_height - HORIZONTAL_SLIDER_SIZE.y * m_scale);
|
||||
|
@ -1247,6 +1276,70 @@ bool IMSlider::render(int canvas_width, int canvas_height)
|
|||
return result;
|
||||
}
|
||||
|
||||
void IMSlider::render_input_custom_gcode()
|
||||
{
|
||||
if (!m_show_custom_gcode_window)
|
||||
return;
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
static bool move_to_center = true;
|
||||
if (move_to_center) {
|
||||
move_to_center = false;
|
||||
auto pos_x = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width() / 2;
|
||||
auto pos_y = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_height() / 2;
|
||||
imgui.set_next_window_pos(pos_x, pos_y, ImGuiCond_Always, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
imgui.push_common_window_style(m_scale);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 12.f * m_scale);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10, 3) * m_scale);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10, 7) * m_scale);
|
||||
int windows_flag =
|
||||
ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_AlwaysAutoResize
|
||||
| ImGuiWindowFlags_NoResize
|
||||
| ImGuiWindowFlags_NoScrollbar
|
||||
| ImGuiWindowFlags_NoScrollWithMouse;
|
||||
imgui.begin(_u8L("Custom G-code"), windows_flag);
|
||||
imgui.text(_u8L("Enter Custom G-code used on current layer:"));
|
||||
int text_height = 6;
|
||||
ImGui::InputTextMultiline("##text", m_custom_gcode, sizeof(m_custom_gcode), ImVec2(-1, ImGui::GetTextLineHeight() * text_height));
|
||||
//text_height = 5;
|
||||
//for (int i = 0; m_custom_gcode[i] != '\0'; ++i){
|
||||
// if ('\n' == m_custom_gcode[i] && text_height < 12)
|
||||
// ++text_height;
|
||||
//}
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::SameLine(ImGui::GetStyle().WindowPadding.x * 14);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f / 255.f, 174.f / 255.f, 66.f / 255.f, 1.f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(61.f / 255.f, 203.f / 255.f, 115.f / 255.f, 1.f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(27.f / 255.f, 136.f / 255.f, 68.f / 255.f, 1.f));
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.f, 1.f, 1.f, 1.f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f));
|
||||
if (imgui.bbl_button(_L("OK"))) {
|
||||
m_show_custom_gcode_window = false;
|
||||
add_custom_gcode(m_custom_gcode);
|
||||
move_to_center = true;
|
||||
}
|
||||
ImGui::PopStyleColor(5);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(255.f / 255.f, 255.f / 255.f, 255.f / 255.f, 1.f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(238.f / 255.f, 238.f / 255.f, 238.f / 255.f, 1.f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(206.f / 255.f, 206.f / 255.f, 206.f / 255.f, 1.f));
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(0.f, 0.f, 0.f, 1.f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(38.f / 255.0f, 46.f / 255.0f, 48.f / 255.0f, 1.00f));
|
||||
if (imgui.bbl_button(_L("Cancel"))) {
|
||||
m_show_custom_gcode_window = false;
|
||||
move_to_center = true;
|
||||
}
|
||||
ImGui::PopStyleColor(5);
|
||||
|
||||
imgui.end();
|
||||
ImGui::PopStyleVar(3);
|
||||
imgui.pop_common_window_style();
|
||||
}
|
||||
|
||||
void IMSlider::render_menu()
|
||||
{
|
||||
ImGuiWrapper::push_menu_style(m_scale);
|
||||
|
@ -1267,6 +1360,14 @@ void IMSlider::render_menu()
|
|||
if (menu_item_with_icon(_u8L("Add Pause").c_str(), "")) {
|
||||
add_code_as_tick(PausePrint);
|
||||
}
|
||||
if (menu_item_with_icon(_u8L("Add Custom G-code").c_str(), "")) {
|
||||
m_show_custom_gcode_window = true;
|
||||
}
|
||||
if (!gcode(Template).empty()) {
|
||||
if (menu_item_with_icon(_u8L("Add Custom Template").c_str(), "")) {
|
||||
add_code_as_tick(Template);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//BBS render this menu item only when extruder_num > 1
|
||||
|
|
|
@ -261,15 +261,18 @@ public:
|
|||
|
||||
void UseDefaultColors(bool def_colors_on) { m_ticks.set_default_colors(def_colors_on); }
|
||||
|
||||
void add_custom_gcode(std::string custom_gcode);
|
||||
void add_code_as_tick(Type type, int selected_extruder = -1);
|
||||
void post_ticks_changed_event(Type type = Custom);
|
||||
bool check_ticks_changed_event(Type type);
|
||||
void switch_one_layer_mode();
|
||||
bool switch_one_layer_mode();
|
||||
|
||||
bool render(int canvas_width, int canvas_height);
|
||||
|
||||
void render_menu();
|
||||
|
||||
void render_input_custom_gcode();
|
||||
|
||||
//BBS update scroll value changed
|
||||
bool is_dirty() { return m_dirty; }
|
||||
void set_as_dirty(bool dirty = true) { m_dirty = dirty; }
|
||||
|
@ -327,6 +330,7 @@ private:
|
|||
bool m_is_one_layer = false;
|
||||
bool m_is_focused = false;
|
||||
bool m_show_menu = false;
|
||||
bool m_show_custom_gcode_window = false;
|
||||
bool m_force_mode_apply = true;
|
||||
bool m_enable_action_icon = true;
|
||||
bool m_enable_cog_icon = false;
|
||||
|
@ -367,6 +371,8 @@ private:
|
|||
Type m_tick_change_event_type;
|
||||
|
||||
std::vector<double> m_alternate_values;
|
||||
|
||||
char m_custom_gcode[1024] = { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1687,6 +1687,33 @@ void ImGuiWrapper::pop_menu_style()
|
|||
ImGuiWrapper::pop_toolbar_style();
|
||||
}
|
||||
|
||||
void ImGuiWrapper::push_common_window_style(const float scale) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f) * scale);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowTitleAlign, ImVec2(0.05f, 0.50f) * scale);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f * scale);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(38 / 255.0f, 46 / 255.0f, 48 / 255.0f, 1.00f)); // 1
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGuiWrapper::COL_WINDOW_BG); // 2
|
||||
ImGui::PushStyleColor(ImGuiCol_TitleBg, ImGuiWrapper::COL_TITLE_BG); // 3
|
||||
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImGuiWrapper::COL_TITLE_BG); // 4
|
||||
ImGui::PushStyleColor(ImGuiCol_Separator, ImGuiWrapper::COL_SEPARATOR); // 5
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.00f, 1.00f, 1.00f, 1.00f)); // 6
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); // 7
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); // 8
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.00f)); // 9
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.00f)); // 10
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 0.00f)); // 11
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.00f, 1.00f, 1.00f, 1.00f)); // 12
|
||||
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, ImGuiWrapper::COL_GREEN_LIGHT); // 13
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); // 14
|
||||
}
|
||||
|
||||
void ImGuiWrapper::pop_common_window_style() {
|
||||
ImGui::PopStyleColor(14);
|
||||
ImGui::PopStyleVar(5);
|
||||
}
|
||||
|
||||
void ImGuiWrapper::init_font(bool compress)
|
||||
{
|
||||
destroy_font();
|
||||
|
|
|
@ -192,6 +192,8 @@ public:
|
|||
static void pop_toolbar_style();
|
||||
static void push_menu_style(const float scale);
|
||||
static void pop_menu_style();
|
||||
static void push_common_window_style(const float scale);
|
||||
static void pop_common_window_style();
|
||||
|
||||
//BBS
|
||||
static int TOOLBAR_WINDOW_FLAGS;
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include "../Utils/MacDarkMode.hpp"
|
||||
#endif
|
||||
|
||||
BEGIN_EVENT_TABLE(Slic3r::GUI::ImageGrid, wxPanel)
|
||||
|
||||
|
@ -102,7 +108,8 @@ void Slic3r::GUI::ImageGrid::SetGroupMode(int mode)
|
|||
void Slic3r::GUI::ImageGrid::SetSelecting(bool selecting)
|
||||
{
|
||||
m_selecting = selecting;
|
||||
if (!m_selecting) m_file_sys->SelectAll(false);
|
||||
if (m_file_sys)
|
||||
m_file_sys->SelectAll(false);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
@ -140,29 +147,53 @@ void Slic3r::GUI::ImageGrid::DoAction(size_t index, int action)
|
|||
{
|
||||
if (action == 0) {
|
||||
m_file_sys->DeleteFiles(index);
|
||||
} else {
|
||||
} else if (action == 1) {
|
||||
if (index != -1) {
|
||||
auto &file = m_file_sys->GetFile(index);
|
||||
if (file.IsDownload() && file.progress >= -1) {
|
||||
if (file.progress >= 100) {
|
||||
if (!m_file_sys->DownloadCheckFile(index)) {
|
||||
wxMessageBox(wxString::Format(_L("File '%s' was lost! Please download it again."), from_u8(file.name)), _L("Error"), wxOK);
|
||||
Refresh();
|
||||
return;
|
||||
}
|
||||
#ifdef __WXMSW__
|
||||
wxExecute("cmd /c start " + from_u8(m_save_path + "\\" + file.name), wxEXEC_HIDE_CONSOLE);
|
||||
auto wfile = boost::filesystem::path(file.path).wstring();
|
||||
SHELLEXECUTEINFO info{sizeof(info), 0, NULL, L"open", wfile.c_str(), L"", SW_HIDE};
|
||||
::ShellExecuteEx(&info);
|
||||
#else
|
||||
wxShell("open " + m_save_path + "/" + file.name);
|
||||
wxShell("open " + file.path);
|
||||
#endif
|
||||
} else {
|
||||
m_file_sys->DownloadCancel(index);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (m_save_path.empty()) {
|
||||
wxDirDialog dlg(NULL, _L("Choose save directory"), "", wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
|
||||
if (dlg.ShowModal() == wxID_CANCEL)
|
||||
return;
|
||||
m_save_path = dlg.GetPath().ToUTF8().data();
|
||||
}
|
||||
m_file_sys->DownloadFiles(index, wxGetApp().app_config->get("download_path"));
|
||||
} else if (action == 2) {
|
||||
if (index != -1) {
|
||||
auto &file = m_file_sys->GetFile(index);
|
||||
if (file.IsDownload() && file.progress >= -1) {
|
||||
if (file.progress >= 100) {
|
||||
if (!m_file_sys->DownloadCheckFile(index)) {
|
||||
wxMessageBox(wxString::Format(_L("File '%s' was lost! Please download it again."), from_u8(file.name)), _L("Error"), wxOK);
|
||||
Refresh();
|
||||
return;
|
||||
}
|
||||
#ifdef __WIN32__
|
||||
wxExecute(L"explorer.exe /select," + from_u8(file.path));
|
||||
#elif __APPLE__
|
||||
openFolderForFile(from_u8(file.path));
|
||||
#else
|
||||
#endif
|
||||
} else {
|
||||
m_file_sys->DownloadCancel(index);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_file_sys->DownloadFiles(index, m_save_path);
|
||||
m_file_sys->DownloadFiles(index, wxGetApp().app_config->get("download_path"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,8 +219,10 @@ 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)
|
||||
if (m_file_sys->GetGroupMode() == PrinterFileSystem::G_NONE) {
|
||||
mask_size.y = 20 * em_unit(this) / 10;
|
||||
size.y -= mask_size.y;
|
||||
}
|
||||
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;
|
||||
|
@ -254,7 +287,9 @@ std::pair<int, size_t> Slic3r::GUI::ImageGrid::HitTest(wxPoint const &pt)
|
|||
if (index >= m_file_sys->GetCount()) { return {HIT_NONE, -1}; }
|
||||
if (!m_selecting) {
|
||||
wxRect hover_rect{0, m_image_size.y - 40, m_image_size.GetWidth(), 40};
|
||||
if (hover_rect.Contains(off.x, off.y)) { return {HIT_ACTION, index * 2 + off.x * 2 / hover_rect.GetWidth()}; } // Two buttons
|
||||
auto & file = m_file_sys->GetFile(index);
|
||||
int btn = file.IsDownload() && file.progress >= 100 ? 3 : 2;
|
||||
if (hover_rect.Contains(off.x, off.y)) { return {HIT_ACTION, index * 4 + off.x * btn / hover_rect.GetWidth()}; } // Two buttons
|
||||
}
|
||||
return {HIT_ITEM, index};
|
||||
}
|
||||
|
@ -316,7 +351,7 @@ void ImageGrid::mouseReleased(wxMouseEvent& event)
|
|||
if (m_hit_type == HIT_ITEM)
|
||||
Select(m_hit_item);
|
||||
else if (m_hit_type == HIT_ACTION)
|
||||
DoAction(m_hit_item / 2, m_hit_item & 1);
|
||||
DoAction(m_hit_item / 4, m_hit_item & 3);
|
||||
else if (m_hit_type == HIT_MODE)
|
||||
SetGroupMode(static_cast<PrinterFileSystem::GroupMode>(2 - m_hit_item));
|
||||
else if (m_hit_type == HIT_STATUS)
|
||||
|
@ -349,8 +384,12 @@ void Slic3r::GUI::ImageGrid::changedEvent(wxCommandEvent& evt)
|
|||
{
|
||||
evt.Skip();
|
||||
BOOST_LOG_TRIVIAL(info) << "ImageGrid::changedEvent: " << evt.GetEventType() << " index: " << evt.GetInt() << " name: " << evt.GetString() << " extra: " << evt.GetExtraLong();
|
||||
if (evt.GetEventType() == EVT_MODE_CHANGED
|
||||
|| evt.GetEventType() == EVT_FILE_CHANGED)
|
||||
if (evt.GetEventType() == EVT_FILE_CHANGED) {
|
||||
if (evt.GetInt() == -1)
|
||||
m_file_sys->DownloadCheckFiles(wxGetApp().app_config->get("download_path"));
|
||||
UpdateFileSystem();
|
||||
}
|
||||
else if (evt.GetEventType() == EVT_MODE_CHANGED)
|
||||
UpdateFileSystem();
|
||||
else
|
||||
Refresh();
|
||||
|
@ -365,13 +404,16 @@ void ImageGrid::paintEvent(wxPaintEvent& evt)
|
|||
|
||||
size_t Slic3r::GUI::ImageGrid::firstItem(wxSize const &size, wxPoint &off)
|
||||
{
|
||||
int size_y = size.y;
|
||||
if (m_file_sys->GetGroupMode() == PrinterFileSystem::G_NONE)
|
||||
size_y -= m_mask.GetHeight();
|
||||
int offx = (size.x - (m_col_count - 1) * m_cell_size.GetWidth() - m_image_size.GetWidth()) / 2;
|
||||
int offy = (m_row_offset + 1 < m_row_count || m_row_count == 0) ?
|
||||
m_cell_size.GetHeight() - m_image_size.GetHeight() - m_row_offset * m_cell_size.GetHeight() / 4 + m_row_offset / 4 * m_cell_size.GetHeight() :
|
||||
size.y - (size.y + m_image_size.GetHeight() - 1) / m_cell_size.GetHeight() * m_cell_size.GetHeight();
|
||||
size_y - (size_y + m_image_size.GetHeight() - 1) / m_cell_size.GetHeight() * m_cell_size.GetHeight();
|
||||
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;
|
||||
((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};
|
||||
|
@ -455,7 +497,7 @@ void ImageGrid::render(wxDC& dc)
|
|||
constexpr wchar_t const * formats[] = {_T("%Y-%m-%d"), _T("%Y-%m"), _T("%Y")};
|
||||
size_t start = index;
|
||||
size_t end = index;
|
||||
size_t hit_image = m_selecting ? size_t(-1) : m_hit_type == HIT_ITEM ? m_hit_item : m_hit_type == HIT_ACTION ? m_hit_item / 2 :size_t(-1);
|
||||
size_t hit_image = m_selecting ? size_t(-1) : m_hit_type == HIT_ITEM ? m_hit_item : m_hit_type == HIT_ACTION ? m_hit_item / 4 :size_t(-1);
|
||||
// Draw items with background
|
||||
while (off.y < size.y)
|
||||
{
|
||||
|
@ -475,15 +517,17 @@ void ImageGrid::render(wxDC& dc)
|
|||
dc.DrawBitmap(m_mask, pt);
|
||||
}
|
||||
}
|
||||
bool show_download_state_always = true;
|
||||
// Draw checked icon
|
||||
if (m_selecting)
|
||||
if (m_selecting && !show_download_state_always)
|
||||
dc.DrawBitmap(file.IsSelect() ? m_checked_icon.bmp() : m_unchecked_icon.bmp(),
|
||||
pt + wxPoint{10, m_image_size.GetHeight() - m_checked_icon.GetBmpHeight() - 10});
|
||||
// can' handle alpha
|
||||
// can't handle alpha
|
||||
// dc.GradientFillLinear({pt.x, pt.y, m_image_size.GetWidth(), 60}, wxColour(0x6F, 0x6F, 0x6F, 0x99), wxColour(0x6F, 0x6F, 0x6F, 0), wxBOTTOM);
|
||||
else if (m_file_sys->GetGroupMode() == PrinterFileSystem::G_NONE) {
|
||||
wxString nonHoverText;
|
||||
wxString secondAction = _L("Download");
|
||||
wxString thirdAction;
|
||||
int states = 0;
|
||||
// Draw download progress
|
||||
if (file.IsDownload()) {
|
||||
|
@ -495,7 +539,8 @@ void ImageGrid::render(wxDC& dc)
|
|||
nonHoverText = _L("Download failed");
|
||||
states = StateColor::Checked;
|
||||
} else if (file.progress >= 100) {
|
||||
secondAction = _L("Open");
|
||||
secondAction = _L("Play");
|
||||
thirdAction = _L("Open Folder");
|
||||
nonHoverText = _L("Download finished");
|
||||
} else {
|
||||
secondAction = _L("Cancel");
|
||||
|
@ -505,10 +550,14 @@ void ImageGrid::render(wxDC& dc)
|
|||
// Draw buttons on hovered item
|
||||
wxRect rect{pt.x, pt.y + m_image_size.y - m_buttons_background.GetHeight(), m_image_size.GetWidth(), m_buttons_background.GetHeight()};
|
||||
if (hit_image == index) {
|
||||
renderButtons(dc, {_L("Delete"), (wxChar const *) secondAction, nullptr}, rect, m_hit_type == HIT_ACTION ? m_hit_item & 1 : -1, states);
|
||||
renderButtons(dc, {_L("Delete"), (wxChar const *) secondAction, thirdAction.IsEmpty() ? nullptr : (wxChar const *) thirdAction, nullptr}, rect,
|
||||
m_hit_type == HIT_ACTION ? m_hit_item & 3 : -1, states);
|
||||
} else if (!nonHoverText.IsEmpty()) {
|
||||
renderButtons(dc, {(wxChar const *) nonHoverText, nullptr}, rect, -1, states);
|
||||
}
|
||||
if (m_selecting && show_download_state_always)
|
||||
dc.DrawBitmap(file.IsSelect() ? m_checked_icon.bmp() : m_unchecked_icon.bmp(),
|
||||
pt + wxPoint{10, m_image_size.GetHeight() - m_checked_icon.GetBmpHeight() - 10});
|
||||
} else {
|
||||
auto date = wxDateTime((time_t) file.time).Format(_L(formats[m_file_sys->GetGroupMode()]));
|
||||
dc.DrawText(date, pt + wxPoint{24, 16});
|
||||
|
@ -569,12 +618,12 @@ void Slic3r::GUI::ImageGrid::renderButtons(wxDC &dc, wxStringList const &texts,
|
|||
for (size_t i = 0; i < texts.size(); ++i) {
|
||||
int states2 = hit == i ? state : 0;
|
||||
// Draw button background
|
||||
rect.Deflate(10, 5);
|
||||
//dc.Blit(rect.GetTopLeft(), rect.GetSize(), &mdc, {m_buttonBackgroundColor.colorIndexForStates(states) * 128, 0});
|
||||
//dc.DrawBitmap(m_button_background, rect2.GetTopLeft());
|
||||
// Draw button splitter
|
||||
if (i > 0) dc.DrawLine(rect.GetLeftTop(), rect.GetLeftBottom());
|
||||
// Draw button text
|
||||
rect.Deflate(10, 5);
|
||||
renderText(dc, texts[i], rect, states | states2);
|
||||
rect.Inflate(10, 5);
|
||||
rect.Offset(rect.GetWidth(), 0);
|
||||
|
|
|
@ -96,8 +96,6 @@ private:
|
|||
wxBitmap m_status_icon;
|
||||
wxString m_status_msg;
|
||||
|
||||
std::string m_save_path;
|
||||
|
||||
ScalableBitmap m_checked_icon;
|
||||
ScalableBitmap m_unchecked_icon;
|
||||
StateColor m_buttonBackgroundColor;
|
||||
|
|
|
@ -503,10 +503,6 @@ void ArrangeJob::process()
|
|||
if (params.is_seq_print)
|
||||
params.min_obj_distance = std::max(params.min_obj_distance, scaled(params.cleareance_radius));
|
||||
|
||||
if (params.avoid_extrusion_cali_region)
|
||||
m_plater->get_partplate_list().preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES);
|
||||
|
||||
|
||||
double skirt_distance = print.has_skirt() ? print.config().skirt_distance.value : 0;
|
||||
double brim_max = 0;
|
||||
std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.brim_width); });
|
||||
|
@ -531,6 +527,9 @@ void ArrangeJob::process()
|
|||
std::for_each(m_selected.begin(), m_selected.end(), [&](auto& ap) {ap.inflation = params.min_obj_distance / 2; });
|
||||
std::for_each(m_unselected.begin(), m_unselected.end(), [&](auto& ap) {ap.inflation = ap.is_virt_object ? scaled(params.brim_skirt_distance) : params.min_obj_distance / 2; });
|
||||
|
||||
if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer"))
|
||||
m_plater->get_partplate_list().preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES);
|
||||
|
||||
m_plater->get_partplate_list().preprocess_exclude_areas(params.excluded_regions, 1);
|
||||
|
||||
// shrink bed by moving to center by dist
|
||||
|
|
|
@ -103,7 +103,10 @@ void BindJob::process()
|
|||
msg = _L("Logging in");
|
||||
}
|
||||
if (code != 0) {
|
||||
msg = _L("Login failed") + wxString::Format("(code=%d,info=%s)", code, info);
|
||||
msg = _L("Login failed") + wxString::Format("(code=%d,info=%s). ", code, info);
|
||||
if (code == BAMBU_NETWORK_ERR_TIMEOUT) {
|
||||
msg += _L("Please check the printer network connection.");
|
||||
}
|
||||
}
|
||||
update_status(curr_percent, msg);
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ wxString PrintJob::get_http_error_msg(unsigned int status, std::string body)
|
|||
else {
|
||||
wxString unkown_text = _L("Unkown Error.");
|
||||
unkown_text += wxString::Format("status=%u, body=%s", status, body);
|
||||
BOOST_LOG_TRIVIAL(error) << "http_error: status=" << status << ", code=" << code << ", error=" << error;
|
||||
return unkown_text;
|
||||
}
|
||||
|
||||
|
@ -151,6 +152,7 @@ void PrintJob::process()
|
|||
params.task_layer_inspect = this->task_layer_inspect;
|
||||
params.task_record_timelapse= this->task_record_timelapse;
|
||||
params.ams_mapping = this->task_ams_mapping;
|
||||
params.ams_mapping_info = this->task_ams_mapping_info;
|
||||
params.connection_type = this->connection_type;
|
||||
params.task_use_ams = this->task_use_ams;
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
bool task_record_timelapse;
|
||||
bool task_layer_inspect;
|
||||
std::string task_ams_mapping;
|
||||
std::string task_ams_mapping_info;
|
||||
std::string connection_type;
|
||||
bool cloud_print_only { false };
|
||||
bool has_sdcard { false };
|
||||
|
|
314
src/slic3r/GUI/Jobs/SendJob.cpp
Normal file
314
src/slic3r/GUI/Jobs/SendJob.cpp
Normal file
|
@ -0,0 +1,314 @@
|
|||
#include "SendJob.hpp"
|
||||
#include "libslic3r/MTUtils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
static wxString check_gcode_failed_str = _L("Abnormal print file data. Please slice again");
|
||||
static wxString printjob_cancel_str = _L("Task canceled");
|
||||
static wxString timeout_to_upload_str = _L("Upload task timed out. Please check the network problem and try again");
|
||||
static wxString failed_in_cloud_service_str = _L("Cloud service connection failed. Please try again.");
|
||||
static wxString file_is_not_exists_str = _L("Print file not found, please slice again");
|
||||
static wxString file_over_size_str = _L("The print file exceeds the maximum allowable size (1GB). Please simplify the model and slice again");
|
||||
static wxString print_canceled_str = _L("Task canceled");
|
||||
static wxString upload_failed_str = _L("Failed uploading print file");
|
||||
static wxString upload_login_failed_str = _L("Wrong Access code");
|
||||
|
||||
|
||||
static wxString sending_over_lan_str = _L("Sending gcode file over LAN");
|
||||
static wxString sending_over_cloud_str = _L("Sending gcode file through cloud service");
|
||||
|
||||
SendJob::SendJob(std::shared_ptr<ProgressIndicator> pri, Plater* plater, std::string dev_id)
|
||||
: PlaterJob{ std::move(pri), plater },
|
||||
m_dev_id(dev_id)
|
||||
{
|
||||
m_print_job_completed_id = plater->get_send_finished_event();
|
||||
}
|
||||
|
||||
void SendJob::prepare()
|
||||
{
|
||||
m_plater->get_print_job_data(&job_data);
|
||||
}
|
||||
|
||||
void SendJob::on_exception(const std::exception_ptr &eptr)
|
||||
{
|
||||
try {
|
||||
if (eptr)
|
||||
std::rethrow_exception(eptr);
|
||||
} catch (std::exception &e) {
|
||||
PlaterJob::on_exception(eptr);
|
||||
}
|
||||
}
|
||||
|
||||
wxString SendJob::get_http_error_msg(unsigned int status, std::string body)
|
||||
{
|
||||
int code = 0;
|
||||
std::string error;
|
||||
std::string message;
|
||||
wxString result;
|
||||
if (status >= 400 && status < 500)
|
||||
try {
|
||||
json j = json::parse(body);
|
||||
if (j.contains("code")) {
|
||||
if (!j["code"].is_null())
|
||||
code = j["code"].get<int>();
|
||||
}
|
||||
if (j.contains("error")) {
|
||||
if (!j["error"].is_null())
|
||||
error = j["error"].get<std::string>();
|
||||
}
|
||||
if (j.contains("message")) {
|
||||
if (!j["message"].is_null())
|
||||
message = j["message"].get<std::string>();
|
||||
}
|
||||
switch (status) {
|
||||
;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
;
|
||||
}
|
||||
else if (status == 503) {
|
||||
return _L("Service Unavailable");
|
||||
}
|
||||
else {
|
||||
wxString unkown_text = _L("Unkown Error.");
|
||||
unkown_text += wxString::Format("status=%u, body=%s", status, body);
|
||||
return unkown_text;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(error) << "http_error: status=" << status << ", code=" << code << ", error=" << error;
|
||||
|
||||
result = wxString::Format("code=%u, error=%s", code, from_u8(error));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string get_transform_string(int bytes)
|
||||
{
|
||||
float ms = (float)bytes / 1024.0f / 1024.0f;
|
||||
float ks = (float)bytes / 1024.0f;
|
||||
char buffer[32];
|
||||
if (ms > 0)
|
||||
::sprintf(buffer, "%.1fM", ms);
|
||||
else if (ks > 0)
|
||||
::sprintf(buffer, "%.1fK", ks);
|
||||
else
|
||||
::sprintf(buffer, "%.1fK", ks);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void SendJob::process()
|
||||
{
|
||||
/* display info */
|
||||
wxString msg;
|
||||
int curr_percent = 10;
|
||||
NetworkAgent* m_agent = wxGetApp().getAgent();
|
||||
AppConfig* config = wxGetApp().app_config;
|
||||
|
||||
if (this->connection_type == "lan") {
|
||||
msg = _L("Sending gcode file over LAN");
|
||||
}
|
||||
else {
|
||||
msg = _L("Sending gcode file through cloud service");
|
||||
}
|
||||
|
||||
int result = -1;
|
||||
unsigned int http_code;
|
||||
std::string http_body;
|
||||
|
||||
int total_plate_num = m_plater->get_partplate_list().get_plate_count();
|
||||
|
||||
PartPlate* plate = m_plater->get_partplate_list().get_plate(job_data.plate_idx);
|
||||
if (plate == nullptr) {
|
||||
plate = m_plater->get_partplate_list().get_curr_plate();
|
||||
if (plate == nullptr)
|
||||
return;
|
||||
}
|
||||
|
||||
/* check gcode is valid */
|
||||
if (!plate->is_valid_gcode_file()) {
|
||||
update_status(curr_percent, check_gcode_failed_str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (was_canceled()) {
|
||||
update_status(curr_percent, printjob_cancel_str);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string project_name = wxGetApp().plater()->get_project_name().ToUTF8().data();
|
||||
int curr_plate_idx = 0;
|
||||
if (job_data.plate_idx >= 0)
|
||||
curr_plate_idx = job_data.plate_idx + 1;
|
||||
else if (job_data.plate_idx == PLATE_CURRENT_IDX)
|
||||
curr_plate_idx = m_plater->get_partplate_list().get_curr_plate_index() + 1;
|
||||
|
||||
BBL::PrintParams params;
|
||||
params.dev_id = m_dev_id;
|
||||
//params.project_name = wxGetApp().plater()->get_project_name().ToUTF8().data();
|
||||
params.project_name = wxGetApp().plater()->get_project_name().utf8_string();
|
||||
|
||||
params.preset_name = wxGetApp().preset_bundle->prints.get_selected_preset_name();
|
||||
params.filename = job_data._3mf_path.string();
|
||||
params.config_filename = job_data._3mf_config_path.string();
|
||||
params.plate_index = curr_plate_idx;
|
||||
params.ams_mapping = this->task_ams_mapping;
|
||||
params.connection_type = this->connection_type;
|
||||
params.task_use_ams = this->task_use_ams;
|
||||
|
||||
// local print access
|
||||
params.dev_ip = m_dev_ip;
|
||||
params.username = "bblp";
|
||||
params.password = m_access_code;
|
||||
wxString error_text;
|
||||
wxString msg_text;
|
||||
|
||||
auto update_fn = [this, &msg, &curr_percent, &error_text](int stage, int code, std::string info) {
|
||||
if (stage == SendingPrintJobStage::PrintingStageCreate) {
|
||||
if (this->connection_type == "lan") {
|
||||
msg = _L("Sending gcode file over LAN");
|
||||
} else {
|
||||
msg = _L("Sending gcode file to sdcard");
|
||||
}
|
||||
curr_percent = 25;
|
||||
}
|
||||
else if (stage == SendingPrintJobStage::PrintingStageUpload) {
|
||||
if (code == 0 && !info.empty()) {
|
||||
if (this->connection_type == "lan") {
|
||||
msg = _L("Sending gcode file over LAN");
|
||||
}
|
||||
else {
|
||||
msg = _L("Sending gcode file to sdcard");
|
||||
}
|
||||
msg += wxString::Format("(%s)", info);
|
||||
curr_percent = 40;
|
||||
this->update_status(curr_percent, msg);
|
||||
}
|
||||
}
|
||||
else if (stage == SendingPrintJobStage::PrintingStageFinished) {
|
||||
curr_percent = 100;
|
||||
msg = wxString::Format(_L("Successfully sent. Close current page in %s s"), info);
|
||||
}
|
||||
else {
|
||||
if (this->connection_type == "lan") {
|
||||
msg = _L("Sending gcode file over LAN");
|
||||
}
|
||||
else {
|
||||
msg = _L("Sending gcode file over LAN");
|
||||
//msg = _L("Sending gcode file through cloud service");
|
||||
}
|
||||
}
|
||||
if (code != 0) {
|
||||
error_text = this->get_http_error_msg(code, info);
|
||||
msg += wxString::Format("[%s]", error_text);
|
||||
}
|
||||
this->update_status(curr_percent, msg);
|
||||
};
|
||||
|
||||
auto cancel_fn = [this]() {
|
||||
return was_canceled();
|
||||
};
|
||||
|
||||
|
||||
if (params.connection_type != "lan") {
|
||||
if (params.dev_ip.empty())
|
||||
params.comments = "no_ip";
|
||||
else if (this->cloud_print_only)
|
||||
params.comments = "low_version";
|
||||
else if (!this->has_sdcard)
|
||||
params.comments = "no_sdcard";
|
||||
else if (params.password.empty())
|
||||
params.comments = "no_password";
|
||||
|
||||
if (!params.password.empty()
|
||||
&& !params.dev_ip.empty()
|
||||
&& this->has_sdcard) {
|
||||
// try to send local with record
|
||||
BOOST_LOG_TRIVIAL(info) << "send_job: try to send gcode to printer";
|
||||
this->update_status(curr_percent, _L("Sending gcode file over LAN"));
|
||||
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn);
|
||||
if (result == BAMBU_NETWORK_ERR_FTP_LOGIN_DENIED) {
|
||||
params.comments = "wrong_code";
|
||||
} else if (result == BAMBU_NETWORK_ERR_FTP_UPLOAD_FAILED) {
|
||||
params.comments = "upload_failed";
|
||||
} else {
|
||||
params.comments = (boost::format("failed(%1%)") % result).str();
|
||||
}
|
||||
if (result < 0) {
|
||||
// try to send with cloud
|
||||
BOOST_LOG_TRIVIAL(info) << "send_job: try to send gcode file to printer";
|
||||
this->update_status(curr_percent, _L("Sending gcode file over LAN"));
|
||||
}
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "send_job: try to send gcode file to printer";
|
||||
this->update_status(curr_percent, _L("Sending gcode file over LAN"));
|
||||
}
|
||||
} else {
|
||||
if (this->has_sdcard) {
|
||||
this->update_status(curr_percent, _L("Sending gcode file over LAN"));
|
||||
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn);
|
||||
} else {
|
||||
this->update_status(curr_percent, _L("An SD card needs to be inserted before printing via LAN."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (was_canceled()) {
|
||||
update_status(curr_percent, printjob_cancel_str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result < 0) {
|
||||
if (result == BAMBU_NETWORK_ERR_FTP_LOGIN_DENIED) {
|
||||
msg_text = upload_failed_str;
|
||||
} if (result == BAMBU_NETWORK_ERR_FILE_NOT_EXIST) {
|
||||
msg_text = file_is_not_exists_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_FILE_OVER_SIZE) {
|
||||
msg_text = file_over_size_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_CHECK_MD5_FAILED) {
|
||||
msg_text = failed_in_cloud_service_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_INVALID_PARAMS) {
|
||||
msg_text = upload_failed_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_CANCELED) {
|
||||
msg_text = print_canceled_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_TIMEOUT) {
|
||||
msg_text = timeout_to_upload_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_INVALID_RESULT) {
|
||||
msg_text = upload_failed_str;
|
||||
} else if (result == BAMBU_NETWORK_ERR_FTP_UPLOAD_FAILED) {
|
||||
msg_text = upload_failed_str;
|
||||
} else {
|
||||
update_status(curr_percent, failed_in_cloud_service_str);
|
||||
}
|
||||
if (!error_text.IsEmpty())
|
||||
msg_text += wxString::Format("[%s]", error_text);
|
||||
update_status(curr_percent, msg_text);
|
||||
BOOST_LOG_TRIVIAL(error) << "send_job: failed, result = " << result;
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(error) << "send_job: send ok.";
|
||||
//m_success_fun();
|
||||
wxCommandEvent* evt = new wxCommandEvent(m_print_job_completed_id);
|
||||
evt->SetString(m_dev_id);
|
||||
wxQueueEvent(m_plater, evt);
|
||||
m_job_finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SendJob::on_success(std::function<void()> success)
|
||||
{
|
||||
m_success_fun = success;
|
||||
}
|
||||
|
||||
|
||||
void SendJob::finalize() {
|
||||
if (was_canceled()) return;
|
||||
|
||||
Job::finalize();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
60
src/slic3r/GUI/Jobs/SendJob.hpp
Normal file
60
src/slic3r/GUI/Jobs/SendJob.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef SendJOB_HPP
|
||||
#define SendJOB_HPP
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include "PlaterJob.hpp"
|
||||
#include "PrintJob.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
typedef std::function<void(int status, int code, std::string msg)> OnUpdateStatusFn;
|
||||
typedef std::function<bool()> WasCancelledFn;
|
||||
|
||||
class SendJob : public PlaterJob
|
||||
{
|
||||
PrintPrepareData job_data;
|
||||
std::string m_dev_id;
|
||||
bool m_job_finished{ false };
|
||||
int m_print_job_completed_id = 0;
|
||||
std::function<void()> m_success_fun{nullptr};
|
||||
|
||||
protected:
|
||||
|
||||
void prepare() override;
|
||||
|
||||
void on_exception(const std::exception_ptr &) override;
|
||||
public:
|
||||
SendJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater, std::string dev_id = "");
|
||||
|
||||
|
||||
std::string m_dev_ip;
|
||||
std::string m_access_code;
|
||||
std::string task_bed_type;
|
||||
std::string task_ams_mapping;
|
||||
std::string connection_type;
|
||||
|
||||
bool cloud_print_only { false };
|
||||
bool has_sdcard { false };
|
||||
bool task_use_ams { true };
|
||||
|
||||
wxWindow* m_parent{nullptr};
|
||||
|
||||
int status_range() const override
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
wxString get_http_error_msg(unsigned int status, std::string body);
|
||||
bool is_finished() { return m_job_finished; }
|
||||
void process() override;
|
||||
void on_success(std::function<void()> success);
|
||||
void finalize() override;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -9,7 +9,8 @@ namespace GUI {
|
|||
|
||||
wxDEFINE_EVENT(EVT_UPGRADE_UPDATE_MESSAGE, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_UPGRADE_NETWORK_SUCCESS, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_UPGRADE_NETWORK_FAILED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_DOWNLOAD_NETWORK_FAILED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_INSTALL_NETWORK_FAILED, wxCommandEvent);
|
||||
|
||||
|
||||
UpgradeNetworkJob::UpgradeNetworkJob(std::shared_ptr<ProgressIndicator> pri)
|
||||
|
@ -88,7 +89,7 @@ void UpgradeNetworkJob::process()
|
|||
|
||||
if (result < 0) {
|
||||
update_status(0, _L("Download failed"));
|
||||
wxCommandEvent event(EVT_UPGRADE_NETWORK_FAILED);
|
||||
wxCommandEvent event(EVT_DOWNLOAD_NETWORK_FAILED);
|
||||
event.SetEventObject(m_event_handle);
|
||||
wxPostEvent(m_event_handle, event);
|
||||
return;
|
||||
|
@ -112,7 +113,7 @@ void UpgradeNetworkJob::process()
|
|||
|
||||
if (result != 0) {
|
||||
update_status(0, _L("Install failed"));
|
||||
wxCommandEvent event(EVT_UPGRADE_NETWORK_FAILED);
|
||||
wxCommandEvent event(EVT_INSTALL_NETWORK_FAILED);
|
||||
event.SetEventObject(m_event_handle);
|
||||
wxPostEvent(m_event_handle, event);
|
||||
return;
|
||||
|
|
|
@ -49,7 +49,8 @@ public:
|
|||
|
||||
wxDECLARE_EVENT(EVT_UPGRADE_UPDATE_MESSAGE, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_UPGRADE_NETWORK_SUCCESS, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_UPGRADE_NETWORK_FAILED, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_DOWNLOAD_NETWORK_FAILED, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_INSTALL_NETWORK_FAILED, wxCommandEvent);
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
|
|
|
@ -200,6 +200,25 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
|
|||
// Font is already set in DPIFrame constructor
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
m_reset_title_text_colour_timer = new wxTimer();
|
||||
m_reset_title_text_colour_timer->SetOwner(this);
|
||||
Bind(wxEVT_TIMER, [this](auto& e) {
|
||||
set_title_colour_after_set_title(GetHandle());
|
||||
m_reset_title_text_colour_timer->Stop();
|
||||
});
|
||||
this->Bind(wxEVT_FULLSCREEN, [this](wxFullScreenEvent& e) {
|
||||
set_tag_when_enter_full_screen(e.IsFullScreen());
|
||||
if (!e.IsFullScreen()) {
|
||||
if (m_reset_title_text_colour_timer) {
|
||||
m_reset_title_text_colour_timer->Stop();
|
||||
m_reset_title_text_colour_timer->Start(500);
|
||||
}
|
||||
}
|
||||
e.Skip();
|
||||
});
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Initialize the docker task bar icon.
|
||||
switch (wxGetApp().get_app_mode()) {
|
||||
|
@ -375,7 +394,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
|
|||
|
||||
// declare events
|
||||
Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& event) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< "received close_widow event";
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ": mainframe received close_widow event";
|
||||
if (event.CanVeto() && m_plater->get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) {
|
||||
// prevents to open the save dirty project dialog
|
||||
event.Veto();
|
||||
|
@ -428,7 +447,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
|
|||
this->shutdown();
|
||||
// propagate event
|
||||
event.Skip();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< "finished process close_widow event";
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ": mainframe finished process close_widow event";
|
||||
});
|
||||
|
||||
//FIXME it seems this method is not called on application start-up, at least not on Windows. Why?
|
||||
|
@ -499,6 +518,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
|
|||
}
|
||||
return;}
|
||||
#endif
|
||||
if (evt.CmdDown() && evt.GetKeyCode() == 'J') { m_printhost_queue_dlg->Show(); return; }
|
||||
if (evt.CmdDown() && evt.GetKeyCode() == 'N') { m_plater->new_project(); return;}
|
||||
if (evt.CmdDown() && evt.GetKeyCode() == 'O') { m_plater->load_project(); return;}
|
||||
if (evt.CmdDown() && evt.ShiftDown() && evt.GetKeyCode() == 'S') { if (m_plater) m_plater->save_project(true); return;}
|
||||
|
@ -702,6 +722,7 @@ void MainFrame::update_layout()
|
|||
// Called when closing the application and when switching the application language.
|
||||
void MainFrame::shutdown()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "MainFrame::shutdown enter";
|
||||
// BBS: backup
|
||||
Slic3r::set_backup_callback(nullptr);
|
||||
#ifdef _WIN32
|
||||
|
@ -763,6 +784,8 @@ void MainFrame::shutdown()
|
|||
wxGetApp().shutdown();
|
||||
// BBS: why clear ?
|
||||
//wxGetApp().plater_ = nullptr;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "MainFrame::shutdown exit";
|
||||
}
|
||||
|
||||
void MainFrame::update_title()
|
||||
|
@ -772,8 +795,8 @@ void MainFrame::update_title()
|
|||
|
||||
void MainFrame::update_title_colour_after_set_title()
|
||||
{
|
||||
#ifdef __WXOSX__
|
||||
set_title_colour_after_set_title();
|
||||
#ifdef __APPLE__
|
||||
set_title_colour_after_set_title(GetHandle());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1269,8 +1292,12 @@ wxBoxSizer* MainFrame::create_side_tools()
|
|||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_GCODE));
|
||||
else if (m_print_select == eSendGcode)
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SEND_GCODE));
|
||||
else if (m_print_select == eUploadGcode)
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_UPLOAD_GCODE));
|
||||
else if (m_print_select == eExportSlicedFile)
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE));
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE));
|
||||
else if (m_print_select == eSendToPrinter)
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SEND_TO_PRINTER));
|
||||
});
|
||||
|
||||
// only support single plate currently
|
||||
|
@ -1322,60 +1349,92 @@ wxBoxSizer* MainFrame::create_side_tools()
|
|||
p->Dismiss();
|
||||
});
|
||||
#endif
|
||||
SideButton* print_plate_btn = new SideButton(p, _L("Print"), "");
|
||||
print_plate_btn->SetCornerRadius(0);
|
||||
print_plate_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
#if ENABEL_PRINT_ALL
|
||||
p->append_button(print_all_btn);
|
||||
#endif
|
||||
if (wxGetApp().preset_bundle
|
||||
&& !wxGetApp().preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(wxGetApp().preset_bundle)) {
|
||||
// ThirdParty Buttons
|
||||
SideButton* export_gcode_btn = new SideButton(p, _L("Export G-code file"), "");
|
||||
export_gcode_btn->SetCornerRadius(0);
|
||||
export_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Export G-code file"));
|
||||
m_print_select = eExportGcode;
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
p->Dismiss();
|
||||
});
|
||||
|
||||
// upload and print
|
||||
SideButton* send_gcode_btn = new SideButton(p, _L("Print"), "");
|
||||
send_gcode_btn->SetCornerRadius(0);
|
||||
send_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Print"));
|
||||
m_print_select = eSendGcode;
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
p->Dismiss();
|
||||
});
|
||||
|
||||
// upload only
|
||||
/*SideButton* upload_gcode_btn = new SideButton(p, _L("Send"), "");
|
||||
upload_gcode_btn->SetCornerRadius(0);
|
||||
upload_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Send"));
|
||||
m_print_select = eUploadGcode;
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
p->Dismiss();
|
||||
});*/
|
||||
|
||||
p->append_button(send_gcode_btn);
|
||||
//p->append_button(upload_gcode_btn);
|
||||
p->append_button(export_gcode_btn);
|
||||
} else {
|
||||
//Bambu Studio Buttons
|
||||
SideButton* print_plate_btn = new SideButton(p, _L("Print"), "");
|
||||
print_plate_btn->SetCornerRadius(0);
|
||||
|
||||
/*SideButton* send_to_printer_btn = new SideButton(p, _L("Send"), "");
|
||||
send_to_printer_btn->SetCornerRadius(0);*/
|
||||
|
||||
SideButton* export_sliced_file_btn = new SideButton(p, _L("Export sliced file"), "");
|
||||
export_sliced_file_btn->SetCornerRadius(0);
|
||||
|
||||
print_plate_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Print"));
|
||||
m_print_select = ePrintPlate;
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
p->Dismiss();
|
||||
});
|
||||
});
|
||||
|
||||
SideButton* send_gcode_btn = new SideButton(p, _L("Send"), "");
|
||||
send_gcode_btn->SetCornerRadius(0);
|
||||
send_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Send to print"));
|
||||
m_print_select = eSendGcode;
|
||||
if (m_print_enable)
|
||||
m_print_enable = get_enable_print_status() && can_send_gcode();
|
||||
/*send_to_printer_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Send"));
|
||||
m_print_select = eSendToPrinter;
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
p->Dismiss();
|
||||
});
|
||||
});*/
|
||||
|
||||
SideButton* export_sliced_file_3mf_btn = new SideButton(p, _L("Export sliced file (.3mf)"), "");
|
||||
export_sliced_file_3mf_btn->SetCornerRadius(0);
|
||||
export_sliced_file_3mf_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Export Sliced File (.3mf)"));
|
||||
export_sliced_file_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Export Sliced File"));
|
||||
m_print_select = eExportSlicedFile;
|
||||
if (m_print_enable)
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
p->Dismiss();
|
||||
});
|
||||
});
|
||||
p->append_button(print_plate_btn);
|
||||
//p->append_button(send_to_printer_btn);
|
||||
p->append_button(export_sliced_file_btn);
|
||||
}
|
||||
|
||||
SideButton* export_sliced_file_gcode_btn = new SideButton(p, _L("Export sliced file (.gcode)"), "");
|
||||
export_sliced_file_gcode_btn->SetCornerRadius(0);
|
||||
export_sliced_file_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
|
||||
m_print_btn->SetLabel(_L("Export Sliced File (.gcode)"));
|
||||
m_print_select = eExportGcode;
|
||||
if (m_print_enable)
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
p->Dismiss();
|
||||
});
|
||||
|
||||
#if ENABEL_PRINT_ALL
|
||||
p->append_button(print_all_btn);
|
||||
#endif
|
||||
p->append_button(print_plate_btn);
|
||||
p->append_button(send_gcode_btn);
|
||||
p->append_button(export_sliced_file_3mf_btn);
|
||||
p->append_button(export_sliced_file_gcode_btn);
|
||||
p->Popup(m_print_btn);
|
||||
}
|
||||
);
|
||||
|
@ -1461,13 +1520,34 @@ bool MainFrame::get_enable_print_status()
|
|||
enable = false;
|
||||
}
|
||||
}
|
||||
else if (m_print_select == eSendGcode)
|
||||
{
|
||||
if (!current_plate->is_slice_result_valid())
|
||||
enable = false;
|
||||
if (!can_send_gcode())
|
||||
enable = false;
|
||||
}
|
||||
else if (m_print_select == eUploadGcode)
|
||||
{
|
||||
if (!current_plate->is_slice_result_valid())
|
||||
enable = false;
|
||||
if (!can_send_gcode())
|
||||
enable = false;
|
||||
}
|
||||
else if (m_print_select == eExportSlicedFile)
|
||||
{
|
||||
if (!current_plate->is_slice_result_ready_for_print())
|
||||
{
|
||||
enable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_print_select == eSendToPrinter)
|
||||
{
|
||||
if (!current_plate->is_slice_result_ready_for_print())
|
||||
{
|
||||
enable = false;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": m_print_select %1%, enable= %2% ")%m_print_select %enable;
|
||||
|
||||
|
@ -1680,6 +1760,10 @@ static wxMenu* generate_help_menu()
|
|||
append_menu_item(helpMenu, wxID_ANY, about_title, about_title,
|
||||
[](wxCommandEvent&) { Slic3r::GUI::about(); });
|
||||
#endif
|
||||
append_menu_item(helpMenu, wxID_ANY, _L("Show Tip of the Day"), _L("Show Tip of the Day"), [](wxCommandEvent&) {
|
||||
wxGetApp().plater()->get_notification_manager()->push_hint_notification(false);
|
||||
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty();
|
||||
});
|
||||
|
||||
append_menu_item(helpMenu, wxID_ANY, _L("Open Network Test"), _L("Open Network Test"), [](wxCommandEvent&) {
|
||||
NetworkTestDialog dlg(wxGetApp().mainframe);
|
||||
|
@ -2613,6 +2697,28 @@ void MainFrame::on_config_changed(DynamicPrintConfig* config) const
|
|||
m_plater->on_config_change(*config); // propagate config change events to the plater
|
||||
}
|
||||
|
||||
void MainFrame::set_print_button_to_default(PrintSelectType select_type)
|
||||
{
|
||||
if (select_type == PrintSelectType::ePrintPlate) {
|
||||
m_print_btn->SetLabel(_L("Print"));
|
||||
m_print_select = ePrintPlate;
|
||||
if (m_print_enable)
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
} else if (select_type == PrintSelectType::eSendGcode) {
|
||||
m_print_btn->SetLabel(_L("Print"));
|
||||
m_print_select = eSendGcode;
|
||||
if (m_print_enable)
|
||||
m_print_enable = get_enable_print_status();
|
||||
m_print_btn->Enable(m_print_enable);
|
||||
this->Layout();
|
||||
} else {
|
||||
//unsupport
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrame::add_to_recent_projects(const wxString& filename)
|
||||
{
|
||||
if (wxFileExists(filename))
|
||||
|
|
|
@ -84,6 +84,7 @@ protected:
|
|||
class MainFrame : public DPIFrame
|
||||
{
|
||||
bool m_loaded {false};
|
||||
wxTimer* m_reset_title_text_colour_timer{ nullptr };
|
||||
|
||||
wxString m_qs_last_input_file = wxEmptyString;
|
||||
wxString m_qs_last_output_file = wxEmptyString;
|
||||
|
@ -167,17 +168,6 @@ class MainFrame : public DPIFrame
|
|||
|
||||
ESettingsLayout m_layout{ ESettingsLayout::Unknown };
|
||||
|
||||
//BBS GUI refactor
|
||||
enum PrintSelectType
|
||||
{
|
||||
ePrintAll = 0,
|
||||
ePrintPlate = 1,
|
||||
eExportSlicedFile = 2,
|
||||
eExportGcode = 3,
|
||||
eSendGcode = 4,
|
||||
|
||||
};
|
||||
|
||||
enum SliceSelectType
|
||||
{
|
||||
eSliceAll = 0,
|
||||
|
@ -193,7 +183,6 @@ protected:
|
|||
#endif
|
||||
|
||||
public:
|
||||
|
||||
MainFrame();
|
||||
~MainFrame() = default;
|
||||
|
||||
|
@ -208,6 +197,18 @@ public:
|
|||
tpProject = 4,
|
||||
};
|
||||
|
||||
//BBS GUI refactor
|
||||
enum PrintSelectType
|
||||
{
|
||||
ePrintAll = 0,
|
||||
ePrintPlate = 1,
|
||||
eExportSlicedFile = 2,
|
||||
eExportGcode = 3,
|
||||
eSendGcode = 4,
|
||||
eSendToPrinter = 5,
|
||||
eUploadGcode = 6
|
||||
};
|
||||
|
||||
//BBS: add slice&&print status update logic
|
||||
enum SlicePrintEventType
|
||||
{
|
||||
|
@ -288,6 +289,7 @@ public:
|
|||
void select_view(const std::string& direction);
|
||||
// Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig
|
||||
void on_config_changed(DynamicPrintConfig* cfg) const ;
|
||||
void set_print_button_to_default(PrintSelectType select_type);
|
||||
|
||||
bool can_save() const;
|
||||
bool can_save_as() const;
|
||||
|
|
|
@ -73,7 +73,8 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent)
|
|||
type_sizer->Add(m_button_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 24);
|
||||
type_sizer->Add(m_button_video, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 24);
|
||||
m_type_panel->SetSizer(type_sizer);
|
||||
//top_sizer->Add(m_type_panel, 0, wxALIGN_CENTER_VERTICAL);
|
||||
m_type_panel->Hide();
|
||||
// top_sizer->Add(m_type_panel, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
// File management
|
||||
m_manage_panel = new ::StaticBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
|
||||
|
@ -82,19 +83,18 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent)
|
|||
m_button_delete->SetToolTip(L("Delete selected files from printer."));
|
||||
m_button_download = new ::Button(m_manage_panel, _L("Download"));
|
||||
m_button_download->SetToolTip(L("Download selected files from printer."));
|
||||
m_button_management = new ::Button(m_manage_panel, _L("Management"));
|
||||
m_button_management = new ::Button(m_manage_panel, _L("Select"));
|
||||
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_delete->SetBorderColorNormal(wxColor("#FF6F00"));
|
||||
m_button_delete->SetTextColorNormal(wxColor("#FF6F00"));
|
||||
m_button_management->SetBorderWidth(0);
|
||||
m_button_management->SetBackgroundColor(wxColor("#00AE42"));
|
||||
m_button_management->SetBackgroundColorNormal(wxColor("#00AE42"));
|
||||
|
||||
wxBoxSizer *manage_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
manage_sizer->AddStretchSpacer(1);
|
||||
|
@ -166,15 +166,16 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent)
|
|||
// File management
|
||||
m_button_management->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) {
|
||||
e.Skip();
|
||||
bool selecting = !m_image_grid->IsSelecting();
|
||||
m_image_grid->SetSelecting(selecting);
|
||||
m_button_management->SetLabel(selecting ? _L("Finish") : _L("Management"));
|
||||
m_manage_panel->GetSizer()->Show(m_button_download, selecting);
|
||||
m_manage_panel->GetSizer()->Show(m_button_delete, selecting);
|
||||
m_manage_panel->Layout();
|
||||
SetSelecting(!m_image_grid->IsSelecting());
|
||||
});
|
||||
m_button_download->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) {
|
||||
m_image_grid->DoActionOnSelection(1);
|
||||
SetSelecting(false);
|
||||
});
|
||||
m_button_delete->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) {
|
||||
m_image_grid->DoActionOnSelection(0);
|
||||
SetSelecting(false);
|
||||
});
|
||||
m_button_download->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) { m_image_grid->DoActionOnSelection(1); });
|
||||
m_button_delete->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) { m_image_grid->DoActionOnSelection(0); });
|
||||
|
||||
auto onShowHide = [this](auto &e) {
|
||||
e.Skip();
|
||||
|
@ -214,6 +215,8 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
|
|||
fs->Unbind(EVT_MODE_CHANGED, &MediaFilePanel::modeChanged, this);
|
||||
fs->Stop(true);
|
||||
}
|
||||
m_button_management->Enable(false);
|
||||
SetSelecting(false);
|
||||
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)) {
|
||||
|
@ -223,8 +226,26 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
|
|||
fs->Attached();
|
||||
m_image_grid->SetFileType(m_last_type);
|
||||
m_image_grid->SetFileSystem(fs);
|
||||
fs->Bind(EVT_FILE_CHANGED, [this, wfs = boost::weak_ptr(fs)](auto &e) {
|
||||
e.Skip();
|
||||
boost::shared_ptr fs(wfs.lock());
|
||||
if (m_image_grid->GetFileSystem() != fs) // canceled
|
||||
return;
|
||||
m_button_management->Enable(fs->GetCount() > 0);
|
||||
if (fs->GetCount() == 0)
|
||||
SetSelecting(false);
|
||||
});
|
||||
fs->Bind(EVT_SELECT_CHANGED, [this, wfs = boost::weak_ptr(fs)](auto &e) {
|
||||
e.Skip();
|
||||
boost::shared_ptr fs(wfs.lock());
|
||||
if (m_image_grid->GetFileSystem() != fs) // canceled
|
||||
return;
|
||||
m_button_delete->Enable(e.GetInt() > 0);
|
||||
m_button_download->Enable(e.GetInt() > 0);
|
||||
});
|
||||
fs->Bind(EVT_MODE_CHANGED, &MediaFilePanel::modeChanged, this);
|
||||
fs->Bind(EVT_STATUS_CHANGED, [this, wfs = boost::weak_ptr(fs)](auto &e) {
|
||||
e.Skip();
|
||||
boost::shared_ptr fs(wfs.lock());
|
||||
if (m_image_grid->GetFileSystem() != fs) // canceled
|
||||
return;
|
||||
|
@ -271,6 +292,15 @@ void MediaFilePanel::Rescale()
|
|||
m_image_grid->Rescale();
|
||||
}
|
||||
|
||||
void MediaFilePanel::SetSelecting(bool selecting)
|
||||
{
|
||||
m_image_grid->SetSelecting(selecting);
|
||||
m_button_management->SetLabel(selecting ? _L("Cancel") : _L("Select"));
|
||||
m_manage_panel->GetSizer()->Show(m_button_download, selecting);
|
||||
m_manage_panel->GetSizer()->Show(m_button_delete, selecting);
|
||||
m_manage_panel->Layout();
|
||||
}
|
||||
|
||||
void MediaFilePanel::modeChanged(wxCommandEvent& e1)
|
||||
{
|
||||
e1.Skip();
|
||||
|
|
|
@ -39,6 +39,8 @@ public:
|
|||
public:
|
||||
void Rescale();
|
||||
|
||||
void SetSelecting(bool selecting);
|
||||
|
||||
private:
|
||||
void modeChanged(wxCommandEvent & e);
|
||||
|
||||
|
|
|
@ -71,11 +71,13 @@ 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_camera_exists = obj->has_ipcam;
|
||||
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_lan_passwd = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->access_code : "";
|
||||
m_tutk_support = obj->is_function_supported(PrinterFunction::FUNC_REMOTE_TUNNEL);
|
||||
} else {
|
||||
m_camera_exists = false;
|
||||
m_lan_mode = false;
|
||||
m_lan_ip.clear();
|
||||
m_lan_passwd.clear();
|
||||
|
@ -93,7 +95,7 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj)
|
|||
if (m_next_retry.IsValid())
|
||||
Play();
|
||||
else
|
||||
SetStatus("");
|
||||
SetStatus("", false);
|
||||
}
|
||||
|
||||
void MediaPlayCtrl::Play()
|
||||
|
@ -102,12 +104,17 @@ void MediaPlayCtrl::Play()
|
|||
return;
|
||||
if (!IsShownOnScreen())
|
||||
return;
|
||||
if (m_last_state != MEDIASTATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
if (m_machine.empty()) {
|
||||
Stop();
|
||||
SetStatus(_L("Initialize failed (No Device)!"));
|
||||
return;
|
||||
}
|
||||
if (m_last_state != MEDIASTATE_IDLE) {
|
||||
if (!m_camera_exists) {
|
||||
Stop();
|
||||
SetStatus(_L("Initialize failed (No Camera Device)!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -135,9 +142,17 @@ void MediaPlayCtrl::Play()
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_lan_mode && !m_tutk_support) { // not support tutk
|
||||
if (m_lan_mode) {
|
||||
Stop();
|
||||
SetStatus(_L("Initialize failed (Not supported)!"));
|
||||
SetStatus(m_lan_passwd.empty()
|
||||
? _L("Initialize failed (Not supported with LAN-only mode)!")
|
||||
: _L("Initialize failed (Not accessible in LAN-only mode)!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_tutk_support) { // not support tutk
|
||||
Stop();
|
||||
SetStatus(_L("Initialize failed (Not supported without remote video tunnel)!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -145,14 +160,13 @@ void MediaPlayCtrl::Play()
|
|||
if (agent) {
|
||||
agent->get_camera_url(m_machine, [this, m = m_machine](std::string url) {
|
||||
BOOST_LOG_TRIVIAL(info) << "camera_url: " << url;
|
||||
if (m != m_machine) return;
|
||||
CallAfter([this, url] {
|
||||
CallAfter([this, m, url] {
|
||||
if (m != m_machine) return;
|
||||
m_url = url;
|
||||
if (m_last_state == MEDIASTATE_INITIALIZING) {
|
||||
if (url.empty()) {
|
||||
if (url.empty() || !boost::algorithm::starts_with(url, "bambu:///")) {
|
||||
Stop();
|
||||
m_failed_code = 1;
|
||||
SetStatus(_L("Initialize failed [%d]!"));
|
||||
SetStatus(wxString::Format(_L("Initialize failed (%s)!"), url.empty() ? _L("Network unreachable") : from_u8(url)));
|
||||
} else {
|
||||
m_last_state = MEDIASTATE_LOADING;
|
||||
SetStatus(_L("Loading..."));
|
||||
|
@ -179,7 +193,10 @@ void MediaPlayCtrl::Stop()
|
|||
m_tasks.push_back("<stop>");
|
||||
m_cond.notify_all();
|
||||
m_last_state = MEDIASTATE_IDLE;
|
||||
SetStatus(_L("Stopped."));
|
||||
if (m_failed_code)
|
||||
SetStatus(_L("Stopped [%d]!"), true);
|
||||
else
|
||||
SetStatus(_L("Stopped."), false);
|
||||
if (m_failed_code >= 100) // not keep retry on local error
|
||||
m_next_retry = wxDateTime();
|
||||
}
|
||||
|
@ -200,7 +217,7 @@ void MediaPlayCtrl::TogglePlay()
|
|||
}
|
||||
}
|
||||
|
||||
void MediaPlayCtrl::SetStatus(wxString const& msg2)
|
||||
void MediaPlayCtrl::SetStatus(wxString const &msg2, bool hyperlink)
|
||||
{
|
||||
auto msg = wxString::Format(msg2, m_failed_code);
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::SetStatus: " << msg.ToUTF8().data();
|
||||
|
@ -211,10 +228,11 @@ void MediaPlayCtrl::SetStatus(wxString const& msg2)
|
|||
#endif // __WXMSW__
|
||||
m_label_status->SetLabel(msg);
|
||||
long style = m_label_status->GetWindowStyle() & ~LB_HYPERLINK;
|
||||
if (m_failed_code && msg != msg2) {
|
||||
if (hyperlink) {
|
||||
style |= LB_HYPERLINK;
|
||||
}
|
||||
m_label_status->SetWindowStyle(style);
|
||||
m_label_status->InvalidateBestSize();
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
@ -271,6 +289,7 @@ void MediaPlayCtrl::onStateChanged(wxMediaEvent& event)
|
|||
}
|
||||
if ((last_state == wxMEDIASTATE_PAUSED || last_state == wxMEDIASTATE_PLAYING) &&
|
||||
state == wxMEDIASTATE_STOPPED) {
|
||||
m_failed_code = m_media_ctrl->GetLastError();
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
@ -280,7 +299,7 @@ void MediaPlayCtrl::onStateChanged(wxMediaEvent& event)
|
|||
m_failed_code = m_media_ctrl->GetLastError();
|
||||
if (size.GetWidth() > 1000) {
|
||||
m_last_state = state;
|
||||
SetStatus(_L("Playing..."));
|
||||
SetStatus(_L("Playing..."), false);
|
||||
m_failed_retry = 0;
|
||||
boost::unique_lock lock(m_mutex);
|
||||
m_tasks.push_back("<play>");
|
||||
|
@ -291,9 +310,9 @@ void MediaPlayCtrl::onStateChanged(wxMediaEvent& event)
|
|||
if (m_failed_code == 0)
|
||||
m_failed_code = 2;
|
||||
SetStatus(_L("Load failed [%d]!"));
|
||||
} else {
|
||||
m_last_state = last_state;
|
||||
}
|
||||
} else {
|
||||
m_last_state = state;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ protected:
|
|||
|
||||
void TogglePlay();
|
||||
|
||||
void SetStatus(wxString const & msg);
|
||||
void SetStatus(wxString const &msg, bool hyperlink = true);
|
||||
|
||||
private:
|
||||
void media_proc();
|
||||
|
@ -61,6 +61,7 @@ private:
|
|||
std::string m_lan_ip;
|
||||
std::string m_lan_user;
|
||||
std::string m_lan_passwd;
|
||||
bool m_camera_exists = false;
|
||||
bool m_lan_mode = false;
|
||||
bool m_tutk_support = false;
|
||||
wxString m_url;
|
||||
|
|
|
@ -177,16 +177,19 @@ MonitorPanel::~MonitorPanel()
|
|||
m_connection_info->SetTextColor(*wxWHITE);
|
||||
m_connection_info->SetFont(::Label::Body_13);
|
||||
m_connection_info->SetCornerRadius(0);
|
||||
m_connection_info->SetSize(wxSize(FromDIP(220), FromDIP(25)));
|
||||
m_connection_info->SetMinSize(wxSize(FromDIP(220), FromDIP(25)));
|
||||
m_connection_info->SetMaxSize(wxSize(FromDIP(220), FromDIP(25)));
|
||||
m_connection_info->SetSize(wxSize(FromDIP(-1), FromDIP(25)));
|
||||
m_connection_info->SetMinSize(wxSize(FromDIP(-1), FromDIP(25)));
|
||||
m_connection_info->SetMaxSize(wxSize(FromDIP(-1), FromDIP(25)));
|
||||
|
||||
wxBoxSizer* connection_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_hyperlink = new wxHyperlinkCtrl(m_connection_info, wxID_ANY, _L("Failed to connect to the server"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
|
||||
connection_sizer->Add(m_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
m_hyperlink->SetBackgroundColour(wxColour(255, 111, 0));
|
||||
m_connection_info->SetSizer(connection_sizer);
|
||||
m_connection_info->Layout();
|
||||
connection_sizer->Fit(m_connection_info);
|
||||
|
||||
m_connection_info->Hide();
|
||||
/*sizer_boxv->Add(m_connection_info, 0, wxALIGN_CENTER, 0);
|
||||
sizer_boxh->Add(sizer_boxv, 1, wxALIGN_CENTER, 0);
|
||||
warning_panel->SetSizer(sizer_boxh);
|
||||
warning_panel->Layout();*/
|
||||
|
||||
|
||||
|
||||
|
||||
sizer_side_tools->Add(m_connection_info, 0, wxEXPAND, 0);
|
||||
|
@ -201,13 +204,11 @@ MonitorPanel::~MonitorPanel()
|
|||
m_status_info_panel = new StatusPanel(m_tabpanel);
|
||||
m_tabpanel->AddPage(m_status_info_panel, _L("Status"), "", true);
|
||||
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
m_media_file_panel = new MediaFilePanel(m_tabpanel);
|
||||
m_tabpanel->AddPage(m_media_file_panel, _L("Media"), "", false);
|
||||
|
||||
m_upgrade_panel = new UpgradePanel(m_tabpanel);
|
||||
m_tabpanel->AddPage(m_upgrade_panel, _L("Update"), "", false);
|
||||
#endif
|
||||
|
||||
m_hms_panel = new HMSPanel(m_tabpanel);
|
||||
m_tabpanel->AddPage(m_hms_panel, _L("HMS"),"", false);
|
||||
|
@ -254,10 +255,8 @@ void MonitorPanel::msw_rescale()
|
|||
m_tabpanel->Rescale();
|
||||
//m_status_add_machine_panel->msw_rescale();
|
||||
m_status_info_panel->msw_rescale();
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
m_media_file_panel->Rescale();
|
||||
m_upgrade_panel->msw_rescale();
|
||||
#endif
|
||||
m_hms_panel->msw_rescale();
|
||||
|
||||
m_connection_info->SetCornerRadius(0);
|
||||
|
@ -318,6 +317,7 @@ void MonitorPanel::on_printer_clicked(wxMouseEvent &event)
|
|||
if (!m_side_tools->is_in_interval()) {
|
||||
wxPoint pos = m_side_tools->ClientToScreen(wxPoint(0, 0));
|
||||
pos.y += m_side_tools->GetRect().height;
|
||||
pos.x = pos.x < 0? 0:pos.x;
|
||||
m_select_machine.Position(pos, wxSize(0, 0));
|
||||
|
||||
#ifdef __linux__
|
||||
|
@ -407,15 +407,11 @@ void MonitorPanel::update_all()
|
|||
}
|
||||
|
||||
m_status_info_panel->obj = obj;
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
m_upgrade_panel->update(obj);
|
||||
#endif
|
||||
|
||||
|
||||
m_status_info_panel->m_media_play_ctrl->SetMachineObject(obj);
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
m_media_file_panel->SetMachineObject(obj);
|
||||
#endif
|
||||
|
||||
update_status(obj);
|
||||
|
||||
|
@ -514,9 +510,14 @@ void MonitorPanel::show_status(int status)
|
|||
|
||||
if (((status & (int) MonitorStatus::MONITOR_DISCONNECTED) != 0) || ((status & (int) MonitorStatus::MONITOR_DISCONNECTED_SERVER) != 0)) {
|
||||
if ((status & (int) MonitorStatus::MONITOR_DISCONNECTED_SERVER))
|
||||
m_connection_info->SetLabel(_L("Failed to connect to the server"));
|
||||
m_hyperlink->SetLabel(_L("Failed to connect to the server"));
|
||||
//m_connection_info->SetLabel(_L("Failed to connect to the server"));
|
||||
else
|
||||
m_connection_info->SetLabel(_L("Failed to connect to the printer"));
|
||||
m_hyperlink->SetLabel(_L("Failed to connect to the printer"));
|
||||
//m_connection_info->SetLabel(_L("Failed to connect to the printer"));
|
||||
|
||||
m_hyperlink->Show();
|
||||
m_connection_info->SetLabel(wxEmptyString);
|
||||
m_connection_info->Show();
|
||||
m_connection_info->SetBackgroundColor(wxColour(255, 111, 0));
|
||||
m_connection_info->SetBorderColor(wxColour(255, 111, 0));
|
||||
|
@ -526,6 +527,7 @@ void MonitorPanel::show_status(int status)
|
|||
} else if ((status & (int) MonitorStatus::MONITOR_NORMAL) != 0) {
|
||||
m_connection_info->Hide();
|
||||
} else if ((status & (int) MonitorStatus::MONITOR_CONNECTING) != 0) {
|
||||
m_hyperlink->Hide();
|
||||
m_connection_info->SetLabel(_L("Connecting..."));
|
||||
m_connection_info->SetBackgroundColor(wxColour(0, 174, 66));
|
||||
m_connection_info->SetBorderColor(wxColour(0, 174, 66));
|
||||
|
|
|
@ -84,6 +84,7 @@ private:
|
|||
UpgradePanel* m_upgrade_panel;
|
||||
HMSPanel* m_hms_panel;
|
||||
Button * m_connection_info{nullptr};
|
||||
wxHyperlinkCtrl* m_hyperlink{nullptr};
|
||||
|
||||
/* side tools */
|
||||
SideTools* m_side_tools{nullptr};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "NotificationManager.hpp"
|
||||
|
||||
#include "HintNotification.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "ImGuiWrapper.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
|
@ -1009,7 +1010,7 @@ void NotificationManager::PrintHostUploadNotification::init()
|
|||
}
|
||||
void NotificationManager::PrintHostUploadNotification::count_spaces()
|
||||
{
|
||||
//determine line width
|
||||
//determine line width
|
||||
m_line_height = ImGui::CalcTextSize("A").y;
|
||||
|
||||
m_left_indentation = m_line_height;
|
||||
|
@ -1078,7 +1079,6 @@ void NotificationManager::PrintHostUploadNotification::render_bar(ImGuiWrapper&
|
|||
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? m_line_height / 4 : m_line_height / 2));
|
||||
break;
|
||||
}
|
||||
|
||||
imgui.text(text.c_str());
|
||||
|
||||
}
|
||||
|
@ -1983,7 +1983,27 @@ int NotificationManager::progress_indicator_get_range() const
|
|||
|
||||
void NotificationManager::push_hint_notification(bool open_next)
|
||||
{
|
||||
return;
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::DidYouKnowHint) {
|
||||
(dynamic_cast<HintNotification*>(notification.get()))->open_next();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NotificationData data{ NotificationType::DidYouKnowHint, NotificationLevel::HintNotificationLevel, 300, "" };
|
||||
// from user - open now
|
||||
if (!open_next) {
|
||||
push_notification_data(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), 0);
|
||||
stop_delayed_notifications_of_type(NotificationType::DidYouKnowHint);
|
||||
// at startup - delay for half a second to let other notification pop up, than try every 30 seconds
|
||||
// show only if no notifications are shown
|
||||
}
|
||||
else {
|
||||
auto condition = [&self = std::as_const(*this)]() {
|
||||
return self.get_notification_count() == 0;
|
||||
};
|
||||
push_delayed_notification_data(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), condition, 500, 30000);
|
||||
}
|
||||
}
|
||||
|
||||
bool NotificationManager::is_hint_notification_open()
|
||||
|
|
|
@ -257,7 +257,8 @@ public:
|
|||
const t_opt_map& opt_map() const throw() { return m_opt_map; }
|
||||
|
||||
void set_config_category_and_type(const wxString &category, int type) { m_config_category = category; m_config_type = type; }
|
||||
void set_config(DynamicPrintConfig* config) { m_config = config; m_modelconfig = nullptr; }
|
||||
void set_config(DynamicPrintConfig* config) {
|
||||
m_config = config; m_modelconfig = nullptr; }
|
||||
Option get_option(const std::string& opt_key, int opt_index = -1);
|
||||
Line create_single_option_line(const std::string& title, const std::string& path = std::string(), int idx = -1) /*const*/{
|
||||
Option option = get_option(title, idx);
|
||||
|
|
|
@ -275,11 +275,61 @@ ParamsPanel::ParamsPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, c
|
|||
wxVSCROLL) // hide hori-bar will cause hidden field mis-position
|
||||
{
|
||||
// ShowScrollBar(GetHandle(), SB_BOTH, FALSE);
|
||||
Bind(wxEVT_SCROLL_CHANGED, [this](auto &e) {
|
||||
wxWindow *child = dynamic_cast<wxWindow *>(e.GetEventObject());
|
||||
if (child != this)
|
||||
EnsureVisible(child);
|
||||
});
|
||||
}
|
||||
virtual bool ShouldScrollToChildOnFocus(wxWindow *child)
|
||||
{
|
||||
EnsureVisible(child);
|
||||
return false;
|
||||
}
|
||||
void EnsureVisible(wxWindow* win)
|
||||
{
|
||||
const wxRect viewRect(m_targetWindow->GetClientRect());
|
||||
const wxRect winRect(m_targetWindow->ScreenToClient(win->GetScreenPosition()), win->GetSize());
|
||||
if (viewRect.Contains(winRect)) {
|
||||
return;
|
||||
}
|
||||
if (winRect.GetWidth() > viewRect.GetWidth() || winRect.GetHeight() > viewRect.GetHeight()) {
|
||||
return;
|
||||
}
|
||||
int stepx, stepy;
|
||||
GetScrollPixelsPerUnit(&stepx, &stepy);
|
||||
|
||||
int startx, starty;
|
||||
GetViewStart(&startx, &starty);
|
||||
// first in vertical direction:
|
||||
if (stepy > 0) {
|
||||
int diff = 0;
|
||||
|
||||
if (winRect.GetTop() < 0) {
|
||||
diff = winRect.GetTop();
|
||||
} else if (winRect.GetBottom() > viewRect.GetHeight()) {
|
||||
diff = winRect.GetBottom() - viewRect.GetHeight() + 1;
|
||||
// round up to next scroll step if we can't get exact position,
|
||||
// so that the window is fully visible:
|
||||
diff += stepy - 1;
|
||||
}
|
||||
starty = (starty * stepy + diff) / stepy;
|
||||
}
|
||||
// then horizontal:
|
||||
if (stepx > 0) {
|
||||
int diff = 0;
|
||||
if (winRect.GetLeft() < 0) {
|
||||
diff = winRect.GetLeft();
|
||||
} else if (winRect.GetRight() > viewRect.GetWidth()) {
|
||||
diff = winRect.GetRight() - viewRect.GetWidth() + 1;
|
||||
// round up to next scroll step if we can't get exact position,
|
||||
// so that the window is fully visible:
|
||||
diff += stepx - 1;
|
||||
}
|
||||
startx = (startx * stepx + diff) / stepx;
|
||||
}
|
||||
Scroll(startx, starty);
|
||||
}
|
||||
};
|
||||
|
||||
m_page_view = new PageScrolledWindow(page_parent);
|
||||
|
|
|
@ -4106,7 +4106,7 @@ int PartPlateList::load_from_3mf_structure(PlateDataPtrs& plate_data_list)
|
|||
ps.total_used_filament *= 1000; //koef
|
||||
gcode_result->toolpath_outside = plate_data_list[i]->toolpath_outside;
|
||||
m_plate_list[index]->slice_filaments_info = plate_data_list[i]->slice_filaments_info;
|
||||
|
||||
gcode_result->warnings = plate_data_list[i]->warnings;
|
||||
if (!plate_data_list[i]->thumbnail_file.empty()) {
|
||||
if (boost::filesystem::exists(plate_data_list[i]->thumbnail_file)) {
|
||||
m_plate_list[index]->load_thumbnail_data(plate_data_list[i]->thumbnail_file);
|
||||
|
|
|
@ -347,6 +347,7 @@ public:
|
|||
Print* fff_print() { return m_print; }
|
||||
//return the slice result
|
||||
GCodeProcessorResult* get_slice_result() { return m_gcode_result; }
|
||||
|
||||
std::string get_tmp_gcode_path();
|
||||
std::string get_temp_config_3mf_path();
|
||||
//this API should only be used for command line usage
|
||||
|
|
|
@ -49,13 +49,51 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent) :
|
|||
#ifndef _WIN32
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
#endif
|
||||
|
||||
|
||||
// input the preset name
|
||||
Tab *tab = wxGetApp().get_tab(Preset::TYPE_PRINTER);
|
||||
m_presets = tab->get_presets();
|
||||
const Preset &sel_preset = m_presets->get_selected_preset();
|
||||
std::string suffix = _CTX_utf8(L_CONTEXT("Copy", "PresetName"), "PresetName");
|
||||
std::string preset_name = sel_preset.is_default ? "Untitled" : sel_preset.is_system ? (boost::format(("%1% - %2%")) % sel_preset.name % suffix).str() : sel_preset.name;
|
||||
|
||||
auto input_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxStaticText *label_top = new wxStaticText(this, wxID_ANY, from_u8((boost::format(_utf8(L("Save %s as"))) % into_u8(tab->title())).str()));
|
||||
label_top->SetFont(::Label::Body_13);
|
||||
label_top->SetForegroundColour(wxColour(38,46,48));
|
||||
|
||||
m_input_area = new RoundedRectangle(this, wxColor(172, 172, 172), wxDefaultPosition, wxSize(-1,-1), 3, 1);
|
||||
m_input_area->SetMinSize(wxSize(FromDIP(360), FromDIP(32)));
|
||||
|
||||
wxBoxSizer *input_sizer_h = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer *input_sizer_v = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_input_ctrl = new wxTextCtrl(m_input_area, -1, from_u8(preset_name), wxDefaultPosition, wxSize(wxSize(FromDIP(360), FromDIP(32)).x, -1), 0 | wxBORDER_NONE);
|
||||
m_input_ctrl->SetBackgroundColour(wxColour(255, 255, 255));
|
||||
m_input_ctrl->Bind(wxEVT_TEXT, [this](wxCommandEvent &) { update(); });
|
||||
|
||||
|
||||
input_sizer_v->Add(m_input_ctrl, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 12);
|
||||
input_sizer_h->Add(input_sizer_v, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
m_input_area->SetSizer(input_sizer_h);
|
||||
m_input_area->Layout();
|
||||
|
||||
m_valid_label = new wxStaticText(this, wxID_ANY, "");
|
||||
m_valid_label->SetForegroundColour(wxColor(255, 111, 0));
|
||||
|
||||
input_sizer->Add(label_top, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, BORDER_W);
|
||||
input_sizer->Add(m_input_area, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, BORDER_W);
|
||||
input_sizer->Add(m_valid_label, 0, wxEXPAND | wxLEFT | wxRIGHT, BORDER_W);
|
||||
|
||||
|
||||
m_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
m_optgroup = new ConfigOptionsGroup(this, _L("Print Host upload"), m_config);
|
||||
build_printhost_settings(m_optgroup);
|
||||
|
||||
wxStdDialogButtonSizer* btns = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
||||
wxButton* btnOK = static_cast<wxButton*>(this->FindWindowById(wxID_OK, this));
|
||||
btnOK = static_cast<wxButton*>(this->FindWindowById(wxID_OK, this));
|
||||
wxGetApp().UpdateDarkUI(btnOK);
|
||||
btnOK->Bind(wxEVT_BUTTON, &PhysicalPrinterDialog::OnOK, this);
|
||||
|
||||
|
@ -65,12 +103,13 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent) :
|
|||
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
// topSizer->Add(label_top , 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, BORDER_W);
|
||||
topSizer->Add(input_sizer , 0, wxEXPAND | wxALL, BORDER_W);
|
||||
topSizer->Add(m_optgroup->sizer , 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, BORDER_W);
|
||||
topSizer->Add(btns , 0, wxEXPAND | wxALL, BORDER_W);
|
||||
topSizer->Add(btns , 0, wxEXPAND | wxALL, BORDER_W);
|
||||
|
||||
SetSizer(topSizer);
|
||||
topSizer->SetSizeHints(this);
|
||||
this->CenterOnScreen();
|
||||
this->CenterOnParent();
|
||||
}
|
||||
|
||||
PhysicalPrinterDialog::~PhysicalPrinterDialog()
|
||||
|
@ -99,7 +138,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
|||
|
||||
auto printhost_browse = [=](wxWindow* parent)
|
||||
{
|
||||
auto sizer = create_sizer_with_btn(parent, &m_printhost_browse_btn, "browse", _L("Browse") + " " + dots);
|
||||
auto sizer = create_sizer_with_btn(parent, &m_printhost_browse_btn, "printer_host_browser", _L("Browse") + " " + dots);
|
||||
m_printhost_browse_btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent& e) {
|
||||
BonjourDialog dialog(this, Preset::printer_technology(*m_config));
|
||||
if (dialog.show_and_lookup()) {
|
||||
|
@ -112,7 +151,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
|||
};
|
||||
|
||||
auto print_host_test = [=](wxWindow* parent) {
|
||||
auto sizer = create_sizer_with_btn(parent, &m_printhost_test_btn, "test", _L("Test"));
|
||||
auto sizer = create_sizer_with_btn(parent, &m_printhost_test_btn, "printer_host_test", _L("Test"));
|
||||
|
||||
m_printhost_test_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
|
||||
std::unique_ptr<PrintHost> host(PrintHost::get_print_host(m_config));
|
||||
|
@ -139,7 +178,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
|||
|
||||
auto print_host_printers = [this, create_sizer_with_btn](wxWindow* parent) {
|
||||
//add_scaled_button(parent, &m_printhost_port_browse_btn, "browse", _(L("Refresh Printers")), wxBU_LEFT | wxBU_EXACTFIT);
|
||||
auto sizer = create_sizer_with_btn(parent, &m_printhost_port_browse_btn, "browse", _(L("Refresh Printers")));
|
||||
auto sizer = create_sizer_with_btn(parent, &m_printhost_port_browse_btn, "monitor_signal_strong", _(L("Refresh Printers")));
|
||||
ScalableButton* btn = m_printhost_port_browse_btn;
|
||||
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) { update_printers(); });
|
||||
|
@ -174,7 +213,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
|||
Line cafile_line = m_optgroup->create_single_option_line(option);
|
||||
|
||||
auto printhost_cafile_browse = [=](wxWindow* parent) {
|
||||
auto sizer = create_sizer_with_btn(parent, &m_printhost_cafile_browse_btn, "browse", _L("Browse") + " " + dots);
|
||||
auto sizer = create_sizer_with_btn(parent, &m_printhost_cafile_browse_btn, "monitor_signal_strong", _L("Browse") + " " + dots);
|
||||
m_printhost_cafile_browse_btn->Bind(wxEVT_BUTTON, [this, m_optgroup](wxCommandEvent e) {
|
||||
static const auto filemasks = _L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*");
|
||||
wxFileDialog openFileDialog(this, _L("Open CA certificate file"), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
|
@ -270,8 +309,88 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
|||
void PhysicalPrinterDialog::update_printhost_buttons()
|
||||
{
|
||||
std::unique_ptr<PrintHost> host(PrintHost::get_print_host(m_config));
|
||||
m_printhost_test_btn->Enable(!m_config->opt_string("print_host").empty() && host->can_test());
|
||||
m_printhost_browse_btn->Enable(host->has_auto_discovery());
|
||||
if (host) {
|
||||
m_printhost_test_btn->Enable(!m_config->opt_string("print_host").empty() && host->can_test());
|
||||
m_printhost_browse_btn->Enable(host->has_auto_discovery());
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicalPrinterDialog::update_preset_input() {
|
||||
m_preset_name = into_u8(m_input_ctrl->GetValue());
|
||||
|
||||
m_valid_type = Valid;
|
||||
wxString info_line;
|
||||
|
||||
const char *unusable_symbols = "<>[]:/\\|?*\"";
|
||||
|
||||
const std::string unusable_suffix = PresetCollection::get_suffix_modified(); //"(modified)";
|
||||
for (size_t i = 0; i < std::strlen(unusable_symbols); i++) {
|
||||
if (m_preset_name.find_first_of(unusable_symbols[i]) != std::string::npos) {
|
||||
info_line = _L("Name is invalid;") + "\n" + _L("illegal characters:") + " " + unusable_symbols;
|
||||
m_valid_type = NoValid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_valid_type == Valid && m_preset_name.find(unusable_suffix) != std::string::npos) {
|
||||
info_line = _L("Name is invalid;") + "\n" + _L("illegal suffix:") + "\n\t" + from_u8(PresetCollection::get_suffix_modified());
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid &&
|
||||
(m_preset_name == "Default Setting" || m_preset_name == "Default Filament" || m_preset_name == "Default Printer")) {
|
||||
info_line = _L("Name is unavailable.");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
const Preset *existing = m_presets->find_preset(m_preset_name, false);
|
||||
if (m_valid_type == Valid && existing && (existing->is_default || existing->is_system)) {
|
||||
info_line = _L("Overwrite a system profile is not allowed");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid && existing && m_preset_name != m_presets->get_selected_preset_name()) {
|
||||
if (existing->is_compatible)
|
||||
info_line = from_u8((boost::format(_u8L("Preset \"%1%\" already exists.")) % m_preset_name).str());
|
||||
else
|
||||
info_line = from_u8((boost::format(_u8L("Preset \"%1%\" already exists and is incompatible with current printer.")) % m_preset_name).str());
|
||||
info_line += "\n" + _L("Please note that saving action will replace this preset");
|
||||
m_valid_type = Warning;
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid && m_preset_name.empty()) {
|
||||
info_line = _L("The name is not allowed to be empty.");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid && m_preset_name.find_first_of(' ') == 0) {
|
||||
info_line = _L("The name is not allowed to start with space character.");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid && m_preset_name.find_last_of(' ') == m_preset_name.length() - 1) {
|
||||
info_line = _L("The name is not allowed to end with space character.");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid && m_presets->get_preset_name_by_alias(m_preset_name) != m_preset_name) {
|
||||
info_line = _L("The name cannot be the same as a preset alias name.");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
m_valid_label->SetLabel(info_line);
|
||||
m_input_area->Refresh();
|
||||
m_valid_label->Show(!info_line.IsEmpty());
|
||||
|
||||
if (m_valid_type == NoValid) {
|
||||
if (btnOK)
|
||||
btnOK->Disable();
|
||||
}
|
||||
else {
|
||||
if (btnOK)
|
||||
btnOK->Enable();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicalPrinterDialog::update(bool printer_change)
|
||||
|
@ -317,6 +436,8 @@ void PhysicalPrinterDialog::update(bool printer_change)
|
|||
m_optgroup->show_field("printhost_port", supports_multiple_printers);
|
||||
m_printhost_port_browse_btn->Show(supports_multiple_printers);
|
||||
|
||||
update_preset_input();
|
||||
|
||||
update_printhost_buttons();
|
||||
|
||||
this->SetSize(this->GetBestSize());
|
||||
|
@ -395,7 +516,7 @@ void PhysicalPrinterDialog::on_dpi_changed(const wxRect& suggested_rect)
|
|||
|
||||
void PhysicalPrinterDialog::OnOK(wxEvent& event)
|
||||
{
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINTER)->save_preset();
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINTER)->save_preset("", false, false, true, m_preset_name );
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "libslic3r/Preset.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "Widgets/RoundedRectangle.hpp"
|
||||
|
||||
class wxString;
|
||||
class wxTextCtrl;
|
||||
|
@ -34,6 +35,10 @@ class PhysicalPrinterDialog : public DPIDialog
|
|||
ScalableButton* m_printhost_client_cert_browse_btn {nullptr};
|
||||
ScalableButton* m_printhost_port_browse_btn {nullptr};
|
||||
|
||||
RoundedRectangle* m_input_area {nullptr};
|
||||
wxStaticText* m_valid_label {nullptr};
|
||||
wxTextCtrl* m_input_ctrl {nullptr};
|
||||
wxButton* btnOK {nullptr};
|
||||
|
||||
void build_printhost_settings(ConfigOptionsGroup* optgroup);
|
||||
void OnOK(wxEvent& event);
|
||||
|
@ -42,8 +47,19 @@ public:
|
|||
PhysicalPrinterDialog(wxWindow* parent);
|
||||
~PhysicalPrinterDialog();
|
||||
|
||||
enum ValidationType
|
||||
{
|
||||
Valid,
|
||||
NoValid,
|
||||
Warning
|
||||
};
|
||||
PresetCollection* m_presets {nullptr};
|
||||
ValidationType m_valid_type;
|
||||
std::string m_preset_name;
|
||||
|
||||
void update(bool printer_change = false);
|
||||
void update_host_type(bool printer_change);
|
||||
void update_preset_input();
|
||||
void update_printhost_buttons();
|
||||
void update_printers();
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include "Jobs/NotificationProgressIndicator.hpp"
|
||||
#include "BackgroundSlicingProcess.hpp"
|
||||
#include "SelectMachine.hpp"
|
||||
#include "SendToPrinter.hpp"
|
||||
#include "PublishDialog.hpp"
|
||||
#include "ConfigWizard.hpp"
|
||||
#include "../Utils/ASCIIFolding.hpp"
|
||||
|
@ -151,6 +152,8 @@ wxDEFINE_EVENT(EVT_PUBLISH, wxCommandEvent);
|
|||
// BBS: backup & restore
|
||||
wxDEFINE_EVENT(EVT_RESTORE_PROJECT, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_PRINT_FINISHED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_SEND_FINISHED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_PUBLISH_FINISHED, wxCommandEvent);
|
||||
//BBS: repair model
|
||||
wxDEFINE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent);
|
||||
|
@ -504,17 +507,17 @@ Sidebar::Sidebar(Plater *parent)
|
|||
combo_printer->edit_btn = edit_btn;
|
||||
p->combo_printer = combo_printer;
|
||||
|
||||
ScalableButton* connection_btn = new ScalableButton(p->m_panel_printer_content, wxID_ANY, "monitor_signal_strong");
|
||||
connection_btn = new ScalableButton(p->m_panel_printer_content, wxID_ANY, "monitor_signal_strong");
|
||||
connection_btn->SetBackgroundColour(wxColour(255, 255, 255));
|
||||
connection_btn->SetToolTip(_L("Connection"));
|
||||
connection_btn->Bind(wxEVT_BUTTON, [this, combo_printer](wxCommandEvent)
|
||||
{
|
||||
PhysicalPrinterDialog dlg(this->GetParent());
|
||||
dlg.ShowModal();
|
||||
});
|
||||
{
|
||||
PhysicalPrinterDialog dlg(this->GetParent());
|
||||
dlg.ShowModal();
|
||||
});
|
||||
|
||||
wxBoxSizer *vsizer_printer = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *hsizer_printer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* vsizer_printer = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* hsizer_printer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
hsizer_printer->Add(combo_printer, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3));
|
||||
hsizer_printer->Add(edit_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3));
|
||||
|
@ -706,7 +709,7 @@ 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,
|
||||
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) {
|
||||
|
@ -906,6 +909,21 @@ void Sidebar::update_all_preset_comboboxes()
|
|||
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
|
||||
const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology();
|
||||
|
||||
bool is_bbl_preset = preset_bundle.printers.get_edited_preset().is_bbl_vendor_preset(&preset_bundle);
|
||||
|
||||
if (is_bbl_preset) {
|
||||
//only show connection button for not-BBL printer
|
||||
connection_btn->Hide();
|
||||
//only show sync-ams button for BBL printer
|
||||
ams_btn->Show();
|
||||
//update print button default value for bbl or third-party printer
|
||||
wxGetApp().mainframe->set_print_button_to_default(MainFrame::PrintSelectType::ePrintPlate);
|
||||
} else {
|
||||
connection_btn->Show();
|
||||
ams_btn->Hide();
|
||||
wxGetApp().mainframe->set_print_button_to_default(MainFrame::PrintSelectType::eSendGcode);
|
||||
}
|
||||
|
||||
// Update the print choosers to only contain the compatible presets, update the dirty flags.
|
||||
//BBS
|
||||
|
||||
|
@ -1472,6 +1490,7 @@ struct Plater::priv
|
|||
MenuFactory menus;
|
||||
|
||||
SelectMachineDialog* m_select_machine_dlg = nullptr;
|
||||
SendToPrinterDialog* m_send_to_sdcard_dlg = nullptr;
|
||||
PublishDialog *m_publish_dlg = nullptr;
|
||||
|
||||
// Data
|
||||
|
@ -1594,6 +1613,7 @@ struct Plater::priv
|
|||
std::string label_btn_send;
|
||||
|
||||
bool show_render_statistic_dialog{ false };
|
||||
bool show_wireframe{ false };
|
||||
|
||||
static const std::regex pattern_bundle;
|
||||
static const std::regex pattern_3mf;
|
||||
|
@ -1671,6 +1691,7 @@ struct Plater::priv
|
|||
|
||||
// BBS
|
||||
void hide_select_machine_dlg() { m_select_machine_dlg->EndModal(wxID_OK); }
|
||||
void hide_send_to_printer_dlg() { m_send_to_sdcard_dlg->EndModal(wxID_OK); }
|
||||
|
||||
void update_preview_bottom_toolbar();
|
||||
|
||||
|
@ -1850,6 +1871,7 @@ struct Plater::priv
|
|||
void on_action_print_all(SimpleEvent&);
|
||||
void on_action_export_gcode(SimpleEvent&);
|
||||
void on_action_send_gcode(SimpleEvent&);
|
||||
void on_action_upload_gcode(SimpleEvent&);
|
||||
void on_action_export_sliced_file(SimpleEvent&);
|
||||
void on_action_select_sliced_plate(wxCommandEvent& evt);
|
||||
|
||||
|
@ -1931,14 +1953,14 @@ struct Plater::priv
|
|||
void update_fff_scene_only_shells(bool only_shells = true);
|
||||
//BBS: add popup object table logic
|
||||
bool PopupObjectTable(int object_id, int volume_id, const wxPoint& position);
|
||||
|
||||
void on_action_send_to_printer();
|
||||
private:
|
||||
void update_fff_scene();
|
||||
void update_sla_scene();
|
||||
|
||||
void undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator it_snapshot);
|
||||
void update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool temp_snapshot_was_taken = false);
|
||||
|
||||
void on_action_export_to_sdcard(SimpleEvent&);
|
||||
// path to project folder stored with no extension
|
||||
boost::filesystem::path m_project_folder;
|
||||
|
||||
|
@ -2201,7 +2223,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
preview->on_tick_changed(tick_event_type);
|
||||
|
||||
// BBS set to invalid state only
|
||||
if (tick_event_type == Type::ToolChange) {
|
||||
if (tick_event_type == Type::ToolChange || tick_event_type == Type::Custom || tick_event_type == Type::Template) {
|
||||
PartPlate *plate = this->q->get_partplate_list().get_curr_plate();
|
||||
if (plate) {
|
||||
plate->update_slice_result_valid_state(false);
|
||||
|
@ -2239,11 +2261,15 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
q->Bind(EVT_GLTOOLBAR_PRINT_ALL, &priv::on_action_print_all, this);
|
||||
q->Bind(EVT_GLTOOLBAR_EXPORT_GCODE, &priv::on_action_export_gcode, this);
|
||||
q->Bind(EVT_GLTOOLBAR_SEND_GCODE, &priv::on_action_send_gcode, this);
|
||||
q->Bind(EVT_GLTOOLBAR_UPLOAD_GCODE, &priv::on_action_upload_gcode, this);
|
||||
q->Bind(EVT_GLTOOLBAR_EXPORT_SLICED_FILE, &priv::on_action_export_sliced_file, this);
|
||||
q->Bind(EVT_GLTOOLBAR_SEND_TO_PRINTER, &priv::on_action_export_to_sdcard, this);
|
||||
q->Bind(EVT_GLCANVAS_PLATE_SELECT, &priv::on_plate_selected, this);
|
||||
q->Bind(EVT_DOWNLOAD_PROJECT, &priv::on_action_download_project, this);
|
||||
q->Bind(EVT_IMPORT_MODEL_ID, &priv::on_action_request_model_id, this);
|
||||
q->Bind(EVT_PRINT_FINISHED, [q](wxCommandEvent &evt) { q->print_job_finished(evt); });
|
||||
q->Bind(EVT_SEND_FINISHED, [q](wxCommandEvent &evt) { q->send_job_finished(evt); });
|
||||
q->Bind(EVT_PUBLISH_FINISHED, [q](wxCommandEvent &evt) { q->publish_job_finished(evt);});
|
||||
//q->Bind(EVT_GLVIEWTOOLBAR_ASSEMBLE, [q](SimpleEvent&) { q->select_view_3D("Assemble"); });
|
||||
}
|
||||
|
||||
|
@ -2514,6 +2540,16 @@ wxColour Plater::get_next_color_for_filament()
|
|||
return colors[curr_color_filamenet++ % 7];
|
||||
}
|
||||
|
||||
wxString Plater::get_slice_warning_string(GCodeProcessorResult::SliceWarning& warning)
|
||||
{
|
||||
if (warning.msg == BED_TEMP_TOO_HIGH_THAN_FILAMENT) {
|
||||
return _L("The bed temperature exceeds filament's vitrification temperature. Please open the front door of printer before printing to avoid nozzle clog.");
|
||||
}
|
||||
else {
|
||||
return wxString(warning.msg);
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::priv::apply_free_camera_correction(bool apply/* = true*/)
|
||||
{
|
||||
bool use_perspective_camera = get_config("use_perspective_camera").compare("true") == 0;
|
||||
|
@ -3467,8 +3503,12 @@ fs::path Plater::priv::get_export_file_path(GUI::FileType file_type)
|
|||
// for 3mf take the path from the project filename, if any
|
||||
output_file = into_path(get_project_filename(".3mf"));
|
||||
|
||||
if (output_file.empty())
|
||||
output_file = into_path(get_project_name() + ".3mf");
|
||||
//bbs name the project using the part name
|
||||
if (output_file.empty()) {
|
||||
if (get_project_name() != _L("Untitled")) {
|
||||
output_file = into_path(get_project_name() + ".3mf");
|
||||
}
|
||||
}
|
||||
|
||||
if (output_file.empty())
|
||||
{
|
||||
|
@ -5647,6 +5687,14 @@ void Plater::priv::on_action_print_plate(SimpleEvent&)
|
|||
m_select_machine_dlg->ShowModal();
|
||||
}
|
||||
|
||||
|
||||
void Plater::priv::on_action_send_to_printer()
|
||||
{
|
||||
if (!m_send_to_sdcard_dlg) m_send_to_sdcard_dlg = new SendToPrinterDialog(q);
|
||||
m_send_to_sdcard_dlg->prepare(partplate_list.get_curr_plate_index());
|
||||
m_send_to_sdcard_dlg->ShowModal();
|
||||
}
|
||||
|
||||
void Plater::priv::on_action_select_sliced_plate(wxCommandEvent &evt)
|
||||
{
|
||||
if (q != nullptr) {
|
||||
|
@ -5677,11 +5725,19 @@ void Plater::priv::on_action_export_gcode(SimpleEvent&)
|
|||
}
|
||||
}
|
||||
|
||||
void Plater::priv::on_action_upload_gcode(SimpleEvent&)
|
||||
{
|
||||
if (q != nullptr) {
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n";
|
||||
q->send_gcode_legacy(-1, nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::priv::on_action_send_gcode(SimpleEvent&)
|
||||
{
|
||||
if (q != nullptr) {
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n" ;
|
||||
q->send_gcode_legacy();
|
||||
q->send_gcode_legacy(-1, nullptr, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5693,6 +5749,14 @@ void Plater::priv::on_action_export_sliced_file(SimpleEvent&)
|
|||
}
|
||||
}
|
||||
|
||||
void Plater::priv::on_action_export_to_sdcard(SimpleEvent&)
|
||||
{
|
||||
if (q != nullptr) {
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export sliced file event\n";
|
||||
q->send_to_printer();
|
||||
}
|
||||
}
|
||||
|
||||
//BBS: add plate select logic
|
||||
void Plater::priv::on_plate_selected(SimpleEvent&)
|
||||
{
|
||||
|
@ -6072,11 +6136,22 @@ void Plater::get_print_job_data(PrintPrepareData* data)
|
|||
data->_3mf_config_path = p->m_print_job_data._3mf_config_path;
|
||||
}
|
||||
}
|
||||
|
||||
int Plater::get_print_finished_event()
|
||||
{
|
||||
return EVT_PRINT_FINISHED;
|
||||
}
|
||||
|
||||
int Plater::get_send_finished_event()
|
||||
{
|
||||
return EVT_SEND_FINISHED;
|
||||
}
|
||||
|
||||
int Plater::get_publish_finished_event()
|
||||
{
|
||||
return EVT_PUBLISH_FINISHED;
|
||||
}
|
||||
|
||||
void Plater::priv::set_current_canvas_as_dirty()
|
||||
{
|
||||
if (current_panel == view3D)
|
||||
|
@ -7123,6 +7198,11 @@ void Plater::add_model(bool imperial_units/* = false*/)
|
|||
auto strategy = LoadStrategy::LoadModel;
|
||||
if (imperial_units) strategy = strategy | LoadStrategy::ImperialUnits;
|
||||
if (!load_files(paths, strategy, ask_multi).empty()) {
|
||||
|
||||
if (get_project_name() == _L("Untitled") && paths.size() > 0) {
|
||||
p->set_project_filename(wxString(paths[0].string()));
|
||||
}
|
||||
|
||||
wxGetApp().mainframe->update_title();
|
||||
}
|
||||
}
|
||||
|
@ -8315,6 +8395,11 @@ void Plater::export_gcode(bool prefer_removable)
|
|||
}
|
||||
}
|
||||
|
||||
void Plater::send_to_printer()
|
||||
{
|
||||
p->on_action_send_to_printer();
|
||||
}
|
||||
|
||||
//BBS export gcode 3mf to file
|
||||
void Plater::export_gcode_3mf()
|
||||
{
|
||||
|
@ -8952,7 +9037,7 @@ void Plater::reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &
|
|||
// and let the background processing start.
|
||||
this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART);
|
||||
}
|
||||
void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn)
|
||||
void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn, bool upload_only)
|
||||
{
|
||||
// if physical_printer is selected, send gcode for this printer
|
||||
// DynamicPrintConfig* physical_printer_config = wxGetApp().preset_bundle->physical_printers.get_selected_printer_config();
|
||||
|
@ -8989,7 +9074,7 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn)
|
|||
wxBusyCursor wait;
|
||||
upload_job.printhost->get_groups(groups);
|
||||
}
|
||||
|
||||
|
||||
PrintHostSendDialog dlg(default_output_file, upload_job.printhost->get_post_upload_actions(), groups);
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
upload_job.upload_data.upload_path = dlg.filename();
|
||||
|
@ -9020,7 +9105,7 @@ int Plater::send_gcode(int plate_idx, Export3mfProgressFn proFn)
|
|||
return -1;
|
||||
}
|
||||
|
||||
SaveStrategy strategy = SaveStrategy::Silence | SaveStrategy::SkipModel | SaveStrategy::WithGcode;
|
||||
SaveStrategy strategy = SaveStrategy::Silence | SaveStrategy::SkipModel | SaveStrategy::WithGcode | SaveStrategy::SkipAuxiliary;
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
//only save model in QA environment
|
||||
std::string sel = get_app_config()->get("iot_environment");
|
||||
|
@ -9053,7 +9138,7 @@ int Plater::export_config_3mf(int plate_idx, Export3mfProgressFn proFn)
|
|||
return -1;
|
||||
}
|
||||
|
||||
SaveStrategy strategy = SaveStrategy::Silence | SaveStrategy::SkipModel | SaveStrategy::WithSliceInfo;
|
||||
SaveStrategy strategy = SaveStrategy::Silence | SaveStrategy::SkipModel | SaveStrategy::WithSliceInfo | SaveStrategy::SkipAuxiliary;
|
||||
result = export_3mf(p->m_print_job_data._3mf_config_path, strategy, plate_idx, proFn);
|
||||
|
||||
return result;
|
||||
|
@ -9074,6 +9159,26 @@ void Plater::print_job_finished(wxCommandEvent &evt)
|
|||
curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS);
|
||||
}
|
||||
|
||||
void Plater::send_job_finished(wxCommandEvent& evt)
|
||||
{
|
||||
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return;
|
||||
dev->set_selected_machine(evt.GetString().ToStdString());
|
||||
|
||||
p->hide_send_to_printer_dlg();
|
||||
//p->main_frame->request_select_tab(MainFrame::TabPosition::tpMonitor);
|
||||
////jump to monitor and select device status panel
|
||||
//MonitorPanel* curr_monitor = p->main_frame->m_monitor;
|
||||
//if (curr_monitor)
|
||||
// curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS);
|
||||
}
|
||||
|
||||
void Plater::publish_job_finished(wxCommandEvent &evt)
|
||||
{
|
||||
p->m_publish_dlg->EndModal(wxID_OK);
|
||||
GUI::wxGetApp().load_url(evt.GetString());
|
||||
}
|
||||
|
||||
// Called when the Eject button is pressed.
|
||||
void Plater::eject_drive()
|
||||
{
|
||||
|
@ -10459,6 +10564,16 @@ bool Plater::is_render_statistic_dialog_visible() const
|
|||
return p->show_render_statistic_dialog;
|
||||
}
|
||||
|
||||
void Plater::toggle_show_wireframe()
|
||||
{
|
||||
p->show_wireframe = !p->show_wireframe;
|
||||
}
|
||||
|
||||
bool Plater::is_show_wireframe() const
|
||||
{
|
||||
return p->show_wireframe;
|
||||
}
|
||||
|
||||
|
||||
/*Plater::TakeSnapshot::TakeSnapshot(Plater *plater, const std::string &snapshot_name)
|
||||
: TakeSnapshot(plater, from_u8(snapshot_name)) {}
|
||||
|
@ -10526,4 +10641,4 @@ SuppressBackgroundProcessingUpdate::~SuppressBackgroundProcessingUpdate()
|
|||
wxGetApp().plater()->schedule_background_process(m_was_scheduled);
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
}} // namespace Slic3r::GUI
|
|
@ -20,6 +20,7 @@
|
|||
#include "PartPlate.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "Jobs/PrintJob.hpp"
|
||||
#include "Jobs/SendJob.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
||||
class wxButton;
|
||||
|
@ -160,6 +161,8 @@ private:
|
|||
|
||||
wxBoxSizer* m_scrolled_sizer = nullptr;
|
||||
ComboBox* m_bed_type_list = nullptr;
|
||||
ScalableButton* connection_btn = nullptr;
|
||||
ScalableButton* ams_btn = nullptr;
|
||||
};
|
||||
|
||||
class Plater: public wxPanel
|
||||
|
@ -232,6 +235,7 @@ public:
|
|||
static void setPrintSpeedTable(Slic3r::GlobalSpeedMap& printSpeedMap);
|
||||
static void setExtruderParams(std::map<size_t, Slic3r::ExtruderParams>& extParas);
|
||||
static wxColour get_next_color_for_filament();
|
||||
static wxString get_slice_warning_string(GCodeProcessorResult::SliceWarning& warning);
|
||||
|
||||
// BBS: restore
|
||||
std::vector<size_t> load_files(const std::vector<boost::filesystem::path>& input_files, LoadStrategy strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig, bool ask_multi = false);
|
||||
|
@ -296,6 +300,7 @@ public:
|
|||
void segment(size_t obj_idx, size_t instance_idx, double smoothing_alpha=0.5, int segment_number=5);
|
||||
void merge(size_t obj_idx, std::vector<int>& vol_indeces);
|
||||
|
||||
void send_to_printer();
|
||||
void export_gcode(bool prefer_removable);
|
||||
void export_gcode_3mf();
|
||||
void export_core_3mf();
|
||||
|
@ -330,10 +335,12 @@ public:
|
|||
/* -1: send current gcode if not specified
|
||||
* -2: send all gcode to target machine */
|
||||
int send_gcode(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
|
||||
void send_gcode_legacy(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
|
||||
void send_gcode_legacy(int plate_idx = -1, Export3mfProgressFn proFn = nullptr, bool upload_only = false);
|
||||
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 send_job_finished(wxCommandEvent& evt);
|
||||
void publish_job_finished(wxCommandEvent& evt);
|
||||
void eject_drive();
|
||||
|
||||
void take_snapshot(const std::string &snapshot_name);
|
||||
|
@ -397,6 +404,8 @@ public:
|
|||
//BBS: add print job releated functions
|
||||
void get_print_job_data(PrintPrepareData* data);
|
||||
int get_print_finished_event();
|
||||
int get_send_finished_event();
|
||||
int get_publish_finished_event();
|
||||
|
||||
void set_current_canvas_as_dirty();
|
||||
void unbind_canvas_event_handlers();
|
||||
|
@ -613,6 +622,9 @@ public:
|
|||
void toggle_render_statistic_dialog();
|
||||
bool is_render_statistic_dialog_visible() const;
|
||||
|
||||
void toggle_show_wireframe();
|
||||
bool is_show_wireframe() const;
|
||||
|
||||
// Wrapper around wxWindow::PopupMenu to suppress error messages popping out while tracking the popup menu.
|
||||
bool PopupMenu(wxMenu *menu, const wxPoint& pos = wxDefaultPosition);
|
||||
bool PopupMenu(wxMenu *menu, int x, int y) { return this->PopupMenu(menu, wxPoint(x, y)); }
|
||||
|
@ -675,4 +687,4 @@ private:
|
|||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -457,9 +457,12 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxWindow *pa
|
|||
m_sizer_checkbox->Add(checkbox, 0, wxALIGN_CENTER, 0);
|
||||
m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 8);
|
||||
|
||||
auto checkbox_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxSize(-1, -1), 0);
|
||||
auto checkbox_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, 0);
|
||||
checkbox_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
|
||||
checkbox_title->SetFont(::Label::Body_13);
|
||||
|
||||
auto size = checkbox_title->GetTextExtent(title);
|
||||
checkbox_title->SetMinSize(wxSize(size.x + FromDIP(40), -1));
|
||||
checkbox_title->Wrap(-1);
|
||||
m_sizer_checkbox->Add(checkbox_title, 0, wxALIGN_CENTER | wxALL, 3);
|
||||
|
||||
|
@ -526,6 +529,57 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxWindow *pa
|
|||
return m_sizer_checkbox;
|
||||
}
|
||||
|
||||
wxWindow* PreferencesDialog::create_item_downloads(wxWindow* parent, int padding_left, std::string param)
|
||||
{
|
||||
wxString download_path = wxString::FromUTF8(app_config->get("download_path"));
|
||||
auto item_panel = new wxWindow(parent, wxID_ANY);
|
||||
item_panel->SetBackgroundColour(*wxWHITE);
|
||||
wxBoxSizer* m_sizer_checkbox = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
|
||||
auto m_staticTextPath = new wxStaticText(item_panel, wxID_ANY, download_path, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
|
||||
//m_staticTextPath->SetMaxSize(wxSize(FromDIP(440), -1));
|
||||
m_staticTextPath->SetForegroundColour(DESIGN_GRAY600_COLOR);
|
||||
m_staticTextPath->SetFont(::Label::Body_13);
|
||||
m_staticTextPath->Wrap(-1);
|
||||
|
||||
auto m_button_download = new Button(item_panel, _L("Browse"));
|
||||
|
||||
StateColor abort_bg(std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Disabled), std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
|
||||
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered), std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Enabled),
|
||||
std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Normal));
|
||||
m_button_download->SetBackgroundColor(abort_bg);
|
||||
StateColor abort_bd(std::pair<wxColour, int>(wxColour(144, 144, 144), StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
|
||||
m_button_download->SetBorderColor(abort_bd);
|
||||
StateColor abort_text(std::pair<wxColour, int>(wxColour(144, 144, 144), StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
|
||||
m_button_download->SetTextColor(abort_text);
|
||||
m_button_download->SetFont(Label::Body_10);
|
||||
m_button_download->SetMinSize(wxSize(FromDIP(58), FromDIP(22)));
|
||||
m_button_download->SetSize(wxSize(FromDIP(58), FromDIP(22)));
|
||||
m_button_download->SetCornerRadius(FromDIP(12));
|
||||
|
||||
m_button_download->Bind(wxEVT_BUTTON, [this, m_staticTextPath, item_panel](auto& e) {
|
||||
wxString defaultPath = wxT("/");
|
||||
wxDirDialog dialog(this, _L("Choose Download Directory"), defaultPath, wxDD_NEW_DIR_BUTTON);
|
||||
|
||||
if (dialog.ShowModal() == wxID_OK) {
|
||||
wxString download_path = dialog.GetPath();
|
||||
std::string download_path_str = download_path.ToUTF8().data();
|
||||
app_config->set("download_path", download_path_str);
|
||||
m_staticTextPath->SetLabelText(download_path);
|
||||
item_panel->Layout();
|
||||
}
|
||||
});
|
||||
|
||||
m_sizer_checkbox->Add(m_staticTextPath, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
|
||||
m_sizer_checkbox->Add(m_button_download, 0, wxALL, FromDIP(5));
|
||||
|
||||
item_panel->SetSizer(m_sizer_checkbox);
|
||||
item_panel->Layout();
|
||||
|
||||
return item_panel;
|
||||
}
|
||||
|
||||
wxWindow *PreferencesDialog ::create_item_radiobox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, int groupid, std::string param)
|
||||
{
|
||||
wxWindow *item = new wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(28)));
|
||||
|
@ -688,6 +742,8 @@ wxWindow* PreferencesDialog::create_general_page()
|
|||
std::vector<wxString> Units = {_L("Metric"), _L("Imperial")};
|
||||
auto item_currency = create_item_combobox(_L("Units"), page, _L("Units"), "use_inches", Units);
|
||||
|
||||
auto item_hints = create_item_checkbox(_L("Show \"Tip of the day\" notification after start"), page, _L("If enabled, useful hints are displayed at startup."), 50, "show_hints");
|
||||
|
||||
auto title_sync_settings = create_item_title(_L("User sync"), page, _L("User sync"));
|
||||
auto item_user_sync = create_item_checkbox(_L("Auto sync user presets(Printer/Filament/Process)"), page, _L("User Sync"), 50, "sync_user_preset");
|
||||
|
||||
|
@ -709,10 +765,15 @@ wxWindow* PreferencesDialog::create_general_page()
|
|||
auto item_backup = create_item_checkbox(_L("Auto-Backup"), page,_L("Auto-Backup"), 50, "backup_switch");
|
||||
auto item_backup_interval = create_item_backup_input(_L("Backup interval"), page, _L("Backup interval"), "backup_interval");
|
||||
|
||||
//downloads
|
||||
auto title_downloads = create_item_title(_L("Downloads"), page, _L("Downloads"));
|
||||
auto item_downloads = create_item_downloads(page,50,"download_path");
|
||||
|
||||
sizer_page->Add(title_general_settings, 0, wxEXPAND, 0);
|
||||
sizer_page->Add(item_language, 0, wxTOP, FromDIP(3));
|
||||
sizer_page->Add(item_region, 0, wxTOP, FromDIP(3));
|
||||
sizer_page->Add(item_currency, 0, wxTOP, FromDIP(3));
|
||||
sizer_page->Add(item_hints, 0, wxTOP, FromDIP(3));
|
||||
sizer_page->Add(title_sync_settings, 0, wxTOP | wxEXPAND, FromDIP(20));
|
||||
sizer_page->Add(item_user_sync, 0, wxTOP, FromDIP(3));
|
||||
#ifdef _WIN32
|
||||
|
@ -726,6 +787,9 @@ wxWindow* PreferencesDialog::create_general_page()
|
|||
sizer_page->Add(item_backup_interval, 0, wxTOP,FromDIP(3));
|
||||
//sizer_page->Add(0, 0, 0, wxTOP, 26);
|
||||
|
||||
sizer_page->Add(title_downloads, 0, wxTOP| wxEXPAND, FromDIP(20));
|
||||
sizer_page->Add(item_downloads, 0, wxEXPAND, FromDIP(3));
|
||||
|
||||
|
||||
page->SetSizer(sizer_page);
|
||||
page->Layout();
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace Slic3r { namespace GUI {
|
|||
#define DESIGN_SELECTOR_NOMORE_COLOR wxColour(248, 248, 248)
|
||||
#define DESIGN_GRAY900_COLOR wxColour(38, 46, 48)
|
||||
#define DESIGN_GRAY800_COLOR wxColour(50, 58, 61)
|
||||
#define DESIGN_GRAY600_COLOR wxColour(144, 144, 144)
|
||||
#define DESIGN_GRAY400_COLOR wxColour(166, 169, 170)
|
||||
|
||||
class Selector
|
||||
|
@ -106,7 +107,8 @@ public:
|
|||
wxBoxSizer *create_item_language_combobox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param, std::vector<const wxLanguageInfo *> vlist);
|
||||
wxBoxSizer *create_item_loglevel_combobox(wxString title, wxWindow *parent, wxString tooltip, std::vector<wxString> vlist);
|
||||
wxBoxSizer *create_item_checkbox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param);
|
||||
wxBoxSizer *create_item_backup_checkbox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param);
|
||||
wxWindow* create_item_downloads(wxWindow* parent, int padding_left, std::string param);
|
||||
wxBoxSizer* create_item_backup_checkbox(wxString title, wxWindow* parent, wxString tooltip, int padding_left, std::string param);
|
||||
wxBoxSizer *create_item_backup_input(wxString title, wxWindow *parent, wxString tooltip, std::string param);
|
||||
wxBoxSizer *create_item_multiple_combobox(
|
||||
wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string parama, std::vector<wxString> vlista, std::vector<wxString> vlistb);
|
||||
|
@ -125,7 +127,6 @@ public:
|
|||
void create_select_domain_widget();
|
||||
|
||||
void Split(const std::string &src, const std::string &separator, std::vector<wxString> &dest);
|
||||
|
||||
int m_current_language_selected = {0};
|
||||
|
||||
protected:
|
||||
|
|
|
@ -50,8 +50,9 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
|
|||
auto *label_dir_hint = new wxStaticText(this, wxID_ANY, _L("Use forward slashes ( / ) as a directory separator if needed."));
|
||||
label_dir_hint->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
|
||||
|
||||
content_sizer->Add(txt_filename, 0, wxEXPAND);
|
||||
content_sizer->Add(label_dir_hint);
|
||||
content_sizer->Add(txt_filename, 0, wxEXPAND | wxALL, FromDIP(10));
|
||||
content_sizer->Add(FromDIP(10), FromDIP(10), 0, 0);
|
||||
content_sizer->Add(label_dir_hint, 0, 0, FromDIP(10));
|
||||
content_sizer->AddSpacer(VERT_SPACING);
|
||||
|
||||
if (combo_groups != nullptr) {
|
||||
|
|
|
@ -1,28 +1,35 @@
|
|||
#pragma once
|
||||
#ifndef _BAMBU__TUNNEL_H_
|
||||
#define _BAMBU__TUNNEL_H_
|
||||
|
||||
#ifdef BAMBU_DYNAMIC
|
||||
# define BAMBU_EXPORT
|
||||
# define BAMBU_FUNC(x) (*x)
|
||||
#else
|
||||
# ifdef __WIN32__
|
||||
# define BAMBU_EXPORT __declspec(dllexport)
|
||||
# ifdef _WIN32
|
||||
# ifdef BAMBU_EXPORTS
|
||||
# define BAMBU_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define BAMBU_EXPORT __declspec(dllimport)
|
||||
# endif // BAMBU_EXPORTS
|
||||
# else
|
||||
# define BAMBU_EXPORT
|
||||
# endif // __WIN32__
|
||||
# define BAMBU_FUNC(x) x
|
||||
#endif
|
||||
#endif // BAMBU_DYNAMIC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
struct Bambu_Session;
|
||||
#ifdef __WIN32__
|
||||
typedef wchar_t Bambu_Message;
|
||||
#ifdef _WIN32
|
||||
typedef wchar_t tchar;
|
||||
#else
|
||||
typedef char Bambu_Message;
|
||||
typedef char tchar;
|
||||
#endif
|
||||
typedef void (*Logger)(Bambu_Session * session, int level, Bambu_Message const * msg);
|
||||
|
||||
typedef void* Bambu_Tunnel;
|
||||
|
||||
typedef void (*Logger)(void * context, int level, tchar const* msg);
|
||||
|
||||
enum Bambu_StreamType
|
||||
{
|
||||
|
@ -89,48 +96,39 @@ enum Bambu_Error
|
|||
{
|
||||
Bambu_success,
|
||||
Bambu_stream_end,
|
||||
Bambu_would_block
|
||||
};
|
||||
|
||||
struct Bambu_Session
|
||||
{
|
||||
int gSID = -1;
|
||||
int avIndex = -1;
|
||||
int block = 0;
|
||||
int block_next = 0;
|
||||
Logger logger = nullptr;
|
||||
void * buffer = nullptr;
|
||||
int buffer_size = 0;
|
||||
void * extra = 0;
|
||||
void * dump_file1 = nullptr;
|
||||
void * dump_file2 = nullptr;
|
||||
|
||||
void Log(int unused, int level, wchar_t const * format, ...);
|
||||
Bambu_would_block,
|
||||
Bambu_buffer_limit
|
||||
};
|
||||
|
||||
#ifdef BAMBU_DYNAMIC
|
||||
struct BambuLib {
|
||||
#endif
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_Open)(Bambu_Session* session, char const* uid);
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_Create)(Bambu_Tunnel* tunnel, char const* path);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_StartStream)(Bambu_Session* session);
|
||||
BAMBU_EXPORT void BAMBU_FUNC(Bambu_SetLogger)(Bambu_Tunnel tunnel, Logger logger, void * context);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_GetStreamCount)(Bambu_Session* session);
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_Open)(Bambu_Tunnel tunnel);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_GetStreamInfo)(Bambu_Session* session, int index, Bambu_StreamInfo* info);
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_StartStream)(Bambu_Tunnel tunnel, bool video);
|
||||
|
||||
BAMBU_EXPORT unsigned long BAMBU_FUNC(Bambu_GetDuration)(Bambu_Session* session);
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_GetStreamCount)(Bambu_Tunnel tunnel);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_Seek)(Bambu_Session* session, unsigned long time);
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_GetStreamInfo)(Bambu_Tunnel tunnel, int index, Bambu_StreamInfo* info);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_ReadSample)(Bambu_Session* session, Bambu_Sample* sample);
|
||||
BAMBU_EXPORT unsigned long BAMBU_FUNC(Bambu_GetDuration)(Bambu_Tunnel tunnel);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_SendMessage)(Bambu_Session* session, int ctrl, char const* data, int len);
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_Seek)(Bambu_Tunnel tunnel, unsigned long time);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_RecvMessage)(Bambu_Session* session, int* ctrl, char* data, int* len);
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_ReadSample)(Bambu_Tunnel tunnel, Bambu_Sample* sample);
|
||||
|
||||
BAMBU_EXPORT void BAMBU_FUNC(Bambu_Close)(Bambu_Session* session);
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_SendMessage)(Bambu_Tunnel tunnel, int ctrl, char const* data, int len);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_RecvMessage)(Bambu_Tunnel tunnel, int* ctrl, char* data, int* len);
|
||||
|
||||
BAMBU_EXPORT void BAMBU_FUNC(Bambu_Close)(Bambu_Tunnel tunnel);
|
||||
|
||||
BAMBU_EXPORT void BAMBU_FUNC(Bambu_Destroy)(Bambu_Tunnel tunnel);
|
||||
|
||||
BAMBU_EXPORT int BAMBU_FUNC(Bambu_Init)();
|
||||
|
||||
|
@ -138,7 +136,7 @@ BAMBU_EXPORT void BAMBU_FUNC(Bambu_Deinit)();
|
|||
|
||||
BAMBU_EXPORT char const* BAMBU_FUNC(Bambu_GetLastErrorMsg)();
|
||||
|
||||
BAMBU_EXPORT void BAMBU_FUNC(Bambu_FreeLogMsg)(Bambu_Message const* msg);
|
||||
BAMBU_EXPORT void BAMBU_FUNC(Bambu_FreeLogMsg)(tchar const* msg);
|
||||
|
||||
#ifdef BAMBU_DYNAMIC
|
||||
};
|
||||
|
@ -147,3 +145,5 @@ BAMBU_EXPORT void BAMBU_FUNC(Bambu_FreeLogMsg)(Bambu_Message const* msg);
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _BAMBU__TUNNEL_H_
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
#include "../../Utils/NetworkAgent.hpp"
|
||||
#include "../BitmapCache.hpp"
|
||||
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/uuid/detail/md5.hpp>
|
||||
|
@ -10,9 +11,14 @@
|
|||
|
||||
#include <cstring>
|
||||
|
||||
#ifndef NDEBUG
|
||||
//#define PRINTER_FILE_SYSTEM_TEST
|
||||
#endif
|
||||
|
||||
wxDEFINE_EVENT(EVT_STATUS_CHANGED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_MODE_CHANGED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_FILE_CHANGED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_SELECT_CHANGED, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_THUMBNAIL, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_DOWNLOAD, wxCommandEvent);
|
||||
|
||||
|
@ -22,21 +28,26 @@ static wxBitmap default_thumbnail;
|
|||
|
||||
struct StaticBambuLib : BambuLib {
|
||||
static StaticBambuLib & get();
|
||||
static int Fake_Bambu_Open(Bambu_Session * session, char const* uid) { return -2; }
|
||||
static int Fake_Bambu_Create(Bambu_Tunnel*, char const*) { return -2; }
|
||||
};
|
||||
|
||||
PrinterFileSystem::PrinterFileSystem()
|
||||
: BambuLib(StaticBambuLib::get())
|
||||
{
|
||||
if (!default_thumbnail.IsOk())
|
||||
default_thumbnail = wxImage(Slic3r::encode_path(Slic3r::var("live_stream_default.png").c_str()));
|
||||
default_thumbnail = *Slic3r::GUI::BitmapCache().load_svg("printer_file", 0, 0);
|
||||
m_session.owner = this;
|
||||
//auto time = wxDateTime::Now();
|
||||
//for (int i = 0; i < 240; ++i) {
|
||||
// m_file_list.push_back({"", time.GetTicks(), 0, default_thumbnail, FF_DOWNLOAD, i - 130});
|
||||
// time.Add(wxDateSpan::Days(-1));
|
||||
//}
|
||||
//BuildGroups();
|
||||
#ifdef PRINTER_FILE_SYSTEM_TEST
|
||||
auto time = wxDateTime::Now();
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
auto name = wxString::Format(L"img-%03d.jpg", i + 1);
|
||||
wxImage im(L"D:\\work\\pic\\" + name);
|
||||
m_file_list.push_back({name.ToUTF8().data(), time.GetTicks(), 26937, im, i < 20 ? FF_DOWNLOAD : 0, i * 10 - 40});
|
||||
time.Add(wxDateSpan::Days(-1));
|
||||
}
|
||||
m_file_list[0].thumbnail = default_thumbnail;
|
||||
BuildGroups();
|
||||
#endif
|
||||
}
|
||||
|
||||
PrinterFileSystem::~PrinterFileSystem()
|
||||
|
@ -102,6 +113,7 @@ void PrinterFileSystem::ListAllFiles()
|
|||
iter1->thumbnail = iter2->thumbnail;
|
||||
iter1->flags = iter2->flags;
|
||||
iter1->progress = iter2->progress;
|
||||
iter1->path = iter2->path;
|
||||
++iter1; ++iter2;
|
||||
} else if (*iter1 < *iter2) {
|
||||
++iter1;
|
||||
|
@ -154,6 +166,7 @@ void PrinterFileSystem::DownloadFiles(size_t index, std::string const &path)
|
|||
if ((file.flags & FF_DOWNLOAD) != 0 && file.progress >= 0) continue;
|
||||
file.flags |= FF_DOWNLOAD;
|
||||
file.progress = -1;
|
||||
file.path = (boost::filesystem::path(path) / file.name).string();
|
||||
++n;
|
||||
}
|
||||
if (n == 0) return;
|
||||
|
@ -165,9 +178,40 @@ void PrinterFileSystem::DownloadFiles(size_t index, std::string const &path)
|
|||
return;
|
||||
file.flags |= FF_DOWNLOAD;
|
||||
file.progress = -1;
|
||||
file.path = (boost::filesystem::path(path) / file.name).string();
|
||||
}
|
||||
if ((m_task_flags & FF_DOWNLOAD) == 0)
|
||||
DownloadNextFile(path);
|
||||
DownloadNextFile();
|
||||
}
|
||||
|
||||
void PrinterFileSystem::DownloadCheckFiles(std::string const &path)
|
||||
{
|
||||
for (size_t i = 0; i < m_file_list.size(); ++i) {
|
||||
auto &file = m_file_list[i];
|
||||
if ((file.flags & FF_DOWNLOAD) != 0 && file.progress >= 0) continue;
|
||||
auto path2 = boost::filesystem::path(path) / file.name;
|
||||
boost::system::error_code ec;
|
||||
if (boost::filesystem::file_size(path2, ec) == file.size) {
|
||||
file.flags |= FF_DOWNLOAD;
|
||||
file.progress = 100;
|
||||
file.path = path2.string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PrinterFileSystem::DownloadCheckFile(size_t index)
|
||||
{
|
||||
if (index >= m_file_list.size()) return false;
|
||||
auto &file = m_file_list[index];
|
||||
if ((file.flags & FF_DOWNLOAD) == 0) return false;
|
||||
if (!boost::filesystem::exists(file.path)) {
|
||||
file.flags &= ~FF_DOWNLOAD;
|
||||
file.progress = 0;
|
||||
file.path.clear();
|
||||
SendChangedEvent(EVT_DOWNLOAD, index, file.path);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrinterFileSystem::DownloadCancel(size_t index)
|
||||
|
@ -201,17 +245,30 @@ size_t PrinterFileSystem::GetIndexAtTime(boost::uint32_t time)
|
|||
|
||||
void PrinterFileSystem::ToggleSelect(size_t index)
|
||||
{
|
||||
if (index < m_file_list.size()) m_file_list[index].flags ^= FF_SELECT;
|
||||
if (index < m_file_list.size()) {
|
||||
m_file_list[index].flags ^= FF_SELECT;
|
||||
if (m_file_list[index].flags & FF_SELECT)
|
||||
++m_select_count;
|
||||
else
|
||||
--m_select_count;
|
||||
}
|
||||
SendChangedEvent(EVT_SELECT_CHANGED, m_select_count);
|
||||
}
|
||||
|
||||
void PrinterFileSystem::SelectAll(bool select)
|
||||
{
|
||||
if (select)
|
||||
if (select) {
|
||||
for (auto &f : m_file_list) f.flags |= FF_SELECT;
|
||||
else
|
||||
m_select_count = m_file_list.size();
|
||||
} else {
|
||||
for (auto &f : m_file_list) f.flags &= ~FF_SELECT;
|
||||
m_select_count = 0;
|
||||
}
|
||||
SendChangedEvent(EVT_SELECT_CHANGED, m_select_count);
|
||||
}
|
||||
|
||||
size_t PrinterFileSystem::GetSelectCount() const { return m_select_count; }
|
||||
|
||||
void PrinterFileSystem::SetFocusRange(size_t start, size_t count)
|
||||
{
|
||||
m_lock_start = start;
|
||||
|
@ -234,7 +291,7 @@ int PrinterFileSystem::RecvData(std::function<int(Bambu_Sample& sample)> const &
|
|||
int result = 0;
|
||||
while (true) {
|
||||
Bambu_Sample sample;
|
||||
result = Bambu_ReadSample(&m_session, &sample);
|
||||
result = Bambu_ReadSample(m_session.tunnel, &sample);
|
||||
if (result == Bambu_success) {
|
||||
result = callback(sample);
|
||||
if (result == 1)
|
||||
|
@ -320,7 +377,7 @@ void PrinterFileSystem::DeleteFilesContinue()
|
|||
std::vector<size_t> indexes;
|
||||
std::vector<std::string> names;
|
||||
for (size_t i = 0; i < m_file_list.size(); ++i)
|
||||
if ((m_file_list[i].flags & FF_SELECT) && !m_file_list[i].name.empty()) {
|
||||
if ((m_file_list[i].flags & FF_DELETED) && !m_file_list[i].name.empty()) {
|
||||
indexes.push_back(i);
|
||||
names.push_back(m_file_list[i].name);
|
||||
if (names.size() >= 64)
|
||||
|
@ -338,14 +395,14 @@ void PrinterFileSystem::DeleteFilesContinue()
|
|||
FILE_DEL, req, nullptr,
|
||||
[indexes, names, this](int, Void const &) {
|
||||
// TODO:
|
||||
for (size_t i = indexes.size() - 1; i >= 0; --i)
|
||||
for (size_t i = indexes.size() - 1; i != size_t(-1); --i)
|
||||
FileRemoved(indexes[i], names[i]);
|
||||
SendChangedEvent(EVT_FILE_CHANGED);
|
||||
SendChangedEvent(EVT_FILE_CHANGED, indexes.size());
|
||||
DeleteFilesContinue();
|
||||
});
|
||||
}
|
||||
|
||||
void PrinterFileSystem::DownloadNextFile(std::string const &path)
|
||||
void PrinterFileSystem::DownloadNextFile()
|
||||
{
|
||||
size_t index = size_t(-1);
|
||||
for (size_t i = 0; i < m_file_list.size(); ++i) {
|
||||
|
@ -363,16 +420,16 @@ void PrinterFileSystem::DownloadNextFile(std::string const &path)
|
|||
SendChangedEvent(EVT_DOWNLOAD, index, m_file_list[index].name);
|
||||
struct Download
|
||||
{
|
||||
int index;
|
||||
std::string name;
|
||||
std::string path;
|
||||
size_t index;
|
||||
std::string name;
|
||||
std::string path;
|
||||
boost::filesystem::ofstream ofs;
|
||||
boost::uuids::detail::md5 boost_md5;
|
||||
boost::uuids::detail::md5 boost_md5;
|
||||
};
|
||||
std::shared_ptr<Download> download(new Download);
|
||||
download->index = index;
|
||||
download->name = m_file_list[index].name;
|
||||
download->path = path;
|
||||
download->path = m_file_list[index].path;
|
||||
m_task_flags |= FF_DOWNLOAD;
|
||||
m_download_seq = SendRequest<Progress>(
|
||||
FILE_DOWNLOAD, req,
|
||||
|
@ -382,7 +439,7 @@ void PrinterFileSystem::DownloadNextFile(std::string const &path)
|
|||
prog.size = resp["offset"];
|
||||
prog.total = resp["total"];
|
||||
if (prog.size == 0) {
|
||||
download->ofs.open(download->path + "/" + download->name, std::ios::binary);
|
||||
download->ofs.open(download->path, std::ios::binary);
|
||||
if (!download->ofs) return FILE_OPEN_ERR;
|
||||
}
|
||||
// receive data
|
||||
|
@ -412,9 +469,9 @@ void PrinterFileSystem::DownloadNextFile(std::string const &path)
|
|||
return result;
|
||||
},
|
||||
[this, download](int result, Progress const &data) {
|
||||
if (download->index >= 0)
|
||||
if (download->index != size_t(-1))
|
||||
download->index = FindFile(download->index, download->name);
|
||||
if (download->index >= 0) {
|
||||
if (download->index != size_t(-1)) {
|
||||
int progress = data.size * 100 / data.total;
|
||||
if (result > CONTINUE)
|
||||
progress = -2;
|
||||
|
@ -423,10 +480,10 @@ void PrinterFileSystem::DownloadNextFile(std::string const &path)
|
|||
file.flags &= ~FF_DOWNLOAD;
|
||||
else if (file.progress != progress) {
|
||||
file.progress = progress;
|
||||
SendChangedEvent(EVT_DOWNLOAD, download->index, m_file_list[download->index].name, data.size);
|
||||
SendChangedEvent(EVT_DOWNLOAD, download->index, file.path, data.size);
|
||||
}
|
||||
}
|
||||
if (result != CONTINUE) DownloadNextFile(download->path);
|
||||
if (result != CONTINUE) DownloadNextFile();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -556,15 +613,15 @@ void PrinterFileSystem::SendChangedEvent(wxEventType type, size_t index, std::st
|
|||
wxPostEvent(this, event);
|
||||
}
|
||||
|
||||
void PrinterFileSystem::DumpLog(Bambu_Session *session, int level, Bambu_Message const *msg)
|
||||
void PrinterFileSystem::DumpLog(void * thiz, int, tchar const *msg)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "PrinterFileSystem: " << msg;
|
||||
StaticBambuLib::get().Bambu_FreeLogMsg(msg);
|
||||
static_cast<PrinterFileSystem*>(thiz)->Bambu_FreeLogMsg(msg);
|
||||
}
|
||||
|
||||
boost::uint32_t PrinterFileSystem::SendRequest(int type, json const &req, callback_t2 const &callback)
|
||||
{
|
||||
if (m_session.gSID < 0) {
|
||||
if (m_session.tunnel == nullptr) {
|
||||
boost::unique_lock l(m_mutex);
|
||||
m_cond.notify_all();
|
||||
return 0;
|
||||
|
@ -640,7 +697,7 @@ void PrinterFileSystem::RecvMessageThread()
|
|||
if (!m_messages.empty()) {
|
||||
auto & msg = m_messages.front();
|
||||
l.unlock();
|
||||
int n = Bambu_SendMessage(&m_session, CTRL_TYPE, msg.c_str(), msg.length());
|
||||
int n = Bambu_SendMessage(m_session.tunnel, CTRL_TYPE, msg.c_str(), msg.length());
|
||||
l.lock();
|
||||
if (n == 0)
|
||||
m_messages.pop_front();
|
||||
|
@ -650,7 +707,7 @@ void PrinterFileSystem::RecvMessageThread()
|
|||
}
|
||||
}
|
||||
l.unlock();
|
||||
int n = Bambu_ReadSample(&m_session, &sample);
|
||||
int n = Bambu_ReadSample(m_session.tunnel, &sample);
|
||||
l.lock();
|
||||
if (n == 0) {
|
||||
HandleResponse(l, sample);
|
||||
|
@ -726,9 +783,12 @@ void PrinterFileSystem::HandleResponse(boost::unique_lock<boost::mutex> &l, Bamb
|
|||
|
||||
void PrinterFileSystem::Reconnect(boost::unique_lock<boost::mutex> &l, int result)
|
||||
{
|
||||
if (m_session.gSID >= 0) {
|
||||
if (m_session.tunnel) {
|
||||
auto tunnel = m_session.tunnel;
|
||||
m_session.tunnel = nullptr;
|
||||
l.unlock();
|
||||
Bambu_Close(&m_session);
|
||||
Bambu_Close(tunnel);
|
||||
Bambu_Destroy(tunnel);
|
||||
l.lock();
|
||||
}
|
||||
if (m_session.owner == nullptr)
|
||||
|
@ -761,11 +821,16 @@ void PrinterFileSystem::Reconnect(boost::unique_lock<boost::mutex> &l, int resul
|
|||
l.unlock();
|
||||
m_status = Status::Connecting;
|
||||
SendChangedEvent(EVT_STATUS_CHANGED, m_status);
|
||||
m_session.logger = &PrinterFileSystem::DumpLog;
|
||||
int ret = Bambu_Open(&m_session, url.c_str() + 9); // skip bambu:/// sync
|
||||
Bambu_Tunnel tunnel = nullptr;
|
||||
int ret = Bambu_Create(&tunnel, url.c_str());
|
||||
if (ret == 0) {
|
||||
Bambu_SetLogger(tunnel, DumpLog, this);
|
||||
ret = Bambu_Open(tunnel);
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = Bambu_StartStream(&m_session);
|
||||
ret = Bambu_StartStream(tunnel, false);
|
||||
l.lock();
|
||||
m_session.tunnel = tunnel;
|
||||
if (ret == 0)
|
||||
break;
|
||||
m_last_error = ret;
|
||||
|
@ -776,7 +841,11 @@ void PrinterFileSystem::Reconnect(boost::unique_lock<boost::mutex> &l, int resul
|
|||
}
|
||||
m_status = Status::ListSyncing;
|
||||
SendChangedEvent(EVT_STATUS_CHANGED, m_status);
|
||||
#ifdef PRINTER_FILE_SYSTEM_TEST
|
||||
PostCallback([this] { SendChangedEvent(EVT_FILE_CHANGED); });
|
||||
#else
|
||||
PostCallback([this] { ListAllFiles(); });
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -818,6 +887,9 @@ StaticBambuLib &StaticBambuLib::get()
|
|||
{
|
||||
static StaticBambuLib lib;
|
||||
// first load the library
|
||||
|
||||
if (lib.Bambu_Open)
|
||||
return lib;
|
||||
|
||||
if (!module) {
|
||||
module = Slic3r::NetworkAgent::get_bambu_source_entry();
|
||||
|
@ -827,14 +899,17 @@ StaticBambuLib &StaticBambuLib::get()
|
|||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", can not Load Library";
|
||||
}
|
||||
|
||||
GET_FUNC(Bambu_Create);
|
||||
GET_FUNC(Bambu_Open);
|
||||
GET_FUNC(Bambu_StartStream);
|
||||
GET_FUNC(Bambu_SendMessage);
|
||||
GET_FUNC(Bambu_ReadSample);
|
||||
GET_FUNC(Bambu_Close);
|
||||
GET_FUNC(Bambu_Destroy);
|
||||
GET_FUNC(Bambu_SetLogger);
|
||||
GET_FUNC(Bambu_FreeLogMsg);
|
||||
|
||||
if (!lib.Bambu_Open)
|
||||
lib.Bambu_Open = Fake_Bambu_Open;
|
||||
lib.Bambu_Create = Fake_Bambu_Create;
|
||||
return lib;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ using nlohmann::json;
|
|||
wxDECLARE_EVENT(EVT_STATUS_CHANGED, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_MODE_CHANGED, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_FILE_CHANGED, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_SELECT_CHANGED, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_THUMBNAIL, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_DOWNLOAD, wxCommandEvent);
|
||||
|
||||
|
@ -95,6 +96,7 @@ public:
|
|||
wxBitmap thumbnail;
|
||||
int flags = 0;
|
||||
int progress = -1; // -1: waiting
|
||||
std::string path;
|
||||
|
||||
bool IsSelect() const { return flags & FF_SELECT; }
|
||||
bool IsDownload() const { return flags & FF_DOWNLOAD; }
|
||||
|
@ -124,6 +126,10 @@ public:
|
|||
|
||||
void DownloadFiles(size_t index, std::string const &path);
|
||||
|
||||
void DownloadCheckFiles(std::string const &path);
|
||||
|
||||
bool DownloadCheckFile(size_t index);
|
||||
|
||||
void DownloadCancel(size_t index);
|
||||
|
||||
size_t GetCount() const;
|
||||
|
@ -134,6 +140,8 @@ public:
|
|||
|
||||
void SelectAll(bool select);
|
||||
|
||||
size_t GetSelectCount() const;
|
||||
|
||||
void SetFocusRange(size_t start, size_t count);
|
||||
|
||||
File const &GetFile(size_t index);
|
||||
|
@ -164,7 +172,7 @@ private:
|
|||
|
||||
void DeleteFilesContinue();
|
||||
|
||||
void DownloadNextFile(std::string const &path);
|
||||
void DownloadNextFile();
|
||||
|
||||
void UpdateFocusThumbnail();
|
||||
|
||||
|
@ -174,7 +182,7 @@ private:
|
|||
|
||||
void SendChangedEvent(wxEventType type, size_t index = (size_t)-1, std::string const &str = {}, long extra = 0);
|
||||
|
||||
static void DumpLog(Bambu_Session *session, int level, Bambu_Message const *msg);
|
||||
static void DumpLog(void* context, int level, tchar const *msg);
|
||||
|
||||
private:
|
||||
template<typename T> using Translator = std::function<int(json const &, T &, unsigned char const *)>;
|
||||
|
@ -260,13 +268,15 @@ protected:
|
|||
std::vector<size_t> m_group_month;
|
||||
|
||||
private:
|
||||
size_t m_select_count = 0;
|
||||
size_t m_lock_start = 0;
|
||||
size_t m_lock_end = 0;
|
||||
int m_task_flags = 0;
|
||||
|
||||
private:
|
||||
struct Session : Bambu_Session
|
||||
struct Session
|
||||
{
|
||||
Bambu_Tunnel tunnel = nullptr;
|
||||
PrinterFileSystem * owner;
|
||||
};
|
||||
Session m_session;
|
||||
|
|
|
@ -57,12 +57,12 @@ ReleaseNoteDialog::ReleaseNoteDialog(Plater *plater /*= nullptr*/)
|
|||
|
||||
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);
|
||||
m_scrollwindw_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||
m_scrollwindw_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)), wxVSCROLL);
|
||||
m_vebview_release_note->SetScrollRate(5, 5);
|
||||
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||
m_vebview_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
|
||||
m_sizer_right->Add(m_scrollwindw_release_note, 0, wxEXPAND | wxRIGHT, FromDIP(20));
|
||||
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT, FromDIP(20));
|
||||
m_sizer_body->Add(m_sizer_right, 1, wxBOTTOM | wxEXPAND, FromDIP(30));
|
||||
m_sizer_main->Add(m_sizer_body, 0, wxEXPAND, 0);
|
||||
|
||||
|
@ -84,11 +84,11 @@ void ReleaseNoteDialog::update_release_note(wxString release_note, std::string v
|
|||
{
|
||||
m_text_up_info->SetLabel(wxString::Format(_L("version %s update information :"), 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);
|
||||
auto m_staticText_release_note = new wxStaticText(m_vebview_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_vebview_release_note->SetSizer(sizer_text_release_note);
|
||||
m_vebview_release_note->Layout();
|
||||
}
|
||||
|
||||
void UpdateVersionDialog::alter_choice(wxCommandEvent& event)
|
||||
|
@ -130,12 +130,22 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
|
|||
|
||||
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
|
||||
|
||||
m_simplebook_release_note = new wxSimplebook(this);
|
||||
m_simplebook_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
m_simplebook_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
m_simplebook_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
m_simplebook_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||
|
||||
m_scrollwindows_release_note = new wxScrolledWindow(m_simplebook_release_note, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(560), FromDIP(430)), wxVSCROLL);
|
||||
m_scrollwindows_release_note->SetScrollRate(5, 5);
|
||||
m_scrollwindows_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||
|
||||
//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)));
|
||||
m_vebview_release_note = CreateTipView(m_simplebook_release_note);
|
||||
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||
m_vebview_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
m_vebview_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430)));
|
||||
|
||||
fs::path ph(data_dir());
|
||||
ph /= "resources/tooltip/common/releasenote.html";
|
||||
|
@ -146,7 +156,10 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
|
|||
auto url = ph.string();
|
||||
std::replace(url.begin(), url.end(), '\\', '/');
|
||||
url = "file:///" + url;
|
||||
m_scrollwindw_release_note->LoadURL(from_u8(url));
|
||||
m_vebview_release_note->LoadURL(from_u8(url));
|
||||
|
||||
m_simplebook_release_note->AddPage(m_scrollwindows_release_note, wxEmptyString, false);
|
||||
m_simplebook_release_note->AddPage(m_vebview_release_note, wxEmptyString, false);
|
||||
|
||||
|
||||
m_remind_choice = new wxCheckBox( this, wxID_ANY, _L("Don't remind me of this version again"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
@ -193,7 +206,7 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
|
|||
sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
|
||||
|
||||
|
||||
m_sizer_right->Add(m_scrollwindw_release_note, 0, wxEXPAND | wxRIGHT, FromDIP(20));
|
||||
m_sizer_right->Add(m_simplebook_release_note, 0, wxEXPAND | wxRIGHT, FromDIP(20));
|
||||
m_sizer_right->Add(sizer_button, 0, wxEXPAND | wxRIGHT, FromDIP(20));
|
||||
|
||||
m_sizer_body->Add(m_sizer_right, 1, wxBOTTOM | wxEXPAND, FromDIP(8));
|
||||
|
@ -263,7 +276,7 @@ bool UpdateVersionDialog::ShowReleaseNote(std::string content)
|
|||
|
||||
void UpdateVersionDialog::RunScript(std::string script)
|
||||
{
|
||||
WebView::RunScript(m_scrollwindw_release_note, script);
|
||||
WebView::RunScript(m_vebview_release_note, script);
|
||||
script.clear();
|
||||
}
|
||||
|
||||
|
@ -272,32 +285,177 @@ void UpdateVersionDialog::on_dpi_changed(const wxRect &suggested_rect) {
|
|||
m_button_cancel->Rescale();
|
||||
}
|
||||
|
||||
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));
|
||||
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();*/
|
||||
std::vector<std::string> UpdateVersionDialog::splitWithStl(std::string str,std::string pattern)
|
||||
{
|
||||
std::string::size_type pos;
|
||||
std::vector<std::string> result;
|
||||
str += pattern;
|
||||
int size = str.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
pos = str.find(pattern, i);
|
||||
if (pos < size)
|
||||
{
|
||||
std::string s = str.substr(i, pos - i);
|
||||
result.push_back(s);
|
||||
i = pos + pattern.size() - 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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));
|
||||
void UpdateVersionDialog::update_version_info(wxString release_note, wxString version)
|
||||
{
|
||||
//bbs check whether the web display is used
|
||||
bool use_web_link = false;
|
||||
std::string url_line = "";
|
||||
auto split_array = splitWithStl(release_note.ToStdString(), "###");
|
||||
|
||||
for (auto i = 0; i < split_array.size(); i++) {
|
||||
std::string url = split_array[i];
|
||||
if (std::strstr (url.c_str(), "http://") != NULL || std::strstr (url.c_str(), "https://") != NULL) {
|
||||
use_web_link = true;
|
||||
url_line = url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (use_web_link) {
|
||||
m_simplebook_release_note->SetSelection(1);
|
||||
m_vebview_release_note->LoadURL(from_u8(url_line));
|
||||
}
|
||||
else {
|
||||
m_scrollwindw_release_note->LoadURL(from_u8(url));
|
||||
m_simplebook_release_note->SetSelection(0);
|
||||
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_scrollwindows_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_scrollwindows_release_note->SetSizer(sizer_text_release_note);
|
||||
m_scrollwindows_release_note->Layout();
|
||||
}
|
||||
}
|
||||
|
||||
SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent)
|
||||
:DPIDialog(parent, wxID_ANY, _L("Confirm"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
|
||||
{
|
||||
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
|
||||
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
|
||||
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
wxBoxSizer* m_sizer_main = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(480), 1));
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
|
||||
|
||||
wxBoxSizer* m_sizer_right = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_sizer_right->Add(0, 0, 1, wxTOP, FromDIP(15));
|
||||
|
||||
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
|
||||
m_vebview_release_note->SetScrollRate(0, 5);
|
||||
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
|
||||
m_vebview_release_note->SetSize(wxSize(FromDIP(280), FromDIP(280)));
|
||||
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), FromDIP(280)));
|
||||
m_vebview_release_note->SetMaxSize(wxSize(FromDIP(280), FromDIP(280)));
|
||||
|
||||
|
||||
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
|
||||
|
||||
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
|
||||
|
||||
m_button_ok = new Button(this, _L("OK"));
|
||||
m_button_ok->SetBackgroundColor(btn_bg_green);
|
||||
m_button_ok->SetBorderColor(*wxWHITE);
|
||||
m_button_ok->SetTextColor(*wxWHITE);
|
||||
m_button_ok->SetFont(Label::Body_12);
|
||||
m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_ok->SetCornerRadius(FromDIP(12));
|
||||
|
||||
m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
EndModal(wxID_YES);
|
||||
});
|
||||
|
||||
m_button_cancel = new Button(this, _L("Cancel"));
|
||||
m_button_cancel->SetBackgroundColor(*wxWHITE);
|
||||
m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
|
||||
m_button_cancel->SetFont(Label::Body_12);
|
||||
m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
|
||||
m_button_cancel->SetCornerRadius(FromDIP(12));
|
||||
|
||||
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
EndModal(wxID_NO);
|
||||
});
|
||||
|
||||
sizer_button->AddStretchSpacer();
|
||||
sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5));
|
||||
sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
|
||||
|
||||
|
||||
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(20));
|
||||
m_sizer_right->Add(sizer_button, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(20));
|
||||
|
||||
|
||||
SetSizer(m_sizer_right);
|
||||
Layout();
|
||||
m_sizer_main->Fit(this);
|
||||
|
||||
CenterOnParent();
|
||||
}
|
||||
|
||||
void SecondaryCheckDialog::update_text(wxString text)
|
||||
{
|
||||
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_staticText_release_note = new wxStaticText(m_vebview_release_note, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_staticText_release_note->SetSize(wxSize(FromDIP(260), -1));
|
||||
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(260), -1));
|
||||
m_staticText_release_note->SetMinSize(wxSize(FromDIP(260), -1));
|
||||
|
||||
text = format_text(m_staticText_release_note, text, FromDIP(240));
|
||||
|
||||
m_staticText_release_note->SetLabelText(text);
|
||||
m_staticText_release_note->Wrap(FromDIP(240));
|
||||
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALIGN_CENTER, 5);
|
||||
m_vebview_release_note->SetSizer(sizer_text_release_note);
|
||||
m_vebview_release_note->Layout();
|
||||
//Fit();
|
||||
}
|
||||
|
||||
wxString SecondaryCheckDialog::format_text(wxStaticText* st, wxString str, int warp)
|
||||
{
|
||||
if (wxGetApp().app_config->get("language") != "zh_CN") { return str; }
|
||||
|
||||
wxString out_txt = str;
|
||||
wxString count_txt = "";
|
||||
int new_line_pos = 0;
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
auto text_size = st->GetTextExtent(count_txt);
|
||||
if (text_size.x < warp) {
|
||||
count_txt += str[i];
|
||||
}
|
||||
else {
|
||||
out_txt.insert(i - 1, '\n');
|
||||
count_txt = "";
|
||||
}
|
||||
}
|
||||
|
||||
return out_txt;
|
||||
}
|
||||
|
||||
SecondaryCheckDialog::~SecondaryCheckDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SecondaryCheckDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
void update_release_note(wxString release_note, std::string version);
|
||||
|
||||
wxStaticText * m_text_up_info{nullptr};
|
||||
wxScrolledWindow *m_scrollwindw_release_note {nullptr};
|
||||
wxScrolledWindow *m_vebview_release_note {nullptr};
|
||||
};
|
||||
|
||||
class UpdateVersionDialog : public DPIDialog
|
||||
|
@ -63,11 +63,14 @@ public:
|
|||
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 update_version_info(wxString release_note, wxString version);
|
||||
void alter_choice(wxCommandEvent& event);
|
||||
std::vector<std::string> splitWithStl(std::string str, std::string pattern);
|
||||
|
||||
wxStaticText * m_text_up_info{nullptr};
|
||||
wxWebView* m_scrollwindw_release_note{nullptr};
|
||||
wxWebView* m_vebview_release_note{nullptr};
|
||||
wxSimplebook* m_simplebook_release_note{nullptr};
|
||||
wxScrolledWindow* m_scrollwindows_release_note{nullptr};
|
||||
wxBoxSizer * sizer_text_release_note{nullptr};
|
||||
wxStaticText * m_staticText_release_note{nullptr};
|
||||
wxCheckBox* m_remind_choice;
|
||||
|
@ -75,6 +78,20 @@ public:
|
|||
Button* m_button_cancel;
|
||||
};
|
||||
|
||||
class SecondaryCheckDialog : public DPIDialog
|
||||
{
|
||||
public:
|
||||
SecondaryCheckDialog(wxWindow* parent);
|
||||
void update_text(wxString text);
|
||||
wxString format_text(wxStaticText* st, wxString str, int warp);
|
||||
~SecondaryCheckDialog();
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
|
||||
wxScrolledWindow *m_vebview_release_note {nullptr};
|
||||
Button* m_button_ok;
|
||||
Button* m_button_cancel;
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
||||
|
|
|
@ -388,6 +388,19 @@ std::string SavePresetDialog::get_name(Preset::Type type)
|
|||
return "";
|
||||
}
|
||||
|
||||
void SavePresetDialog::input_name_from_other(std::string new_preset_name) {
|
||||
//only work for one-item
|
||||
Item* curr_item = m_items[0];
|
||||
curr_item->m_input_ctrl->SetValue(new_preset_name);
|
||||
}
|
||||
|
||||
void SavePresetDialog::confirm_from_other() {
|
||||
for (Item *item : m_items) {
|
||||
item->accept();
|
||||
if (item->type() == Preset::TYPE_PRINTER) update_physical_printers(item->preset_name());
|
||||
}
|
||||
}
|
||||
|
||||
// BBS: add project relate
|
||||
bool SavePresetDialog::get_save_to_project_selection(Preset::Type type)
|
||||
{
|
||||
|
|
|
@ -97,6 +97,8 @@ public:
|
|||
|
||||
std::string get_name();
|
||||
std::string get_name(Preset::Type type);
|
||||
void input_name_from_other(std::string new_preset_name);
|
||||
void confirm_from_other();
|
||||
|
||||
bool enable_ok_btn() const;
|
||||
void add_info_for_edit_ph_printer(wxBoxSizer *sizer);
|
||||
|
|
|
@ -365,8 +365,8 @@ void OptionsSearcher::show_dialog(Preset::Type type, wxWindow *parent, wxTextCtr
|
|||
{
|
||||
if (parent == nullptr || input == nullptr) return;
|
||||
auto search_dialog = new SearchDialog(this, type, parent, input, ssearch_btn);
|
||||
wxPoint pos = parent->ClientToScreen(wxPoint(0, 0));
|
||||
pos.y += parent->GetRect().height;
|
||||
wxPoint pos = input->GetParent()->ClientToScreen(wxPoint(0, 0));
|
||||
pos.y += input->GetParent()->GetRect().height;
|
||||
search_dialog->SetPosition(pos);
|
||||
search_dialog->Popup();
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ void SearchDialog::Dismiss()
|
|||
|
||||
void SearchDialog::Die()
|
||||
{
|
||||
Destroy();
|
||||
wxPopupTransientWindow::Dismiss();
|
||||
wxCommandEvent event(wxCUSTOMEVT_EXIT_SEARCH);
|
||||
wxPostEvent(search_line, event);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "Plater.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
#include "BindDialog.hpp"
|
||||
#include "ConfirmHintDialog.hpp"
|
||||
#include "ReleaseNote.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
@ -38,6 +40,8 @@ wxDEFINE_EVENT(EVT_EDIT_PRINT_NAME, wxCommandEvent);
|
|||
#define LIST_REFRESH_INTERVAL 200
|
||||
#define MACHINE_LIST_REFRESH_INTERVAL 2000
|
||||
|
||||
#define WRAP_GAP FromDIP(10)
|
||||
|
||||
static wxString task_canceled_text = _L("Task canceled");
|
||||
|
||||
|
||||
|
@ -88,6 +92,8 @@ std::string get_print_status_info(PrintDialogStatus status)
|
|||
return "PrintStatusLanModeNoSdcard";
|
||||
case PrintStatusNoSdcard:
|
||||
return "PrintStatusNoSdcard";
|
||||
case PrintStatusTimelapseNoSdcard:
|
||||
return "PrintStatusTimelapseNoSdcard";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
@ -395,13 +401,13 @@ SelectMachinePopup::SelectMachinePopup(wxWindow *parent)
|
|||
m_sizxer_scrolledWindow->Fit(m_scrolledWindow);
|
||||
|
||||
#if !BBL_RELEASE_TO_PUBLIC && defined(__WINDOWS__)
|
||||
m_sizer_search_bar = new wxBoxSizer(wxVERTICAL);
|
||||
m_search_bar = new wxSearchCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_sizer_search_bar = new wxBoxSizer(wxVERTICAL);
|
||||
m_search_bar = new wxSearchCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_search_bar->ShowSearchButton( true );
|
||||
m_search_bar->ShowCancelButton( false );
|
||||
m_sizer_search_bar->Add( m_search_bar, 1, wxALL| wxEXPAND, 1 );
|
||||
m_sizer_main->Add(m_sizer_search_bar, 0, wxALL | wxEXPAND, FromDIP(2));
|
||||
m_search_bar->Bind( wxEVT_COMMAND_TEXT_UPDATED, &SelectMachinePopup::update_machine_list, this );
|
||||
m_sizer_main->Add(m_sizer_search_bar, 0, wxALL | wxEXPAND, FromDIP(2));
|
||||
m_search_bar->Bind( wxEVT_COMMAND_TEXT_UPDATED, &SelectMachinePopup::update_machine_list, this );
|
||||
#endif
|
||||
auto own_title = create_title_panel(_L("My Device"));
|
||||
m_sizer_my_devices = new wxBoxSizer(wxVERTICAL);
|
||||
|
@ -550,6 +556,7 @@ void SelectMachinePopup::update_other_devices()
|
|||
this->Freeze();
|
||||
m_scrolledWindow->Freeze();
|
||||
int i = 0;
|
||||
|
||||
for (auto &elem : m_free_machine_list) {
|
||||
MachineObject * mobj = elem.second;
|
||||
/* do not show printer bind state is empty */
|
||||
|
@ -568,9 +575,9 @@ void SelectMachinePopup::update_other_devices()
|
|||
op = m_other_list_machine_panel[i]->mPanel;
|
||||
op->Show();
|
||||
#if !BBL_RELEASE_TO_PUBLIC && defined(__WINDOWS__)
|
||||
if (!search_for_printer(mobj)) {
|
||||
op->Hide();
|
||||
}
|
||||
if (!search_for_printer(mobj)) {
|
||||
op->Hide();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
op = new MachineObjectPanel(m_scrolledWindow, wxID_ANY);
|
||||
|
@ -626,13 +633,37 @@ void SelectMachinePopup::update_other_devices()
|
|||
m_other_list_machine_panel[j]->mPanel->update_machine_info(nullptr);
|
||||
m_other_list_machine_panel[j]->mPanel->Hide();
|
||||
}
|
||||
m_sizer_other_devices->Layout();
|
||||
|
||||
if (m_placeholder_panel != nullptr) {
|
||||
m_scrolledWindow->RemoveChild(m_placeholder_panel);
|
||||
m_placeholder_panel->Destroy();
|
||||
m_placeholder_panel = nullptr;
|
||||
}
|
||||
|
||||
m_placeholder_panel = new wxWindow(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxSize(-1,FromDIP(26)));
|
||||
wxBoxSizer* placeholder_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto m_hyperlink = new wxHyperlinkCtrl(m_placeholder_panel, wxID_ANY, _L("Can't find my devices?"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
|
||||
placeholder_sizer->Add(m_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
|
||||
m_placeholder_panel->SetSizer(placeholder_sizer);
|
||||
m_placeholder_panel->Layout();
|
||||
placeholder_sizer->Fit(m_placeholder_panel);
|
||||
|
||||
m_placeholder_panel->SetBackgroundColour(*wxWHITE);
|
||||
m_sizer_other_devices->Add(m_placeholder_panel, 0, wxEXPAND, 0);
|
||||
|
||||
//m_sizer_other_devices->Layout();
|
||||
if(m_other_devices_count != i) {
|
||||
m_scrolledWindow->Fit();
|
||||
}
|
||||
m_scrolledWindow->Layout();
|
||||
m_scrolledWindow->Fit();
|
||||
m_scrolledWindow->Thaw();
|
||||
Layout();
|
||||
Fit();
|
||||
this->Thaw();
|
||||
m_scrolledWindow->Thaw();
|
||||
Layout();
|
||||
Fit();
|
||||
this->Thaw();
|
||||
m_other_devices_count = i;
|
||||
BOOST_LOG_TRIVIAL(trace) << "SelectMachinePopup update_other_devices end";
|
||||
}
|
||||
|
||||
|
@ -653,6 +684,7 @@ void SelectMachinePopup::update_user_devices()
|
|||
this->Freeze();
|
||||
m_scrolledWindow->Freeze();
|
||||
int i = 0;
|
||||
|
||||
for (auto& elem : m_bind_machine_list) {
|
||||
MachineObject* mobj = elem.second;
|
||||
MachineObjectPanel* op = nullptr;
|
||||
|
@ -660,9 +692,9 @@ void SelectMachinePopup::update_user_devices()
|
|||
op = m_user_list_machine_panel[i]->mPanel;
|
||||
op->Show();
|
||||
#if !BBL_RELEASE_TO_PUBLIC && defined(__WINDOWS__)
|
||||
if (!search_for_printer(mobj)) {
|
||||
op->Hide();
|
||||
}
|
||||
if (!search_for_printer(mobj)) {
|
||||
op->Hide();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
op = new MachineObjectPanel(m_scrolledWindow, wxID_ANY);
|
||||
|
@ -752,27 +784,31 @@ void SelectMachinePopup::update_user_devices()
|
|||
m_user_list_machine_panel[j]->mPanel->Hide();
|
||||
}
|
||||
//m_sizer_my_devices->Layout();
|
||||
|
||||
if (m_my_devices_count != i) {
|
||||
m_scrolledWindow->Fit();
|
||||
}
|
||||
m_scrolledWindow->Layout();
|
||||
m_scrolledWindow->Fit();
|
||||
m_scrolledWindow->Thaw();
|
||||
Layout();
|
||||
Fit();
|
||||
this->Thaw();
|
||||
Layout();
|
||||
Fit();
|
||||
this->Thaw();
|
||||
m_my_devices_count = i;
|
||||
}
|
||||
|
||||
bool SelectMachinePopup::search_for_printer(MachineObject* obj)
|
||||
{
|
||||
std::string search_text = std::string((m_search_bar->GetValue()).mb_str());
|
||||
if (search_text.empty()) {
|
||||
return true;
|
||||
}
|
||||
auto name = obj->dev_name;
|
||||
auto ip = obj->dev_ip;
|
||||
auto name_it = name.find(search_text);
|
||||
auto ip_it = ip.find(search_text);
|
||||
if ((name_it != std::string::npos)||(ip_it != std::string::npos)) {
|
||||
return true;
|
||||
}
|
||||
std::string search_text = std::string((m_search_bar->GetValue()).mb_str());
|
||||
if (search_text.empty()) {
|
||||
return true;
|
||||
}
|
||||
auto name = obj->dev_name;
|
||||
auto ip = obj->dev_ip;
|
||||
auto name_it = name.find(search_text);
|
||||
auto ip_it = ip.find(search_text);
|
||||
if ((name_it != std::string::npos)||(ip_it != std::string::npos)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -954,7 +990,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
|
|||
|
||||
wxBoxSizer *m_sizer_printer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_stext_printer_title = new wxStaticText(this, wxID_ANY, L("Printer"), wxDefaultPosition, wxSize(-1, -1), 0);
|
||||
m_stext_printer_title = new wxStaticText(this, wxID_ANY, _L("Printer"), wxDefaultPosition, wxSize(-1, -1), 0);
|
||||
m_stext_printer_title->SetFont(::Label::Head_14);
|
||||
m_stext_printer_title->Wrap(-1);
|
||||
m_stext_printer_title->SetForegroundColour(m_colour_bold_color);
|
||||
|
@ -984,17 +1020,21 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
|
|||
m_statictext_printer_msg->SetFont(::Label::Body_13);
|
||||
m_statictext_printer_msg->Hide();
|
||||
|
||||
m_sizer_select = new wxGridSizer(0, 2, 0, 0);
|
||||
//m_sizer_select = new wxGridSizer(0, 2, 0, 0);
|
||||
m_sizer_select = new wxWrapSizer();
|
||||
select_bed = create_item_checkbox(_L("Bed Leveling"), this, _L("Bed Leveling"), "bed_leveling");
|
||||
select_flow = create_item_checkbox(_L("Flow Calibration"), this, _L("Flow Calibration"), "flow_cali");
|
||||
select_timelapse = create_item_checkbox(_L("Timelapse"), this, _L("Timelapse"), "timelapse");
|
||||
select_use_ams = create_ams_checkbox(_L("Enable AMS"), this, _L("Enable AMS"));
|
||||
|
||||
m_sizer_select->Add(select_bed);
|
||||
m_sizer_select->Add(select_flow);
|
||||
m_sizer_select->Add(select_use_ams);
|
||||
m_sizer_select->Add(select_bed, 0, wxLEFT | wxRIGHT, WRAP_GAP);
|
||||
m_sizer_select->Add(select_flow, 0, wxLEFT | wxRIGHT, WRAP_GAP);
|
||||
m_sizer_select->Add(select_timelapse, 0, wxLEFT | wxRIGHT, WRAP_GAP);
|
||||
m_sizer_select->Add(select_use_ams, 0, wxLEFT | wxRIGHT, WRAP_GAP);
|
||||
|
||||
select_bed->Show(true);
|
||||
select_flow->Show(true);
|
||||
select_timelapse->Show(false);
|
||||
select_use_ams->Show(true);
|
||||
|
||||
// line schedule
|
||||
|
@ -1007,11 +1047,23 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
|
|||
// perpare mode
|
||||
m_panel_prepare = new wxPanel(m_simplebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
m_panel_prepare->SetBackgroundColour(m_colour_def_color);
|
||||
// m_panel_prepare->SetBackgroundColour(wxColour(135,206,250));
|
||||
//m_panel_prepare->SetBackgroundColour(wxColour(135,206,250));
|
||||
wxBoxSizer *m_sizer_prepare = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *m_sizer_pcont = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_sizer_prepare->Add(0, 0, 1, wxTOP, FromDIP(22));
|
||||
m_sizer_prepare->Add(0, 0, 1, wxTOP, FromDIP(12));
|
||||
|
||||
auto hyperlink_sizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
auto m_hyperlink = new wxHyperlinkCtrl(m_panel_prepare, wxID_ANY, _L("Can't find my devices?"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
|
||||
|
||||
//auto linkimg = new wxStaticBitmap(m_panel_prepare, wxID_ANY, create_scaled_bitmap("link_wiki_img", this, 18), wxDefaultPosition, wxSize(FromDIP(18), FromDIP(18)), 0);
|
||||
|
||||
hyperlink_sizer->Add(m_hyperlink, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
//hyperlink_sizer->Add(linkimg, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
|
||||
m_sizer_prepare->Add(hyperlink_sizer, 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
|
||||
m_sizer_pcont->Add(0, 0, 1, wxEXPAND, 0);
|
||||
m_button_ensure = new Button(m_panel_prepare, _L("Send"));
|
||||
m_button_ensure->SetBackgroundColor(btn_bg_enable);
|
||||
|
@ -1021,7 +1073,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
|
|||
m_button_ensure->SetMinSize(SELECT_MACHINE_DIALOG_BUTTON_SIZE);
|
||||
m_button_ensure->SetCornerRadius(FromDIP(12));
|
||||
|
||||
m_button_ensure->Bind(wxEVT_BUTTON, &SelectMachineDialog::on_ok, this);
|
||||
m_button_ensure->Bind(wxEVT_BUTTON, &SelectMachineDialog::on_ok_btn, this);
|
||||
m_sizer_pcont->Add(m_button_ensure, 0, wxEXPAND | wxBOTTOM, FromDIP(10));
|
||||
m_sizer_prepare->Add(m_sizer_pcont, 0, wxEXPAND, 0);
|
||||
m_panel_prepare->SetSizer(m_sizer_prepare);
|
||||
|
@ -1131,23 +1183,23 @@ wxWindow *SelectMachineDialog::create_ams_checkbox(wxString title, wxWindow *par
|
|||
auto img_ams_tip = new wxStaticBitmap(checkbox, wxID_ANY, create_scaled_bitmap("enable_ams", this, 16), wxDefaultPosition, wxSize(FromDIP(16), FromDIP(16)), 0);
|
||||
sizer_checkbox->Add(img_ams_tip, 0, wxALIGN_CENTER | wxLEFT, FromDIP(5));
|
||||
|
||||
img_ams_tip->Bind(wxEVT_ENTER_WINDOW, [this, img_ams_tip](auto &e) {
|
||||
wxPoint pos = img_ams_tip->ClientToScreen(wxPoint(0, 0));
|
||||
pos.y += img_ams_tip->GetRect().height;
|
||||
m_mapping_tip_popup.Position(pos, wxSize(0,0));
|
||||
img_ams_tip->Bind(wxEVT_ENTER_WINDOW, [this, img_ams_tip](auto& e) {
|
||||
wxPoint img_pos = img_ams_tip->ClientToScreen(wxPoint(0, 0));
|
||||
wxPoint popup_pos(img_pos.x, img_pos.y + img_ams_tip->GetRect().height);
|
||||
m_mapping_tip_popup.Position(popup_pos, wxSize(0, 0));
|
||||
m_mapping_tip_popup.Popup();
|
||||
});
|
||||
img_ams_tip->Bind(wxEVT_LEAVE_WINDOW, [this, img_ams_tip](wxMouseEvent &e) {
|
||||
auto region = m_mapping_tip_popup.GetClientRect();
|
||||
|
||||
if(e.GetPosition().x > region.GetLeftTop().x && e.GetPosition().y > region.GetLeftTop().y && e.GetPosition().x < region.GetRightBottom().x && e.GetPosition().x < region.GetRightBottom().y)
|
||||
;
|
||||
else
|
||||
if (m_mapping_tip_popup.ClientToScreen(wxPoint(0, 0)).y < img_pos.y) {
|
||||
m_mapping_tip_popup.Dismiss();
|
||||
popup_pos = wxPoint(img_pos.x, img_pos.y - m_mapping_tip_popup.GetRect().height);
|
||||
m_mapping_tip_popup.Position(popup_pos, wxSize(0, 0));
|
||||
m_mapping_tip_popup.Popup();
|
||||
}
|
||||
});
|
||||
m_mapping_tip_popup.Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {
|
||||
m_mapping_tip_popup.Dismiss();
|
||||
});
|
||||
|
||||
img_ams_tip->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) {
|
||||
m_mapping_tip_popup.Dismiss();
|
||||
});
|
||||
|
||||
checkbox->SetSizer(sizer_checkbox);
|
||||
checkbox->Layout();
|
||||
|
@ -1177,10 +1229,12 @@ wxWindow *SelectMachineDialog::create_item_checkbox(wxString title, wxWindow *pa
|
|||
sizer_checkbox->Add(sizer_check, 0, wxEXPAND, FromDIP(5));
|
||||
sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(11));
|
||||
|
||||
auto text = new wxStaticText(checkbox, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, 0);
|
||||
auto text = new wxStaticText(checkbox, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
|
||||
text->SetFont(::Label::Body_13);
|
||||
text->SetForegroundColour(wxColour(107, 107, 107));
|
||||
text->Wrap(-1);
|
||||
text->SetMinSize(wxSize(FromDIP(120), -1));
|
||||
text->SetMaxSize(wxSize(FromDIP(120), -1));
|
||||
sizer_checkbox->Add(text, 0, wxBOTTOM | wxEXPAND | wxTOP, FromDIP(5));
|
||||
|
||||
checkbox->SetSizer(sizer_checkbox);
|
||||
|
@ -1209,6 +1263,13 @@ void SelectMachineDialog::update_select_layout(MachineObject *obj)
|
|||
select_bed->Hide();
|
||||
}
|
||||
|
||||
if (obj && obj->is_function_supported(PrinterFunction::FUNC_TIMELAPSE)
|
||||
&& obj->is_support_print_with_timelapse()) {
|
||||
//always hide timelapse
|
||||
select_timelapse->Hide();
|
||||
} else {
|
||||
select_timelapse->Hide();
|
||||
}
|
||||
Fit();
|
||||
}
|
||||
|
||||
|
@ -1319,7 +1380,8 @@ bool SelectMachineDialog::do_ams_mapping(MachineObject *obj_)
|
|||
if (result == 0) {
|
||||
print_ams_mapping_result(m_ams_mapping_result);
|
||||
std::string ams_array;
|
||||
get_ams_mapping_result(ams_array);
|
||||
std::string mapping_info;
|
||||
get_ams_mapping_result(ams_array, mapping_info);
|
||||
if (ams_array.empty()) {
|
||||
reset_ams_material();
|
||||
BOOST_LOG_TRIVIAL(info) << "ams_mapping_array=[]";
|
||||
|
@ -1345,7 +1407,7 @@ bool SelectMachineDialog::do_ams_mapping(MachineObject *obj_)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SelectMachineDialog::get_ams_mapping_result(std::string &mapping_array_str)
|
||||
bool SelectMachineDialog::get_ams_mapping_result(std::string &mapping_array_str, std::string &ams_mapping_info)
|
||||
{
|
||||
if (m_ams_mapping_result.empty())
|
||||
return false;
|
||||
|
@ -1363,16 +1425,39 @@ bool SelectMachineDialog::get_ams_mapping_result(std::string &mapping_array_str)
|
|||
return false;
|
||||
} else {
|
||||
json j = json::array();
|
||||
json mapping_info_json = json::array();
|
||||
|
||||
for (int i = 0; i < wxGetApp().preset_bundle->filament_presets.size(); i++) {
|
||||
int tray_id = -1;
|
||||
json mapping_item;
|
||||
mapping_item["ams"] = tray_id;
|
||||
mapping_item["targetColor"] = "";
|
||||
mapping_item["filamentId"] = "";
|
||||
mapping_item["filamentType"] = "";
|
||||
|
||||
for (int k = 0; k < m_ams_mapping_result.size(); k++) {
|
||||
if (m_ams_mapping_result[k].id == i) {
|
||||
tray_id = m_ams_mapping_result[k].tray_id;
|
||||
mapping_item["ams"] = tray_id;
|
||||
mapping_item["filamentType"] = m_filaments[k].type;
|
||||
auto it = wxGetApp().preset_bundle->filaments.find_preset(wxGetApp().preset_bundle->filament_presets[i]);
|
||||
if (it != nullptr) {
|
||||
mapping_item["filamentId"] = it->filament_id;
|
||||
}
|
||||
//convert #RRGGBB to RRGGBBAA
|
||||
if (m_filaments[k].color.size() > 6) {
|
||||
mapping_item["sourceColor"] = m_filaments[k].color.substr(1, 6) + "FF";
|
||||
} else {
|
||||
mapping_item["sourceColor"] = m_filaments[k].color;
|
||||
}
|
||||
mapping_item["targetColor"] = m_ams_mapping_result[k].color;
|
||||
}
|
||||
}
|
||||
j.push_back(tray_id);
|
||||
mapping_info_json.push_back(mapping_item);
|
||||
}
|
||||
mapping_array_str = j.dump();
|
||||
ams_mapping_info = mapping_info_json.dump();
|
||||
return valid_mapping_result;
|
||||
}
|
||||
return true;
|
||||
|
@ -1464,6 +1549,22 @@ void SelectMachineDialog::update_print_status_msg(wxString msg, bool is_warning,
|
|||
}
|
||||
}
|
||||
|
||||
bool SelectMachineDialog::has_tips(MachineObject* obj)
|
||||
{
|
||||
if (!obj) return false;
|
||||
|
||||
// must set to a status if return true
|
||||
if (select_timelapse->IsShown() &&
|
||||
m_checkbox_list["timelapse"]->GetValue()) {
|
||||
if (!obj->has_sdcard()) {
|
||||
show_status(PrintDialogStatus::PrintStatusTimelapseNoSdcard);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxString> params)
|
||||
{
|
||||
if (m_print_status != status)
|
||||
|
@ -1564,7 +1665,8 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxSt
|
|||
Enable_Send_Button(false);
|
||||
Enable_Refresh_Button(true);
|
||||
} else if (status == PrintDialogStatus::PrintStatusAmsMappingValid) {
|
||||
update_print_status_msg(wxEmptyString, false, false);
|
||||
wxString msg_text = _L("Filaments to AMS slots mappings have been established. You can click a filament above to change its mapping AMS slot");
|
||||
update_print_status_msg(msg_text, false, false);
|
||||
Enable_Send_Button(true);
|
||||
Enable_Refresh_Button(true);
|
||||
} else if (status == PrintDialogStatus::PrintStatusRefreshingMachineList) {
|
||||
|
@ -1592,6 +1694,11 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxSt
|
|||
update_print_status_msg(msg_text, true, true);
|
||||
Enable_Send_Button(true);
|
||||
Enable_Refresh_Button(true);
|
||||
} else if (status == PrintDialogStatus::PrintStatusTimelapseNoSdcard) {
|
||||
wxString msg_text = _L("An SD card needs to be inserted to recording timelapse");
|
||||
update_print_status_msg(msg_text, true, true);
|
||||
Enable_Send_Button(true);
|
||||
Enable_Refresh_Button(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1638,7 +1745,71 @@ void SelectMachineDialog::on_cancel(wxCloseEvent &event)
|
|||
this->EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
void SelectMachineDialog::on_ok(wxCommandEvent &event)
|
||||
bool SelectMachineDialog::is_same_printer_model()
|
||||
{
|
||||
bool result = true;
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return result;
|
||||
|
||||
MachineObject* obj_ = dev->get_selected_machine();
|
||||
assert(obj_->dev_id == m_printer_last_select);
|
||||
if (obj_ == nullptr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
if (preset_bundle && preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle) != obj_->printer_type) {
|
||||
BOOST_LOG_TRIVIAL(info) << "printer_model: source = " << preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
BOOST_LOG_TRIVIAL(info) << "printer_model: target = " << obj_->printer_type;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SelectMachineDialog::on_ok_btn(wxCommandEvent &event)
|
||||
{
|
||||
wxString confirm_text = _L("Please check the following infomation:\n");
|
||||
|
||||
//Check Printer Model Id
|
||||
bool is_same_printer_type = is_same_printer_model();
|
||||
if (!is_same_printer_type)
|
||||
confirm_text += _L("The printer type used to generate G-code is not the same type as the currently selected physical printer. It is recommend to re-slice by selecting the same printer type.\n");
|
||||
|
||||
//Check slice warnings
|
||||
bool has_slice_warnings = false;
|
||||
PartPlate* plate = m_plater->get_partplate_list().get_curr_plate();
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (dev) {
|
||||
MachineObject* obj_ = dev->get_selected_machine();
|
||||
for (auto warning : plate->get_slice_result()->warnings) {
|
||||
if (warning.msg == BED_TEMP_TOO_HIGH_THAN_FILAMENT) {
|
||||
if ((obj_->printer_type == "BL-P001" || obj_->printer_type == "BL-P002")) {
|
||||
confirm_text += Plater::get_slice_warning_string(warning) + "\n";
|
||||
has_slice_warnings = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
has_slice_warnings = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_same_printer_type
|
||||
|| has_slice_warnings
|
||||
) {
|
||||
wxString confirm_title = _L("Confirm");
|
||||
SecondaryCheckDialog confirm_dlg(this);
|
||||
confirm_dlg.update_text(confirm_text);
|
||||
if (confirm_dlg.ShowModal() == wxID_YES) {
|
||||
this->on_ok();
|
||||
}
|
||||
} else {
|
||||
this->on_ok();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectMachineDialog::on_ok()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "print_job: on_ok to send";
|
||||
m_is_canceled = false;
|
||||
|
@ -1690,7 +1861,8 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event)
|
|||
|
||||
// get ams_mapping_result
|
||||
std::string ams_mapping_array;
|
||||
get_ams_mapping_result(ams_mapping_array);
|
||||
std::string ams_mapping_info;
|
||||
get_ams_mapping_result(ams_mapping_array, ams_mapping_info);
|
||||
|
||||
result = m_plater->send_gcode(m_print_plate_idx, [this](int export_stage, int current, int total, bool &cancel) {
|
||||
if (this->m_is_canceled) return;
|
||||
|
@ -1730,10 +1902,13 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event)
|
|||
m_print_job->m_dev_ip = obj_->dev_ip;
|
||||
m_print_job->m_access_code = obj_->access_code;
|
||||
m_print_job->connection_type = obj_->connection_type();
|
||||
if (obj_->is_support_ams_mapping())
|
||||
if (obj_->is_support_ams_mapping()) {
|
||||
m_print_job->task_ams_mapping = ams_mapping_array;
|
||||
else
|
||||
m_print_job->task_ams_mapping_info = ams_mapping_info;
|
||||
} else {
|
||||
m_print_job->task_ams_mapping = "";
|
||||
m_print_job->task_ams_mapping_info = "";
|
||||
}
|
||||
|
||||
m_print_job->has_sdcard = obj_->has_sdcard();
|
||||
|
||||
|
@ -1741,13 +1916,16 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event)
|
|||
m_print_job->cloud_print_only = true;
|
||||
}
|
||||
|
||||
|
||||
bool timelapse_option = select_timelapse->IsShown() ? m_checkbox_list["timelapse"]->GetValue() : true;
|
||||
|
||||
m_print_job->set_print_config(
|
||||
MachineBedTypeString[0],
|
||||
m_checkbox_list["bed_leveling"]->GetValue(),
|
||||
m_checkbox_list["flow_cali"]->GetValue(),
|
||||
false,
|
||||
false,
|
||||
true);
|
||||
timelapse_option);
|
||||
|
||||
if (obj_->has_ams()) {
|
||||
m_print_job->task_use_ams = ams_check->GetValue();
|
||||
|
@ -1755,6 +1933,7 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event)
|
|||
m_print_job->task_use_ams = false;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "print_job: timelapse_option = " << timelapse_option;
|
||||
BOOST_LOG_TRIVIAL(info) << "print_job: use_ams = " << m_print_job->task_use_ams;
|
||||
|
||||
m_print_job->on_success([this]() { finish_mode(); });
|
||||
|
@ -1809,6 +1988,9 @@ void SelectMachineDialog::on_set_finish_mapping(wxCommandEvent &evt)
|
|||
for (auto i = 0; i < m_ams_mapping_result.size(); i++) {
|
||||
if (m_ams_mapping_result[i].id == wxAtoi(selection_data_arr[4])) {
|
||||
m_ams_mapping_result[i].tray_id = evt.GetInt();
|
||||
auto ams_colour = wxColour(wxAtoi(selection_data_arr[0]), wxAtoi(selection_data_arr[1]), wxAtoi(selection_data_arr[2]));
|
||||
auto color = wxString::Format("%sFF", ams_colour.GetAsString(wxC2S_HTML_SYNTAX).substr(1, ams_colour.GetAsString(wxC2S_HTML_SYNTAX).size()-1));
|
||||
m_ams_mapping_result[i].color = color.ToStdString();
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(trace) << "The ams mapping result: id is " << m_ams_mapping_result[i].id << "tray_id is " << m_ams_mapping_result[i].tray_id;
|
||||
}
|
||||
|
@ -1973,6 +2155,8 @@ void SelectMachineDialog::on_selection_changed(wxCommandEvent &event)
|
|||
obj->command_get_version();
|
||||
obj->command_request_push_all();
|
||||
dev->set_selected_machine(m_printer_last_select);
|
||||
// Has changed machine unrecoverably
|
||||
GUI::wxGetApp().sidebar().load_ams_list(obj->amsList);
|
||||
update_select_layout(obj);
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(error) << "on_selection_changed dev_id not found";
|
||||
|
@ -2007,10 +2191,14 @@ void SelectMachineDialog::update_show_status()
|
|||
|
||||
NetworkAgent* agent = Slic3r::GUI::wxGetApp().getAgent();
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!agent) return;
|
||||
if (!agent) {
|
||||
update_ams_check(nullptr);
|
||||
return;
|
||||
}
|
||||
if (!dev) return;
|
||||
MachineObject* obj_ = dev->get_my_machine(m_printer_last_select);
|
||||
if (!obj_) {
|
||||
update_ams_check(nullptr);
|
||||
if (agent) {
|
||||
if (agent->is_user_login()) {
|
||||
show_status(PrintDialogStatus::PrintStatusInvalidPrinter);
|
||||
|
@ -2075,13 +2263,11 @@ void SelectMachineDialog::update_show_status()
|
|||
show_status(PrintDialogStatus::PrintStatusInPrinting);
|
||||
return;
|
||||
}
|
||||
else if (!obj_->is_function_supported(PrinterFunction::FUNC_PRINT_WITHOUT_SD)) {
|
||||
else if (!obj_->is_function_supported(PrinterFunction::FUNC_PRINT_WITHOUT_SD) && !obj_->has_sdcard()) {
|
||||
show_status(PrintDialogStatus::PrintStatusNoSdcard);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// check sdcard when if lan mode printer
|
||||
if (obj_->is_lan_mode_printer()) {
|
||||
if (!obj_->has_sdcard()) {
|
||||
|
@ -2092,7 +2278,8 @@ void SelectMachineDialog::update_show_status()
|
|||
|
||||
// no ams
|
||||
if (!obj_->has_ams()) {
|
||||
show_status(PrintDialogStatus::PrintStatusReadingFinished);
|
||||
if (!has_tips(obj_))
|
||||
show_status(PrintDialogStatus::PrintStatusReadingFinished);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2144,10 +2331,13 @@ void SelectMachineDialog::update_show_status()
|
|||
}
|
||||
else {
|
||||
if (obj_->is_valid_mapping_result(m_ams_mapping_result)) {
|
||||
show_status(PrintDialogStatus::PrintStatusAmsMappingValid);
|
||||
if (!has_tips(obj_))
|
||||
show_status(PrintDialogStatus::PrintStatusAmsMappingValid);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
show_status(PrintDialogStatus::PrintStatusAmsMappingInvalid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2250,6 +2440,7 @@ void SelectMachineDialog::set_default()
|
|||
// checkbox default values
|
||||
m_checkbox_list["bed_leveling"]->SetValue(true);
|
||||
m_checkbox_list["flow_cali"]->SetValue(true);
|
||||
m_checkbox_list["timelapse"]->SetValue(true);
|
||||
ams_check->SetValue(true);
|
||||
|
||||
// thumbmail
|
||||
|
|
|
@ -195,6 +195,9 @@ public:
|
|||
bool was_dismiss() { return m_dismiss; }
|
||||
|
||||
private:
|
||||
int m_my_devices_count{0};
|
||||
int m_other_devices_count{0};
|
||||
wxWindow* m_placeholder_panel{nullptr};
|
||||
wxBoxSizer * m_sizer_body{nullptr};
|
||||
wxBoxSizer * m_sizer_my_devices{nullptr};
|
||||
wxBoxSizer * m_sizer_other_devices{nullptr};
|
||||
|
@ -249,7 +252,9 @@ enum PrintDialogStatus {
|
|||
PrintStatusSending,
|
||||
PrintStatusSendingCanceled,
|
||||
PrintStatusLanModeNoSdcard,
|
||||
PrintStatusNoSdcard
|
||||
PrintStatusNoSdcard,
|
||||
PrintStatusTimelapseNoSdcard,
|
||||
PrintStatusNotOnTheSameLAN
|
||||
};
|
||||
|
||||
std::string get_print_status_info(PrintDialogStatus status);
|
||||
|
@ -308,7 +313,8 @@ protected:
|
|||
int m_current_filament_id;
|
||||
bool m_is_in_sending_mode { false };
|
||||
|
||||
wxGridSizer *m_sizer_select;
|
||||
//wxGridSizer *m_sizer_select;
|
||||
wxWrapSizer *m_sizer_select;
|
||||
wxBoxSizer * sizer_thumbnail;
|
||||
wxGridSizer *m_sizer_material;
|
||||
wxBoxSizer * m_sizer_main;
|
||||
|
@ -323,6 +329,7 @@ protected:
|
|||
|
||||
wxWindow *select_bed{nullptr};
|
||||
wxWindow *select_flow{nullptr};
|
||||
wxWindow *select_timelapse { nullptr };
|
||||
wxWindow *select_use_ams{nullptr};
|
||||
CheckBox *ams_check{nullptr};
|
||||
|
||||
|
@ -346,11 +353,14 @@ public:
|
|||
|
||||
void sync_ams_mapping_result(std::vector<FilamentInfo>& result);
|
||||
bool do_ams_mapping(MachineObject *obj_);
|
||||
bool get_ams_mapping_result(std::string &mapping_array_str);
|
||||
bool get_ams_mapping_result(std::string &mapping_array_str, std::string &ams_mapping_info);
|
||||
void prepare(int print_plate_idx);
|
||||
bool has_tips(MachineObject* obj);
|
||||
void show_status(PrintDialogStatus status, std::vector<wxString> params = std::vector<wxString>());
|
||||
PrintDialogStatus get_status() { return m_print_status; }
|
||||
|
||||
bool is_same_printer_model();
|
||||
|
||||
bool Show(bool show);
|
||||
|
||||
/* model */
|
||||
|
@ -386,7 +396,8 @@ protected:
|
|||
// Virtual event handlers, overide them in your derived class
|
||||
void update_printer_combobox(wxCommandEvent &event);
|
||||
void on_cancel(wxCloseEvent &event);
|
||||
void on_ok(wxCommandEvent &event);
|
||||
void on_ok_btn(wxCommandEvent &event);
|
||||
void on_ok();
|
||||
void on_refresh(wxCommandEvent &event);
|
||||
void on_set_finish_mapping(wxCommandEvent &evt);
|
||||
void on_print_job_cancel(wxCommandEvent &evt);
|
||||
|
|
|
@ -1105,6 +1105,12 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
|
|||
else
|
||||
v.set_instance_scaling_factor(scale);
|
||||
}
|
||||
|
||||
// update the instance assemble transform
|
||||
ModelObject* object = m_model->objects[v.object_idx()];
|
||||
Geometry::Transformation assemble_transform = object->instances[v.instance_idx()]->get_assemble_transformation();
|
||||
assemble_transform.set_scaling_factor(v.get_instance_scaling_factor());
|
||||
object->instances[v.instance_idx()]->set_assemble_transformation(assemble_transform);
|
||||
}
|
||||
else if (is_single_volume() || is_single_modifier())
|
||||
v.set_volume_scaling_factor(scale);
|
||||
|
|
1009
src/slic3r/GUI/SendToPrinter.cpp
Normal file
1009
src/slic3r/GUI/SendToPrinter.cpp
Normal file
File diff suppressed because it is too large
Load diff
162
src/slic3r/GUI/SendToPrinter.hpp
Normal file
162
src/slic3r/GUI/SendToPrinter.hpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
#ifndef slic3r_GUI_SendToSDcard_hpp_
|
||||
#define slic3r_GUI_SendToSDcard_hpp_
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/collpane.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/hyperlink.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/popupwin.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/wrapsizer.h>
|
||||
#include <wx/srchctrl.h>
|
||||
|
||||
#include "SelectMachine.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "DeviceManager.hpp"
|
||||
#include "Plater.hpp"
|
||||
#include "BBLStatusBar.hpp"
|
||||
#include "BBLStatusBarSend.hpp"
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "Widgets/CheckBox.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
#include "Widgets/ScrolledWindow.hpp"
|
||||
#include <wx/simplebook.h>
|
||||
#include <wx/hashmap.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class SendToPrinterDialog : public DPIDialog
|
||||
{
|
||||
private:
|
||||
void init_model();
|
||||
void init_bind();
|
||||
void init_timer();
|
||||
|
||||
int m_print_plate_idx;
|
||||
PrintDialogStatus m_print_status { PrintStatusInit };
|
||||
|
||||
std::string m_printer_last_select;
|
||||
std::vector<wxString> m_bedtype_list;
|
||||
std::map<std::string, ::CheckBox*> m_checkbox_list;
|
||||
|
||||
wxColour m_colour_def_color{ wxColour(255, 255, 255) };
|
||||
wxColour m_colour_bold_color{ wxColour(38, 46, 48) };
|
||||
|
||||
protected:
|
||||
Plater* m_plater{ nullptr };
|
||||
wxPanel* m_line_top{ nullptr };
|
||||
wxPanel* m_panel_image{ nullptr };
|
||||
wxStaticText* m_stext_time{ nullptr };
|
||||
wxStaticText* m_stext_weight{ nullptr };
|
||||
wxPanel* m_line_materia{ nullptr };
|
||||
wxStaticText* m_stext_printer_title{ nullptr };
|
||||
|
||||
wxStaticText* m_statictext_printer_msg{ nullptr };
|
||||
wxStaticBitmap* m_staticbitmap{ nullptr };
|
||||
ThumbnailPanel* m_thumbnailPanel{ nullptr };
|
||||
|
||||
::ComboBox* m_comboBox_printer{ nullptr };
|
||||
::ComboBox* m_comboBox_bed{ nullptr };
|
||||
wxStaticText* m_staticText_bed_title{ nullptr };
|
||||
wxPanel* m_line_schedule{ nullptr };
|
||||
wxPanel* m_panel_sending{ nullptr };
|
||||
wxStaticText* m_stext_sending{ nullptr };
|
||||
wxPanel* m_panel_prepare{ nullptr };
|
||||
Button* m_button_refresh{ nullptr };
|
||||
Button* m_button_ensure{ nullptr };
|
||||
wxPanel* m_panel_finish{ nullptr };
|
||||
wxSimplebook* m_simplebook{ nullptr };
|
||||
wxStaticText* m_statictext_finish{ nullptr };
|
||||
|
||||
StateColor btn_bg_enable;
|
||||
int m_current_filament_id;
|
||||
bool m_is_in_sending_mode{ false };
|
||||
|
||||
wxBoxSizer* sizer_thumbnail;
|
||||
wxBoxSizer* m_sizer_main;
|
||||
wxBoxSizer* m_sizer_bottom;
|
||||
|
||||
bool enable_prepare_mode{true};
|
||||
bool m_need_adaptation_screen{ false };
|
||||
wxPanel* m_scrollable_region;
|
||||
wxBoxSizer* m_sizer_scrollable_region;
|
||||
|
||||
|
||||
void stripWhiteSpace(std::string& str);
|
||||
wxString format_text(wxString& m_msg);
|
||||
void update_priner_status_msg(wxString msg, bool is_warning = false);
|
||||
void update_print_status_msg(wxString msg, bool is_warning = false, bool is_printer = true);
|
||||
|
||||
public:
|
||||
SendToPrinterDialog(Plater* plater = nullptr);
|
||||
~SendToPrinterDialog();
|
||||
|
||||
void prepare_mode();
|
||||
void sending_mode();
|
||||
void prepare(int print_plate_idx);
|
||||
bool Show(bool show);
|
||||
|
||||
/* model */
|
||||
wxObjectDataPtr<MachineListModel> machine_model;
|
||||
std::shared_ptr<BBLStatusBarSend> m_status_bar;
|
||||
bool m_export_3mf_cancel{ false };
|
||||
bool m_is_canceled{ false };
|
||||
|
||||
protected:
|
||||
std::vector<MachineObject*> m_list;
|
||||
wxDataViewCtrl* m_dataViewListCtrl_machines{ nullptr };
|
||||
wxStaticText* m_staticText_left{ nullptr };
|
||||
wxHyperlinkCtrl* m_hyperlink_add_machine{ nullptr };
|
||||
wxGauge* m_gauge_job_progress{ nullptr };
|
||||
wxPanel* m_panel_status{ nullptr };
|
||||
wxButton* m_button_cancel{ nullptr };
|
||||
|
||||
std::string m_print_info;
|
||||
int timeout_count = 0;
|
||||
bool is_timeout();
|
||||
void reset_timeout();
|
||||
void update_user_printer();
|
||||
void update_show_status();
|
||||
|
||||
wxTimer* m_refresh_timer{ nullptr };
|
||||
|
||||
std::shared_ptr<SendJob> m_send_job{nullptr};
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
void update_printer_combobox(wxCommandEvent& event);
|
||||
void on_cancel(wxCloseEvent& event);
|
||||
void on_ok(wxCommandEvent& event);
|
||||
void on_refresh(wxCommandEvent& event);
|
||||
void on_print_job_cancel(wxCommandEvent& evt);
|
||||
void set_default();
|
||||
void on_timer(wxTimerEvent& event);
|
||||
void on_selection_changed(wxCommandEvent& event);
|
||||
void Enable_Refresh_Button(bool en);
|
||||
void show_status(PrintDialogStatus status, std::vector<wxString> params = std::vector<wxString>());
|
||||
void Enable_Send_Button(bool en);
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
void update_user_machine_list();
|
||||
std::vector<std::string> sort_string(std::vector<std::string> strArray);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -177,6 +177,7 @@ void StatusBasePanel::init_bitmaps()
|
|||
m_thumbnail_sdcard = ScalableBitmap(this, "monitor_sdcard_thumbnail", 120);
|
||||
//m_bitmap_camera = create_scaled_bitmap("monitor_camera", nullptr, 18);
|
||||
m_bitmap_extruder = *cache.load_png("monitor_extruder", FromDIP(28), FromDIP(70), false, false);
|
||||
m_bitmap_extruder_load = *cache.load_png("monitor_extruder_load", FromDIP(28), FromDIP(70), false, false);
|
||||
m_bitmap_sdcard_state_on = create_scaled_bitmap("sdcard_state_on", nullptr, 20);
|
||||
m_bitmap_sdcard_state_off = create_scaled_bitmap("sdcard_state_off", nullptr, 20);
|
||||
}
|
||||
|
@ -741,7 +742,7 @@ wxBoxSizer *StatusBasePanel::create_misc_control(wxWindow *parent)
|
|||
m_switch_nozzle_fan->SetLabels(_L("Part Cooling"), _L("Part Cooling"));
|
||||
m_switch_nozzle_fan->SetPadding(FromDIP(3));
|
||||
m_switch_nozzle_fan->SetBorderWidth(FromDIP(2));
|
||||
m_switch_nozzle_fan->SetFont(SWITCH_FONT);
|
||||
m_switch_nozzle_fan->SetFont(::Label::Body_10);
|
||||
m_switch_nozzle_fan->SetTextColor(StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_FAN_TEXT_COL, (int) StateColor::Normal)));
|
||||
|
||||
line_sizer->Add(m_switch_nozzle_fan, 1, wxALIGN_CENTER | wxALL, 0);
|
||||
|
@ -754,7 +755,7 @@ wxBoxSizer *StatusBasePanel::create_misc_control(wxWindow *parent)
|
|||
m_switch_printing_fan->SetMinSize(MISC_BUTTON_SIZE);
|
||||
m_switch_printing_fan->SetPadding(FromDIP(3));
|
||||
m_switch_printing_fan->SetBorderWidth(FromDIP(2));
|
||||
m_switch_printing_fan->SetFont(SWITCH_FONT);
|
||||
m_switch_printing_fan->SetFont(::Label::Body_10);
|
||||
m_switch_printing_fan->SetLabels(_L("Aux Cooling"), _L("Aux Cooling"));
|
||||
m_switch_printing_fan->SetTextColor(
|
||||
StateColor(std::make_pair(DISCONNECT_TEXT_COL, (int) StateColor::Disabled), std::make_pair(NORMAL_FAN_TEXT_COL, (int) StateColor::Normal)));
|
||||
|
@ -770,11 +771,11 @@ void StatusBasePanel::reset_temp_misc_control()
|
|||
{
|
||||
// reset temp string
|
||||
m_tempCtrl_nozzle->SetLabel(TEMP_BLANK_STR);
|
||||
m_tempCtrl_nozzle->GetTextCtrl()->SetLabel(TEMP_BLANK_STR);
|
||||
m_tempCtrl_nozzle->GetTextCtrl()->SetValue(TEMP_BLANK_STR);
|
||||
m_tempCtrl_bed->SetLabel(TEMP_BLANK_STR);
|
||||
m_tempCtrl_bed->GetTextCtrl()->SetLabel(TEMP_BLANK_STR);
|
||||
m_tempCtrl_bed->GetTextCtrl()->SetValue(TEMP_BLANK_STR);
|
||||
m_tempCtrl_frame->SetLabel(TEMP_BLANK_STR);
|
||||
m_tempCtrl_frame->GetTextCtrl()->SetLabel(TEMP_BLANK_STR);
|
||||
m_tempCtrl_frame->GetTextCtrl()->SetValue(TEMP_BLANK_STR);
|
||||
m_button_unload->Show();
|
||||
|
||||
m_tempCtrl_nozzle->Enable(true);
|
||||
|
@ -1103,6 +1104,8 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
|
|||
Bind(EVT_AMS_REFRESH_RFID, &StatusPanel::on_ams_refresh_rfid, this);
|
||||
Bind(EVT_AMS_ON_SELECTED, &StatusPanel::on_ams_selected, this);
|
||||
Bind(EVT_AMS_ON_FILAMENT_EDIT, &StatusPanel::on_filament_edit, this);
|
||||
Bind(EVT_AMS_GUIDE_WIKI, &StatusPanel::on_ams_guide, this);
|
||||
Bind(EVT_AMS_RETRY, &StatusPanel::on_ams_retry, this);
|
||||
|
||||
m_switch_speed->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(StatusPanel::on_switch_speed), NULL, this);
|
||||
m_calibration_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_calibration), NULL, this);
|
||||
|
@ -1305,6 +1308,13 @@ void StatusPanel::update(MachineObject *obj)
|
|||
update_temp_ctrl(obj);
|
||||
update_misc_ctrl(obj);
|
||||
|
||||
if (obj && obj->is_filament_at_extruder()) {
|
||||
m_bitmap_extruder_img->SetBitmap(m_bitmap_extruder_load);
|
||||
}
|
||||
else {
|
||||
m_bitmap_extruder_img->SetBitmap(m_bitmap_extruder);
|
||||
}
|
||||
|
||||
// BBS hide tasklist info
|
||||
// update_tasklist(obj);
|
||||
update_ams(obj);
|
||||
|
@ -1351,7 +1361,7 @@ void StatusPanel::update(MachineObject *obj)
|
|||
m_tempCtrl_frame->Enable();
|
||||
} else {
|
||||
m_tempCtrl_frame->SetLabel(TEMP_BLANK_STR);
|
||||
m_tempCtrl_frame->GetTextCtrl()->SetLabel(TEMP_BLANK_STR);
|
||||
m_tempCtrl_frame->GetTextCtrl()->SetValue(TEMP_BLANK_STR);
|
||||
m_tempCtrl_frame->Disable();
|
||||
}
|
||||
|
||||
|
@ -1386,6 +1396,7 @@ void StatusPanel::update_error_message()
|
|||
}
|
||||
|
||||
if (before_error_code != obj->print_error) {
|
||||
before_error_code = obj->print_error;
|
||||
if (wxGetApp().get_hms_query()) {
|
||||
char buf[32];
|
||||
::sprintf(buf, "%08X", obj->print_error);
|
||||
|
@ -1398,11 +1409,11 @@ void StatusPanel::update_error_message()
|
|||
print_error_str);
|
||||
show_error_message(error_msg);
|
||||
//hint dialog
|
||||
ConfirmHintDialog print_error_dlg(this->GetParent(), wxID_ANY, _L("Warning"));
|
||||
BOOST_LOG_TRIVIAL(info) << "Print error! " << error_msg;
|
||||
ConfirmHintDialog print_error_dlg(this->GetParent(), wxID_ANY, _L("Warning"), ConfirmHintDialog::ButtonStyle::ONLY_CONFIRM);
|
||||
print_error_dlg.SetHint(error_msg);
|
||||
print_error_dlg.ShowModal();
|
||||
}
|
||||
before_error_code = obj->print_error;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1764,7 +1775,7 @@ void StatusPanel::update_cali(MachineObject *obj)
|
|||
{
|
||||
if (!obj) return;
|
||||
|
||||
if (obj->is_in_calibration()) {
|
||||
if (obj->is_calibration_running()) {
|
||||
m_calibration_btn->SetLabel(_L("Calibrating"));
|
||||
if (calibration_dlg && calibration_dlg->IsShown()) {
|
||||
m_calibration_btn->Disable();
|
||||
|
@ -1840,7 +1851,8 @@ void StatusPanel::update_subtask(MachineObject *obj)
|
|||
{
|
||||
if (!obj) return;
|
||||
|
||||
if (obj->is_system_printing()) {
|
||||
if (obj->is_system_printing()
|
||||
|| obj->is_in_calibration()) {
|
||||
reset_printing_values();
|
||||
} else if (obj->is_in_printing() || obj->print_status == "FINISH") {
|
||||
if (obj->is_in_prepare()) {
|
||||
|
@ -2103,11 +2115,17 @@ void StatusPanel::on_set_nozzle_temp()
|
|||
}
|
||||
|
||||
void StatusPanel::on_ams_load(SimpleEvent &event)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "on_ams_load";
|
||||
on_ams_load_curr();
|
||||
}
|
||||
|
||||
void StatusPanel::on_ams_load_curr()
|
||||
{
|
||||
if (obj) {
|
||||
std::string curr_ams_id = m_ams_control->GetCurentAms();
|
||||
std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id);
|
||||
std::map<std::string, Ams *>::iterator it = obj->amsList.find(curr_ams_id);
|
||||
std::map<std::string, Ams*>::iterator it = obj->amsList.find(curr_ams_id);
|
||||
if (it == obj->amsList.end()) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed";
|
||||
return;
|
||||
|
@ -2118,8 +2136,8 @@ void StatusPanel::on_ams_load(SimpleEvent &event)
|
|||
return;
|
||||
}
|
||||
|
||||
AmsTray *curr_tray = obj->get_curr_tray();
|
||||
AmsTray *targ_tray = obj->get_ams_tray(curr_ams_id, curr_can_id);
|
||||
AmsTray* curr_tray = obj->get_curr_tray();
|
||||
AmsTray* targ_tray = obj->get_ams_tray(curr_ams_id, curr_can_id);
|
||||
if (curr_tray && targ_tray) {
|
||||
int old_temp = -1;
|
||||
int new_temp = -1;
|
||||
|
@ -2128,12 +2146,14 @@ void StatusPanel::on_ams_load(SimpleEvent &event)
|
|||
old_temp = (atoi(curr_tray->nozzle_temp_min.c_str()) + atoi(curr_tray->nozzle_temp_max.c_str())) / 2;
|
||||
if (!targ_tray->nozzle_temp_max.empty() && !targ_tray->nozzle_temp_min.empty())
|
||||
new_temp = (atoi(targ_tray->nozzle_temp_min.c_str()) + atoi(targ_tray->nozzle_temp_max.c_str())) / 2;
|
||||
} catch (...) {
|
||||
}
|
||||
catch (...) {
|
||||
;
|
||||
}
|
||||
int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(tray_it->second->id.c_str());
|
||||
obj->command_ams_switch(tray_index, old_temp, new_temp);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(tray_it->second->id.c_str());
|
||||
obj->command_ams_switch(tray_index, -1, -1);
|
||||
}
|
||||
|
@ -2257,6 +2277,20 @@ void StatusPanel::on_ams_selected(wxCommandEvent &event)
|
|||
}
|
||||
}
|
||||
|
||||
void StatusPanel::on_ams_guide(wxCommandEvent& event)
|
||||
{
|
||||
wxString ams_wiki_url = "https://wiki.bambulab.com/en/software/bambu-studio/use-ams-on-bambu-studio";
|
||||
wxLaunchDefaultBrowser(ams_wiki_url);
|
||||
}
|
||||
|
||||
void StatusPanel::on_ams_retry(wxCommandEvent& event)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "on_ams_retry";
|
||||
if (obj) {
|
||||
obj->command_ams_control("resume");
|
||||
}
|
||||
}
|
||||
|
||||
void StatusPanel::on_bed_temp_kill_focus(wxFocusEvent &event)
|
||||
{
|
||||
event.Skip();
|
||||
|
|
|
@ -81,6 +81,7 @@ protected:
|
|||
ScalableBitmap m_bitmap_use_time;
|
||||
ScalableBitmap m_bitmap_use_weight;
|
||||
wxBitmap m_bitmap_extruder;
|
||||
wxBitmap m_bitmap_extruder_load;
|
||||
|
||||
CameraRecordingStatus m_state_recording{CameraRecordingStatus::RECORDING_NONE};
|
||||
CameraTimelapseStatus m_state_timelapse{CameraTimelapseStatus::TIMELAPSE_NONE};
|
||||
|
@ -300,11 +301,14 @@ protected:
|
|||
|
||||
/* extruder apis */
|
||||
void on_ams_load(SimpleEvent &event);
|
||||
void on_ams_load_curr();
|
||||
void on_ams_unload(SimpleEvent &event);
|
||||
void on_ams_setting_click(SimpleEvent &event);
|
||||
void on_filament_edit(wxCommandEvent &event);
|
||||
void on_ams_refresh_rfid(wxCommandEvent &event);
|
||||
void on_ams_selected(wxCommandEvent &event);
|
||||
void on_ams_guide(wxCommandEvent &event);
|
||||
void on_ams_retry(wxCommandEvent &event);
|
||||
|
||||
void on_switch_speed(wxCommandEvent &event);
|
||||
void on_lamp_switch(wxCommandEvent &event);
|
||||
|
|
|
@ -318,7 +318,7 @@ void Tab::create_preset_tab()
|
|||
this->GetParent()->Update();
|
||||
this->GetParent()->Layout();
|
||||
|
||||
wxGetApp().plater()->search(false, m_type, m_search_item, m_search_input, m_btn_search);
|
||||
wxGetApp().plater()->search(false, m_type, m_top_panel->GetParent(), m_search_input, m_btn_search);
|
||||
m_search_input->SetFocus();
|
||||
Thaw();
|
||||
|
||||
|
@ -1382,19 +1382,14 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
|||
auto timelapse_type = m_config->option<ConfigOptionEnum<TimelapseType>>("timelapse_type");
|
||||
bool timelapse_enabled = timelapse_type->value == TimelapseType::tlSmooth;
|
||||
if (!boost::any_cast<bool>(value) && timelapse_enabled) {
|
||||
MessageDialog dlg(wxGetApp().plater(), _L("Prime tower is required by timeplase. Are you sure you want to disable both of them?"),
|
||||
MessageDialog dlg(wxGetApp().plater(), _L("Prime tower is required by smooth timeplase. If whthout prime tower, there will be flaws on the model. Are you sure you want to disable prime tower?"),
|
||||
_L("Warning"), wxICON_WARNING | wxYES | wxNO);
|
||||
if (dlg.ShowModal() == wxID_YES) {
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
new_conf.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(TimelapseType::tlNone));
|
||||
m_config_manipulation.apply(m_config, &new_conf);
|
||||
wxGetApp().plater()->update();
|
||||
}
|
||||
else {
|
||||
if (dlg.ShowModal() == wxID_NO) {
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
new_conf.set_key_value("enable_prime_tower", new ConfigOptionBool(true));
|
||||
m_config_manipulation.apply(m_config, &new_conf);
|
||||
}
|
||||
wxGetApp().plater()->update();
|
||||
}
|
||||
update_wiping_button_visibility();
|
||||
}
|
||||
|
@ -1403,7 +1398,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
|||
if (opt_key == "timelapse_type") {
|
||||
bool wipe_tower_enabled = m_config->option<ConfigOptionBool>("enable_prime_tower")->value;
|
||||
if (!wipe_tower_enabled && boost::any_cast<int>(value) == int(TimelapseType::tlSmooth)) {
|
||||
MessageDialog dlg(wxGetApp().plater(), _L("Prime tower is required by timelapse. Do you want to enable both of them?"),
|
||||
MessageDialog dlg(wxGetApp().plater(), _L("Prime tower is required by smooth timelapse. If whthout prime tower, there will be flaws on the model. Do you want to enable prime tower?"),
|
||||
_L("Warning"), wxICON_WARNING | wxYES | wxNO);
|
||||
if (dlg.ShowModal() == wxID_YES) {
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
|
@ -1411,11 +1406,6 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
|||
m_config_manipulation.apply(m_config, &new_conf);
|
||||
wxGetApp().plater()->update();
|
||||
}
|
||||
else {
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
new_conf.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(TimelapseType::tlNone));
|
||||
m_config_manipulation.apply(m_config, &new_conf);
|
||||
}
|
||||
} else {
|
||||
wxGetApp().plater()->update();
|
||||
}
|
||||
|
@ -1515,8 +1505,14 @@ void Tab::activate_option(const std::string& opt_key, const wxString& category)
|
|||
Field* field = get_field(opt_key);
|
||||
|
||||
// focused selected field
|
||||
if (field)
|
||||
if (field) {
|
||||
set_focus(field->getWindow());
|
||||
if (!field->getWindow()->HasFocus()) {
|
||||
wxScrollEvent evt(wxEVT_SCROLL_CHANGED);
|
||||
evt.SetEventObject(field->getWindow());
|
||||
wxPostEvent(m_page_view, evt);
|
||||
}
|
||||
}
|
||||
//else if (category == "Single extruder MM setup") {
|
||||
// // When we show and hide "Single extruder MM setup" page,
|
||||
// // related options are still in the search list
|
||||
|
@ -1807,9 +1803,9 @@ void TabPrint::build()
|
|||
|
||||
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->append_single_option_line("sparse_infill_pattern", "fill-patterns#infill types and their properties of sparse");
|
||||
optgroup->append_single_option_line("top_surface_pattern", "fill-patterns#Infill of the top surface and bottom surface");
|
||||
optgroup->append_single_option_line("bottom_surface_pattern", "fill-patterns#Infill of the top surface and bottom surface");
|
||||
|
||||
optgroup = page->new_optgroup(L("Advanced"), L"param_advanced");
|
||||
optgroup->append_single_option_line("infill_wall_overlap");
|
||||
|
@ -1932,19 +1928,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("print_sequence");
|
||||
optgroup->append_single_option_line("spiral_mode", "spiral-vase");
|
||||
optgroup->append_single_option_line("timelapse_type", "Timelapse");
|
||||
//BBS: todo remove clearance to machine
|
||||
#if 0
|
||||
//line = { L("Extruder radius"), "" };
|
||||
//line.append_option(optgroup->get_option("extruder_clearance_radius"));
|
||||
//optgroup->append_line(line);
|
||||
////BBS: new line for extruder_clearance_height_to_lid as there is not enough space for a single line
|
||||
//line = { L("Height to rod"), "" };
|
||||
//line.append_option(optgroup->get_option("extruder_clearance_height_to_rod"));
|
||||
//optgroup->append_line(line);
|
||||
//line = { L("Height to lid"), "" };
|
||||
//line.append_option(optgroup->get_option("extruder_clearance_height_to_lid"));
|
||||
//optgroup->append_line(line);
|
||||
#endif
|
||||
|
||||
optgroup->append_single_option_line("fuzzy_skin");
|
||||
optgroup->append_single_option_line("fuzzy_skin_point_distance");
|
||||
optgroup->append_single_option_line("fuzzy_skin_thickness");
|
||||
|
@ -2888,6 +2872,11 @@ void TabPrinter::build_fff()
|
|||
optgroup->append_single_option_line("machine_load_filament_time");
|
||||
optgroup->append_single_option_line("machine_unload_filament_time");
|
||||
|
||||
optgroup = page->new_optgroup(L("Extruder Clearance"));
|
||||
optgroup->append_single_option_line("extruder_clearance_radius");
|
||||
optgroup->append_single_option_line("extruder_clearance_height_to_rod");
|
||||
optgroup->append_single_option_line("extruder_clearance_height_to_lid");
|
||||
|
||||
optgroup = page->new_optgroup(L("Accessory") /*, L"param_accessory"*/);
|
||||
optgroup->append_single_option_line("nozzle_type");
|
||||
optgroup->append_single_option_line("auxiliary_fan");
|
||||
|
@ -2953,6 +2942,15 @@ void TabPrinter::build_fff()
|
|||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Template Custom 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);
|
||||
};
|
||||
option = optgroup->get_option("template_custom_gcode");
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
#if 0
|
||||
//page = add_options_page(L("Dependencies"), "advanced");
|
||||
// optgroup = page->new_optgroup(L("Profile dependencies"));
|
||||
|
@ -3417,17 +3415,26 @@ void TabPrinter::toggle_options()
|
|||
if (!m_active_page || m_presets->get_edited_preset().printer_technology() == ptSLA)
|
||||
return;
|
||||
|
||||
bool have_multiple_extruders = m_extruders_count > 1;
|
||||
if (m_active_page->title() == "Custom G-code") {
|
||||
toggle_option("change_filament_gcode", have_multiple_extruders);
|
||||
//BBS: whether the preset is Bambu Lab printer
|
||||
bool is_BBL_printer = false;
|
||||
if (m_preset_bundle) {
|
||||
is_BBL_printer = m_preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(m_preset_bundle);
|
||||
}
|
||||
if (m_active_page->title() == "General") {
|
||||
|
||||
bool have_multiple_extruders = m_extruders_count > 1;
|
||||
//if (m_active_page->title() == "Custom G-code") {
|
||||
// toggle_option("change_filament_gcode", have_multiple_extruders);
|
||||
//}
|
||||
if (m_active_page->title() == "Basic information") {
|
||||
toggle_option("single_extruder_multi_material", have_multiple_extruders);
|
||||
|
||||
auto flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value;
|
||||
bool is_marlin_flavor = flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware;
|
||||
// Disable silent mode for non-marlin firmwares.
|
||||
toggle_option("silent_mode", is_marlin_flavor);
|
||||
//BBS: extruder clearance of BBL printer can't be edited.
|
||||
for (auto el : { "extruder_clearance_radius", "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid" })
|
||||
toggle_option(el, !is_BBL_printer);
|
||||
}
|
||||
|
||||
wxString extruder_number;
|
||||
|
@ -3476,9 +3483,10 @@ void TabPrinter::toggle_options()
|
|||
|| m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlinFirmware);
|
||||
bool silent_mode = m_config->opt_bool("silent_mode");
|
||||
int max_field = silent_mode ? 2 : 1;
|
||||
//BBS: limits of BBL printer can't be edited.
|
||||
for (const std::string &opt : Preset::machine_limits_options())
|
||||
for (int i = 0; i < max_field; ++ i)
|
||||
toggle_option(opt, true, i);
|
||||
toggle_option(opt, !is_BBL_printer, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4285,12 +4293,21 @@ void Tab::compare_preset()
|
|||
// Wizard calls save_preset with a name "My Settings", otherwise no name is provided and this method
|
||||
// opens a Slic3r::GUI::SavePresetDialog dialog.
|
||||
//BBS: add project embedded preset relate logic
|
||||
void Tab::save_preset(std::string name /*= ""*/, bool detach, bool save_to_project)
|
||||
void Tab::save_preset(std::string name /*= ""*/, bool detach, bool save_to_project, bool from_input, std::string input_name )
|
||||
{
|
||||
// since buttons(and choices too) don't get focus on Mac, we set focus manually
|
||||
// to the treectrl so that the EVT_* events are fired for the input field having
|
||||
// focus currently.is there anything better than this ?
|
||||
//! m_tabctrl->OnSetFocus();
|
||||
if (from_input) {
|
||||
SavePresetDialog dlg(m_parent, m_type, detach ? _u8L("Detached") : "");
|
||||
dlg.Show(false);
|
||||
dlg.input_name_from_other(input_name);
|
||||
wxCommandEvent evt(wxEVT_TEXT, GetId());
|
||||
dlg.GetEventHandler()->ProcessEvent(evt);
|
||||
dlg.confirm_from_other();
|
||||
name = input_name;
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
SavePresetDialog dlg(m_parent, m_type, detach ? _u8L("Detached") : "");
|
||||
|
|
|
@ -333,7 +333,7 @@ public:
|
|||
|
||||
void compare_preset();
|
||||
//BBS: add project embedded preset relate logic
|
||||
void save_preset(std::string name = std::string(), bool detach = false, bool save_to_project = false);
|
||||
void save_preset(std::string name = std::string(), bool detach = false, bool save_to_project = false, bool from_input = false, std::string input_name = "");
|
||||
//void save_preset(std::string name = std::string(), bool detach = false);
|
||||
|
||||
void delete_preset();
|
||||
|
|
|
@ -228,6 +228,7 @@ wxPanel *MachineInfoPanel::create_caption_panel(wxWindow *parent)
|
|||
|
||||
m_upgrade_status_img = new wxStaticBitmap(caption_panel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(5), FromDIP(5)));
|
||||
m_upgrade_status_img->SetBitmap(upgrade_gray_icon);
|
||||
m_upgrade_status_img->Hide();
|
||||
m_caption_sizer->Add(m_upgrade_status_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
|
||||
|
||||
m_caption_text = new wxStaticText(caption_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
|
||||
|
|
|
@ -649,6 +649,34 @@ int GuideFrame::SaveProfile()
|
|||
return 0;
|
||||
}
|
||||
|
||||
static std::set<std::string> get_new_added_presets(const std::map<std::string, std::string>& old_data, const std::map<std::string, std::string>& new_data)
|
||||
{
|
||||
auto get_aliases = [](const std::map<std::string, std::string>& data) {
|
||||
std::set<std::string> old_aliases;
|
||||
for (auto item : data) {
|
||||
const std::string& name = item.first;
|
||||
size_t pos = name.find("@");
|
||||
old_aliases.emplace(pos == std::string::npos ? name : name.substr(0, pos-1));
|
||||
}
|
||||
return old_aliases;
|
||||
};
|
||||
|
||||
std::set<std::string> old_aliases = get_aliases(old_data);
|
||||
std::set<std::string> new_aliases = get_aliases(new_data);
|
||||
std::set<std::string> diff;
|
||||
std::set_difference(new_aliases.begin(), new_aliases.end(), old_aliases.begin(), old_aliases.end(), std::inserter(diff, diff.begin()));
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
static std::string get_first_added_preset(const std::map<std::string, std::string>& old_data, const std::map<std::string, std::string>& new_data)
|
||||
{
|
||||
std::set<std::string> diff = get_new_added_presets(old_data, new_data);
|
||||
if (diff.empty())
|
||||
return std::string();
|
||||
return *diff.begin();
|
||||
}
|
||||
|
||||
bool GuideFrame::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater, bool& apply_keeped_changes)
|
||||
{
|
||||
const auto enabled_vendors = m_appconfig_new.vendors();
|
||||
|
@ -714,13 +742,67 @@ bool GuideFrame::apply_config(AppConfig *app_config, PresetBundle *preset_bundle
|
|||
BOOST_LOG_TRIVIAL(info) << "No bundles need to be removed";
|
||||
}
|
||||
|
||||
std::string preferred_model;
|
||||
std::string preferred_variant;
|
||||
PrinterTechnology preferred_pt = ptFFF;
|
||||
auto get_preferred_printer_model = [preset_bundle, enabled_vendors, old_enabled_vendors, preferred_pt](const std::string& bundle_name, std::string& variant) {
|
||||
const auto config = enabled_vendors.find(bundle_name);
|
||||
if (config == enabled_vendors.end())
|
||||
return std::string();
|
||||
|
||||
const std::map<std::string, std::set<std::string>>& model_maps = config->second;
|
||||
//for (const auto& vendor_profile : preset_bundle->vendors) {
|
||||
for (const auto model_it: model_maps) {
|
||||
if (model_it.second.size() > 0) {
|
||||
variant = *model_it.second.begin();
|
||||
const auto config_old = old_enabled_vendors.find(bundle_name);
|
||||
if (config_old == old_enabled_vendors.end())
|
||||
return model_it.first;
|
||||
const auto model_it_old = config_old->second.find(model_it.first);
|
||||
if (model_it_old == config_old->second.end())
|
||||
return model_it.first;
|
||||
else if (model_it_old->second != model_it.second) {
|
||||
for (const auto& var : model_it.second)
|
||||
if (model_it_old->second.find(var) == model_it_old->second.end()) {
|
||||
variant = var;
|
||||
return model_it.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
if (!variant.empty())
|
||||
variant.clear();
|
||||
return std::string();
|
||||
};
|
||||
// Prusa printers are considered first, then 3rd party.
|
||||
if (preferred_model = get_preferred_printer_model(PresetBundle::BBL_BUNDLE, preferred_variant);
|
||||
preferred_model.empty()) {
|
||||
for (const auto& bundle : enabled_vendors) {
|
||||
if (bundle.first == PresetBundle::BBL_BUNDLE) { continue; }
|
||||
if (preferred_model = get_preferred_printer_model(bundle.first, preferred_variant);
|
||||
!preferred_model.empty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string first_added_filament;
|
||||
auto get_first_added_material_preset = [this, app_config](const std::string& section_name, std::string& first_added_preset) {
|
||||
if (m_appconfig_new.has_section(section_name)) {
|
||||
// get first of new added preset names
|
||||
const std::map<std::string, std::string>& old_presets = app_config->has_section(section_name) ? app_config->get_section(section_name) : std::map<std::string, std::string>();
|
||||
first_added_preset = get_first_added_preset(old_presets, m_appconfig_new.get_section(section_name));
|
||||
}
|
||||
};
|
||||
get_first_added_material_preset(AppConfig::SECTION_FILAMENTS, first_added_filament);
|
||||
|
||||
//update the app_config
|
||||
app_config->set_section(AppConfig::SECTION_FILAMENTS, enabled_filaments);
|
||||
app_config->set_vendors(m_appconfig_new);
|
||||
|
||||
if (check_unsaved_preset_changes)
|
||||
preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem,
|
||||
{PresetBundle::BBL_DEFAULT_PRINTER_MODEL, PresetBundle::BBL_DEFAULT_PRINTER_VARIANT, PresetBundle::BBL_DEFAULT_FILAMENT, std::string()});
|
||||
{preferred_model, preferred_variant, first_added_filament, std::string()});
|
||||
|
||||
// Update the selections from the compatibilty.
|
||||
preset_bundle->export_selections(*app_config);
|
||||
|
@ -902,6 +984,7 @@ int GuideFrame::LoadProfile()
|
|||
//} while (_findnext(handle, &findData) == 0); // 查找目录中的下一个文件
|
||||
|
||||
|
||||
//load BBL bundle from user data path
|
||||
string targetPath = bbl_bundle_path.make_preferred().string();
|
||||
boost::filesystem::path myPath(targetPath);
|
||||
boost::filesystem::directory_iterator endIter;
|
||||
|
@ -914,11 +997,30 @@ int GuideFrame::LoadProfile()
|
|||
//cout << iter->path().string() << endl;
|
||||
wxString strVendor = from_u8(iter->path().string()).BeforeLast('.');
|
||||
strVendor = strVendor.AfterLast( '\\');
|
||||
strVendor = strVendor.AfterLast('\/');
|
||||
strVendor = strVendor.AfterLast('\/');
|
||||
|
||||
LoadProfileFamily(w2s(strVendor), iter->path().string());
|
||||
if (w2s(strVendor) == PresetBundle::BBL_BUNDLE)
|
||||
LoadProfileFamily(w2s(strVendor), iter->path().string());
|
||||
}
|
||||
}
|
||||
|
||||
//string others_targetPath = rsrc_vendor_dir.string();
|
||||
boost::filesystem::directory_iterator others_endIter;
|
||||
for (boost::filesystem::directory_iterator iter(rsrc_vendor_dir); iter != others_endIter; iter++) {
|
||||
if (boost::filesystem::is_directory(*iter)) {
|
||||
//cout << "is dir" << endl;
|
||||
//cout << iter->path().string() << endl;
|
||||
} else {
|
||||
//cout << "is a file" << endl;
|
||||
//cout << iter->path().string() << endl;
|
||||
wxString strVendor = from_u8(iter->path().string()).BeforeLast('.');
|
||||
strVendor = strVendor.AfterLast( '\\');
|
||||
strVendor = strVendor.AfterLast('\/');
|
||||
|
||||
if (w2s(strVendor) != PresetBundle::BBL_BUNDLE)
|
||||
LoadProfileFamily(w2s(strVendor), iter->path().string());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//LoadProfileFamily(PresetBundle::BBL_BUNDLE, bbl_bundle_path.string());
|
||||
|
@ -1309,15 +1411,15 @@ int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath
|
|||
json pPrinters = pm["compatible_printers"];
|
||||
int nPrinter = pPrinters.size();
|
||||
std::string ModelList = "";
|
||||
for (int i = 0; i < nPrinter; i++)
|
||||
{
|
||||
for (int i = 0; i < nPrinter; i++)
|
||||
{
|
||||
std::string sP = pPrinters.at(i);
|
||||
if (m_ProfileJson["machine"].contains(sP))
|
||||
if (m_ProfileJson["machine"].contains(sP))
|
||||
{
|
||||
std::string mModel = m_ProfileJson["machine"][sP]["model"];
|
||||
std::string mNozzle = m_ProfileJson["machine"][sP]["nozzle"];
|
||||
std::string NewModel = mModel + "++" + mNozzle;
|
||||
|
||||
|
||||
ModelList = (boost::format("%1%[%2%]") % ModelList % NewModel).str();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ wxDEFINE_EVENT(EVT_AMS_ON_SELECTED, wxCommandEvent);
|
|||
wxDEFINE_EVENT(EVT_AMS_ON_FILAMENT_EDIT, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_AMS_CLIBRATION_AGAIN, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_AMS_CLIBRATION_CANCEL, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_AMS_GUIDE_WIKI, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_AMS_RETRY, wxCommandEvent);
|
||||
|
||||
inline int hex_digit_to_int(const char c)
|
||||
{
|
||||
|
@ -1467,14 +1469,26 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
|
|||
m_simplebook_right->AddPage(m_filament_unload_step, wxEmptyString, false);
|
||||
|
||||
wxBoxSizer *m_sizer_right_bottom = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_sizer_right_bottom->Add(0, 0, 1, wxEXPAND, FromDIP(5));
|
||||
m_button_ams_setting = new Button(m_amswin, _L("AMS Settings"));
|
||||
m_button_ams_setting->SetBackgroundColor(btn_bg_white);
|
||||
m_button_ams_setting->SetBorderColor(btn_bd_white);
|
||||
m_button_ams_setting->SetFont(Label::Body_13);
|
||||
//m_button_ams_setting->Hide();
|
||||
m_sizer_right_bottom->Add(m_button_ams_setting, 0, wxTOP, FromDIP(20));
|
||||
m_sizer_right->Add(m_sizer_right_bottom, 0, wxEXPAND, FromDIP(5));
|
||||
m_button_ams_setting = new Button(m_amswin, "", "ams_setting_normal", wxBORDER_NONE, FromDIP(24));
|
||||
m_button_ams_setting->SetPaddingSize(wxSize(0, 0));
|
||||
m_button_ams_setting->SetBackgroundColor(m_amswin->GetBackgroundColour());
|
||||
|
||||
m_button_guide = new Button(m_amswin, _L("Guide"));
|
||||
m_button_guide->SetFont(Label::Body_13);
|
||||
m_button_guide->SetCornerRadius(FromDIP(12));
|
||||
m_button_guide->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_guide->SetBackgroundColor(btn_bg_white);
|
||||
|
||||
m_button_retry = new Button(m_amswin, _L("Retry"));
|
||||
m_button_retry->SetFont(Label::Body_13);
|
||||
m_button_retry->SetCornerRadius(FromDIP(12));
|
||||
m_button_retry->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_retry->SetBackgroundColor(btn_bg_white);
|
||||
|
||||
m_sizer_right_bottom->Add(m_button_ams_setting, 0);
|
||||
m_sizer_right_bottom->Add(m_button_guide, 0, wxLEFT, FromDIP(10));
|
||||
m_sizer_right_bottom->Add(m_button_retry, 0, wxLEFT, FromDIP(10));
|
||||
m_sizer_right->Add(m_sizer_right_bottom, 0, wxEXPAND | wxTOP, FromDIP(20));
|
||||
m_sizer_bottom->Add(m_sizer_right, 0, wxEXPAND, FromDIP(5));
|
||||
|
||||
m_sizer_body->Add(m_simplebook_amsitems, 0, wxEXPAND, 0);
|
||||
|
@ -1485,7 +1499,6 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
|
|||
m_amswin->SetSizer(m_sizer_body);
|
||||
m_amswin->Layout();
|
||||
m_amswin->Fit();
|
||||
|
||||
//Thaw();
|
||||
|
||||
SetSize(m_amswin->GetSize());
|
||||
|
@ -1566,6 +1579,25 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
|
|||
m_button_extruder_feed->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_filament_load), NULL, this);
|
||||
m_button_extruder_back->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_filament_unload), NULL, this);
|
||||
m_button_ams_setting->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_ams_setting_click), NULL, this);
|
||||
m_button_ams_setting->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& e) {
|
||||
m_button_ams_setting->SetIcon("ams_setting_hover");
|
||||
e.Skip();
|
||||
});
|
||||
m_button_ams_setting->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
|
||||
m_button_ams_setting->SetIcon("ams_setting_press");
|
||||
e.Skip();
|
||||
});
|
||||
m_button_ams_setting->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent&e) {
|
||||
m_button_ams_setting->SetIcon("ams_setting_normal");
|
||||
e.Skip();
|
||||
});
|
||||
|
||||
m_button_guide->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
|
||||
post_event(wxCommandEvent(EVT_AMS_GUIDE_WIKI));
|
||||
});
|
||||
m_button_retry->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
|
||||
post_event(wxCommandEvent(EVT_AMS_RETRY));
|
||||
});
|
||||
|
||||
CreateAms();
|
||||
SetSelection(0);
|
||||
|
@ -1578,8 +1610,6 @@ void AMSControl::init_scaled_buttons()
|
|||
m_button_extruder_feed->SetCornerRadius(FromDIP(12));
|
||||
m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_extruder_back->SetCornerRadius(FromDIP(12));
|
||||
m_button_ams_setting->SetMinSize(wxSize(-1, FromDIP(33)));
|
||||
m_button_ams_setting->SetCornerRadius(FromDIP(12));
|
||||
}
|
||||
|
||||
std::string AMSControl::GetCurentAms() { return m_current_ams; }
|
||||
|
@ -1709,7 +1739,9 @@ void AMSControl::msw_rescale()
|
|||
m_extruder->msw_rescale();
|
||||
m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_extruder_feed->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_ams_setting->SetMinSize(wxSize(-1, FromDIP(33)));
|
||||
m_button_ams_setting->SetMinSize(wxSize(FromDIP(25), FromDIP(24)));
|
||||
m_button_guide->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
m_button_retry->SetMinSize(wxSize(-1, FromDIP(24)));
|
||||
|
||||
for (auto i = 0; i < m_ams_cans_list.GetCount(); i++) {
|
||||
AmsCansWindow *cans = m_ams_cans_list[i];
|
||||
|
|
|
@ -461,7 +461,9 @@ protected:
|
|||
|
||||
Button *m_button_extruder_feed = {nullptr};
|
||||
Button *m_button_extruder_back = {nullptr};
|
||||
Button *m_button_ams_setting = {nullptr};
|
||||
Button* m_button_ams_setting = {nullptr};
|
||||
Button *m_button_guide = {nullptr};
|
||||
Button *m_button_retry = {nullptr};
|
||||
|
||||
wxHyperlinkCtrl *m_hyperlink = {nullptr};
|
||||
|
||||
|
@ -518,6 +520,8 @@ wxDECLARE_EVENT(EVT_AMS_ON_SELECTED, wxCommandEvent);
|
|||
wxDECLARE_EVENT(EVT_AMS_ON_FILAMENT_EDIT, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_AMS_CLIBRATION_AGAIN, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_AMS_CLIBRATION_CANCEL, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_AMS_GUIDE_WIKI, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_AMS_RETRY, wxCommandEvent);
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ BEGIN_EVENT_TABLE(Button, StaticBox)
|
|||
|
||||
EVT_LEFT_DOWN(Button::mouseDown)
|
||||
EVT_LEFT_UP(Button::mouseReleased)
|
||||
EVT_MOUSE_CAPTURE_LOST(Button::mouseCaptureLost)
|
||||
EVT_KEY_DOWN(Button::keyDownUp)
|
||||
EVT_KEY_UP(Button::keyDownUp)
|
||||
|
||||
|
@ -23,7 +24,6 @@ END_EVENT_TABLE()
|
|||
|
||||
Button::Button()
|
||||
: paddingSize(10, 8)
|
||||
, text_color(*wxBLACK)
|
||||
{
|
||||
background_color = StateColor(
|
||||
std::make_pair(0xF0F0F0, (int) StateColor::Disabled),
|
||||
|
@ -31,6 +31,9 @@ Button::Button()
|
|||
std::make_pair(0x00AE42, (int) StateColor::Checked),
|
||||
std::make_pair(*wxLIGHT_GREY, (int) StateColor::Hovered),
|
||||
std::make_pair(*wxWHITE, (int) StateColor::Normal));
|
||||
text_color = StateColor(
|
||||
std::make_pair(*wxLIGHT_GREY, (int) StateColor::Disabled),
|
||||
std::make_pair(*wxBLACK, (int) StateColor::Normal));
|
||||
}
|
||||
|
||||
Button::Button(wxWindow* parent, wxString text, wxString icon, long style, int iconSize)
|
||||
|
@ -242,12 +245,19 @@ void Button::mouseReleased(wxMouseEvent& event)
|
|||
event.Skip();
|
||||
if (pressedDown) {
|
||||
pressedDown = false;
|
||||
ReleaseMouse();
|
||||
if (HasCapture())
|
||||
ReleaseMouse();
|
||||
if (wxRect({0, 0}, GetSize()).Contains(event.GetPosition()))
|
||||
sendButtonEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void Button::mouseCaptureLost(wxMouseCaptureLostEvent &event)
|
||||
{
|
||||
wxMouseEvent evt;
|
||||
mouseReleased(evt);
|
||||
}
|
||||
|
||||
void Button::keyDownUp(wxKeyEvent &event)
|
||||
{
|
||||
if (event.GetKeyCode() == WXK_SPACE || event.GetKeyCode() == WXK_RETURN) {
|
||||
|
|
|
@ -67,6 +67,7 @@ private:
|
|||
// some useful events
|
||||
void mouseDown(wxMouseEvent& event);
|
||||
void mouseReleased(wxMouseEvent& event);
|
||||
void mouseCaptureLost(wxMouseCaptureLostEvent &event);
|
||||
void keyDownUp(wxKeyEvent &event);
|
||||
|
||||
void sendButtonEvent();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue