Merge branch 'master' into SoftFever

# Conflicts:
#	bbl/i18n/zh_cn/BambuStudio_zh_CN.po
#	resources/i18n/de/BambuStudio.mo
#	resources/i18n/en/BambuStudio.mo
#	resources/i18n/es/BambuStudio.mo
#	resources/i18n/fr/BambuStudio.mo
#	resources/i18n/hu/BambuStudio.mo
#	resources/i18n/nl/BambuStudio.mo
#	resources/i18n/sv/BambuStudio.mo
#	resources/i18n/zh_cn/BambuStudio.mo
#	resources/profiles/Creality.json
#	resources/profiles/Voron.json
#	resources/web/guide/3/index.html
#	src/libslic3r/AppConfig.cpp
#	src/libslic3r/GCode.cpp
#	src/libslic3r/GCode/GCodeProcessor.cpp
#	src/libslic3r/LayerRegion.cpp
#	src/libslic3r/Preset.cpp
#	src/libslic3r/Print.cpp
#	src/libslic3r/PrintConfig.cpp
#	src/libslic3r/PrintConfig.hpp
#	src/libslic3r/PrintObject.cpp
#	src/slic3r/GUI/AboutDialog.cpp
#	src/slic3r/GUI/BBLTopbar.cpp
#	src/slic3r/GUI/ConfigManipulation.cpp
#	src/slic3r/GUI/ConfigWizard.cpp
#	src/slic3r/GUI/GCodeViewer.cpp
#	src/slic3r/GUI/GUI_App.cpp
#	src/slic3r/GUI/GUI_Factories.cpp
#	src/slic3r/GUI/MainFrame.cpp
#	src/slic3r/GUI/Plater.cpp
#	src/slic3r/GUI/Tab.cpp
#	version.inc
This commit is contained in:
SoftFever 2022-12-16 13:59:30 +08:00
commit bf8a9fee1f
689 changed files with 46784 additions and 10006 deletions

View file

@ -22,6 +22,7 @@
static const float GROUND_Z = -0.04f;
static const std::array<float, 4> DEFAULT_MODEL_COLOR = { 0.3255f, 0.337f, 0.337f, 1.0f };
static const std::array<float, 4> DEFAULT_MODEL_COLOR_DARK = { 0.255f, 0.255f, 0.283f, 1.0f };
static const std::array<float, 4> PICKING_MODEL_COLOR = { 0.0f, 0.0f, 0.0f, 1.0f };
namespace Slic3r {
@ -251,7 +252,7 @@ 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
//BBS add default bed
#if 1
ExPolygon poly{ Polygon::new_scale(printable_area) };
@ -264,10 +265,11 @@ bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_heig
calc_triangles(poly);
const BoundingBox& bed_bbox = poly.contour.bounding_box();
calc_gridlines(poly, bed_bbox);
//no need gridline for 3dbed
//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();
@ -313,6 +315,11 @@ Point Bed3D::point_projection(const Point& point) const
return m_polygon.point_projection(point);
}*/
void Bed3D::on_change_color_mode(bool is_dark)
{
m_is_dark = is_dark;
}
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes)
{
render_internal(canvas, bottom, scale_factor, show_axes);
@ -334,7 +341,7 @@ void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
glsafe(::glEnable(GL_DEPTH_TEST));
m_model.set_color(-1, DEFAULT_MODEL_COLOR);
m_model.set_color(-1, m_is_dark ? DEFAULT_MODEL_COLOR_DARK : DEFAULT_MODEL_COLOR);
switch (m_type)
{
@ -385,7 +392,7 @@ void Bed3D::calc_triangles(const ExPolygon& poly)
void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
{
Polylines axes_lines;
/*Polylines axes_lines;
for (coord_t x = bed_bbox.min.x(); x <= bed_bbox.max.x(); x += scale_(10.0)) {
Polyline line;
line.append(Point(x, bed_bbox.min.y()));
@ -407,7 +414,7 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines));
if (!m_gridlines.set_from_lines(gridlines, GROUND_Z))
BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n";
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,
@ -651,7 +658,7 @@ void Bed3D::render_model() const
GLModel* model = const_cast<GLModel*>(&m_model);
if (model->get_filename() != m_model_filename && model->init_from_file(m_model_filename)) {
model->set_color(-1, DEFAULT_MODEL_COLOR);
model->set_color(-1, m_is_dark ? DEFAULT_MODEL_COLOR_DARK : DEFAULT_MODEL_COLOR);
update_model_offset();
}
@ -710,7 +717,7 @@ void Bed3D::render_default(bool bottom) const
glsafe(::glDepthMask(GL_TRUE));
}
if (!picking) {
/*if (!picking) {
// draw grid
glsafe(::glLineWidth(1.5f * m_scale_factor));
if (has_model && !bottom)
@ -719,7 +726,7 @@ void Bed3D::render_default(bool bottom) const
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f));
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));

View file

@ -90,9 +90,9 @@ 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;
//Polygon m_polygon;
GeometryBuffer m_triangles;
GeometryBuffer m_gridlines;
//GeometryBuffer m_gridlines;
GLTexture m_texture;
// temporary texture shown until the main texture has still no levels compressed
//GLTexture m_temp_texture;
@ -105,6 +105,7 @@ private:
//BBS: add part plate related logic
Vec2d m_position{ Vec2d::Zero() };
std::vector<Vec2d> m_bed_shape;
bool m_is_dark = false;
public:
Bed3D() = default;
@ -141,6 +142,8 @@ public:
void render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes);
//void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor);
void on_change_color_mode(bool is_dark);
private:
//BBS: add partplate related logic
// Calculate an extended bounding box from axes and current model for visualization purposes.

View file

@ -869,10 +869,6 @@ 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());
@ -1054,7 +1050,8 @@ int GLVolumeCollection::load_object_volume(
int volume_idx,
int instance_idx,
const std::string &color_by,
bool opengl_initialized)
bool opengl_initialized,
bool in_assemble_view)
{
const ModelVolume *model_volume = model_object->volumes[volume_idx];
const int extruder_id = model_volume->extruder_id();
@ -1082,7 +1079,12 @@ int GLVolumeCollection::load_object_volume(
}
v.is_modifier = !model_volume->is_model_part();
v.shader_outside_printer_detection_enabled = model_volume->is_model_part();
v.set_instance_transformation(instance->get_transformation());
if (in_assemble_view) {
v.set_instance_transformation(instance->get_assemble_transformation());
v.set_offset_to_assembly(instance->get_offset_to_assembly());
}
else
v.set_instance_transformation(instance->get_transformation());
v.set_volume_transformation(model_volume->get_transformation());
return int(this->volumes.size() - 1);

View file

@ -632,7 +632,8 @@ public:
int volume_idx,
int instance_idx,
const std::string &color_by,
bool opengl_initialized);
bool opengl_initialized,
bool in_assemble_view = false);
// Load SLA auxiliary GLVolumes (for support trees or pad).
void load_object_auxiliary(

View file

@ -15,17 +15,13 @@ AMSMaterialsSetting::AMSMaterialsSetting(wxWindow *parent, wxWindowID id)
: DPIDialog(parent, id, _L("AMS Materials Setting"), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)
{
create();
wxGetApp().UpdateDlgDarkUI(this);
}
void AMSMaterialsSetting::create()
{
SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL);
SetSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
SetMinSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
SetMaxSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
wxBoxSizer *m_sizer_filament = new wxBoxSizer(wxHORIZONTAL);
@ -104,7 +100,7 @@ void AMSMaterialsSetting::create()
sizer_tempinput->Add(m_input_nozzle_max, 1, wxALIGN_CENTER, 0);
sizer_tempinput->Add(bitmap_min_degree, 0, wxALIGN_CENTER, 0);
sizer_tempinput->Add(FromDIP(10), 0, wxEXPAND, 0);
sizer_tempinput->Add(FromDIP(10), 0, 0, 0);
sizer_tempinput->Add(m_input_nozzle_min, 1, wxALIGN_CENTER, 0);
sizer_tempinput->Add(bitmap_max_degree, 0, wxALIGN_CENTER, 0);
@ -116,8 +112,8 @@ void AMSMaterialsSetting::create()
m_title_min->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_min->SetFont(::Label::Body_13);
sizer_temp_txt->Add(m_title_max, 1, wxALIGN_CENTER, 0);
sizer_temp_txt->Add(FromDIP(10), 0, wxEXPAND, 0);
sizer_temp_txt->Add(m_title_min, 1, wxALIGN_CENTER|wxRIGHT, FromDIP(16));
sizer_temp_txt->Add(FromDIP(10), 0, 0, 0);
sizer_temp_txt->Add(m_title_min, 1, wxALIGN_CENTER | wxRIGHT, FromDIP(16));
sizer_other->Add(sizer_temp_txt, 0, wxALIGN_CENTER, 0);
@ -188,7 +184,13 @@ void AMSMaterialsSetting::create()
m_panel_SN->Layout();
m_panel_SN->Fit();
wxBoxSizer* m_tip_sizer = new wxBoxSizer(wxHORIZONTAL);
m_tip_readonly = new wxStaticText(this, wxID_ANY, _L("Setting AMS slot information while printing is not supported"), wxDefaultPosition, wxSize(-1, AMS_MATERIALS_SETTING_INPUT_SIZE.y));
m_tip_readonly->Hide();
m_tip_sizer->Add(m_tip_readonly, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(20));
wxBoxSizer *m_sizer_button = new wxBoxSizer(wxHORIZONTAL);
m_sizer_button->Add(0, 0, 1, wxEXPAND, 0);
m_button_confirm = new Button(this, _L("Confirm"));
@ -196,7 +198,7 @@ void AMSMaterialsSetting::create()
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_confirm->SetBackgroundColor(m_btn_bg_green);
m_button_confirm->SetBorderColor(wxColour(0, 174, 66));
m_button_confirm->SetTextColor(AMS_MATERIALS_SETTING_GREY200);
m_button_confirm->SetTextColor(wxColour("#FFFFFE"));
m_button_confirm->SetMinSize(AMS_MATERIALS_SETTING_BUTTON_SIZE);
m_button_confirm->SetCornerRadius(FromDIP(12));
m_button_confirm->Bind(wxEVT_BUTTON, &AMSMaterialsSetting::on_select_ok, this);
@ -225,6 +227,7 @@ void AMSMaterialsSetting::create()
m_sizer_main->Add(warning_text, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(m_panel_SN, 0, wxLEFT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(24));
m_sizer_main->Add(m_tip_sizer, 0, wxLEFT, FromDIP(20));
m_sizer_main->Add(m_sizer_button, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
@ -240,7 +243,7 @@ void AMSMaterialsSetting::paintEvent(wxPaintEvent &evt)
{
auto size = GetSize();
wxPaintDC dc(this);
dc.SetPen(wxPen(wxColour(38, 46, 48), 1, wxSOLID));
dc.SetPen(wxPen(StateColor::darkModeColorFor(wxColour("#000000")), 1, wxSOLID));
dc.SetBrush(wxBrush(*wxTRANSPARENT_BRUSH));
dc.DrawRectangle(0, 0, size.x, size.y);
}
@ -294,11 +297,14 @@ void AMSMaterialsSetting::update()
void AMSMaterialsSetting::enable_confirm_button(bool en)
{
if (!m_is_third) return;
if (!m_is_third) {
m_tip_readonly->Hide();
}
else {
m_button_confirm->Show(en);
COMBOBOX_FILAMENT->Show(en);
m_readonly_filament->Show(!en);
m_tip_readonly->Show(!en);
}
}
@ -386,9 +392,9 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
m_input_nozzle_min->GetTextCtrl()->SetValue(temp_min);
m_input_nozzle_max->GetTextCtrl()->SetValue(temp_max);
update();
Layout();
Fit();
update();
ShowModal();
return;
}
@ -397,8 +403,6 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
m_panel_SN->Hide();
COMBOBOX_FILAMENT->Show();
m_readonly_filament->Hide();
Layout();
Fit();
int selection_idx = -1, idx = 0;
@ -468,6 +472,8 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
}
update();
Layout();
Fit();
ShowModal();
}

View file

@ -81,8 +81,9 @@ protected:
TextInput * m_input_nozzle_min;
TextInput* m_input_nozzle_max;
Button * m_button_confirm;
wxStaticText* m_tip_readonly;
Button * m_button_close;
Button * m_clr_picker;
Button * m_clr_picker;
wxColourData * m_clrData;
#ifdef __APPLE__
wxComboBox *m_comboBox_filament_mac;

View file

@ -1,4 +1,5 @@
#include "AMSSetting.hpp"
#include "GUI_App.hpp"
#include "I18N.hpp"
namespace Slic3r { namespace GUI {
@ -7,6 +8,7 @@ AMSSetting::AMSSetting(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
: DPIDialog(parent, id, wxEmptyString, pos, size, style)
{
create();
wxGetApp().UpdateDlgDarkUI(this);
}
AMSSetting::~AMSSetting() {}
@ -14,15 +16,17 @@ void AMSSetting::create()
{
wxBoxSizer *m_sizer_main;
m_sizer_main = new wxBoxSizer(wxVERTICAL);
SetBackgroundColour(*wxWHITE);
auto m_static_ams_settings = new wxStaticText(this, wxID_ANY, _L("AMS Settings"), wxDefaultPosition, wxDefaultSize, 0);
m_static_ams_settings->SetFont(::Label::Head_14);
m_static_ams_settings->SetForegroundColour(AMS_SETTING_GREY800);
m_sizer_main->Add(0,0,0,wxTOP,FromDIP(10));
m_sizer_main->Add(m_static_ams_settings, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(24));
m_panel_body = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxTAB_TRAVERSAL);
wxBoxSizer *m_sizerl_body;
m_sizerl_body = new wxBoxSizer(wxVERTICAL);
m_panel_body->SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizerl_body = new wxBoxSizer(wxVERTICAL);
// checkbox area 1
@ -41,8 +45,7 @@ void AMSSetting::create()
m_title_Insert_material_auto_read->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_Insert_material->Add(m_title_Insert_material_auto_read, 1, wxALL | wxEXPAND, 0);
m_sizerl_body->Add(m_sizer_Insert_material, 0, wxEXPAND, 0);
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
wxBoxSizer *m_sizer_Insert_material_tip = new wxBoxSizer(wxHORIZONTAL);
m_sizer_Insert_material_tip_inline = new wxBoxSizer(wxVERTICAL);
@ -84,31 +87,23 @@ void AMSSetting::create()
m_sizer_Insert_material_tip_inline->Add(m_tip_Insert_material_line3, 0, wxEXPAND, 0);
m_sizer_Insert_material_tip->Add(m_sizer_Insert_material_tip_inline, 1, wxALIGN_CENTER, 0);
m_sizerl_body->Add(m_sizer_Insert_material_tip, 0, wxEXPAND | wxLEFT, 18);
// checkbox area 2
m_sizerl_body->Add(0, 0, 0, wxTOP, 15);
wxBoxSizer *m_sizer_starting = new wxBoxSizer(wxHORIZONTAL);
m_checkbox_starting_auto_read = new ::CheckBox(m_panel_body);
m_checkbox_starting_auto_read->Bind(wxEVT_TOGGLEBUTTON, &AMSSetting::on_starting_read, this);
m_sizer_starting->Add(m_checkbox_starting_auto_read, 0, wxTOP, 1);
m_sizer_starting->Add(0, 0, 0, wxLEFT, 12);
m_title_starting_auto_read = new wxStaticText(m_panel_body, wxID_ANY, _L("Power on update"), wxDefaultPosition,
wxDefaultSize, 0);
m_title_starting_auto_read = new wxStaticText(m_panel_body, wxID_ANY, _L("Power on update"), wxDefaultPosition,wxDefaultSize, 0);
m_title_starting_auto_read->SetFont(::Label::Head_13);
m_title_starting_auto_read->SetForegroundColour(AMS_SETTING_GREY800);
m_title_starting_auto_read->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_starting->Add(m_title_starting_auto_read, 1, wxEXPAND, 0);
m_sizerl_body->Add(m_sizer_starting, 0, wxEXPAND|wxTOP, FromDIP(8));
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
wxBoxSizer *m_sizer_starting_tip = new wxBoxSizer(wxHORIZONTAL);
m_sizer_starting_tip->Add(0, 0, 0, wxLEFT, 10);
// tip line
@ -131,51 +126,98 @@ void AMSSetting::create()
m_tip_starting_line2->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
m_tip_starting_line2->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_starting_tip_inline->Add(m_tip_starting_line2, 0, wxEXPAND,0);
m_sizer_starting_tip->Add(m_sizer_starting_tip_inline, 1, wxALIGN_CENTER, 0);
m_sizerl_body->Add(m_sizer_starting_tip, 0, wxLEFT, 18);
// checkbox area 3
wxBoxSizer* m_sizer_remain = new wxBoxSizer(wxHORIZONTAL);
m_checkbox_remain = new ::CheckBox(m_panel_body);
m_checkbox_remain->Bind(wxEVT_TOGGLEBUTTON, &AMSSetting::on_remain, this);
m_sizer_remain->Add(m_checkbox_remain, 0, wxTOP, 1);
m_sizer_remain->Add(0, 0, 0, wxLEFT, 12);
m_title_remain = new wxStaticText(m_panel_body, wxID_ANY, _L("Update remaining capacity"), wxDefaultPosition, wxDefaultSize, 0);
m_title_remain->SetFont(::Label::Head_13);
m_title_remain->SetForegroundColour(AMS_SETTING_GREY800);
m_title_remain->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_remain->Add(m_title_remain, 1, wxEXPAND, 0);
m_sizerl_body->Add(0, 0, 0, wxTOP, 6);
wxBoxSizer* m_sizer_remain_tip = new wxBoxSizer(wxHORIZONTAL);
m_sizer_remain_tip->Add(0, 0, 0, wxLEFT, 10);
// tip line
m_sizer_remain_inline = new wxBoxSizer(wxVERTICAL);
m_tip_remain_line1 = new wxStaticText(m_panel_body, wxID_ANY,
_L("The AMS will estimate Bambu filament's remaining capacity after the filament info is updated. During printing, remaining capacity will be updated automatically."),
wxDefaultPosition, wxDefaultSize, 0);
m_tip_remain_line1->SetFont(::Label::Body_13);
m_tip_remain_line1->SetForegroundColour(AMS_SETTING_GREY700);
m_tip_remain_line1->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
m_tip_remain_line1->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_remain_inline->Add(m_tip_remain_line1, 0, wxEXPAND, 0);
m_sizer_remain_tip->Add(m_sizer_remain_inline, 1, wxALIGN_CENTER, 0);
// checkbox area 4
wxBoxSizer* m_sizer_switch_filament = new wxBoxSizer(wxHORIZONTAL);
m_checkbox_switch_filament = new ::CheckBox(m_panel_body);
m_checkbox_switch_filament->Bind(wxEVT_TOGGLEBUTTON, &AMSSetting::on_switch_filament, this);
m_sizer_switch_filament->Add(m_checkbox_switch_filament, 0, wxTOP, 1);
m_sizer_switch_filament->Add(0, 0, 0, wxLEFT, 12);
m_title_switch_filament = new wxStaticText(m_panel_body, wxID_ANY, _L("AMS auto switch filament"), wxDefaultPosition, wxDefaultSize, 0);
m_title_switch_filament->SetFont(::Label::Head_13);
m_title_switch_filament->SetForegroundColour(AMS_SETTING_GREY800);
m_title_switch_filament->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_switch_filament->Add(m_title_switch_filament, 1, wxEXPAND, 0);
wxBoxSizer* m_sizer_switch_filament_tip = new wxBoxSizer(wxHORIZONTAL);
m_sizer_switch_filament_tip->Add(0, 0, 0, wxLEFT, 10);
// tip line
m_sizer_switch_filament_inline = new wxBoxSizer(wxVERTICAL);
m_tip_switch_filament_line1 = new wxStaticText(m_panel_body, wxID_ANY,
_L("AMS will continue to another spool with the same properties of filament automatically when current filament runs out"),
wxDefaultPosition, wxDefaultSize, 0);
m_tip_switch_filament_line1->SetFont(::Label::Body_13);
m_tip_switch_filament_line1->SetForegroundColour(AMS_SETTING_GREY700);
m_tip_switch_filament_line1->SetSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
m_tip_switch_filament_line1->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_switch_filament_inline->Add(m_tip_switch_filament_line1, 0, wxEXPAND, 0);
m_sizer_switch_filament_tip->Add(m_sizer_switch_filament_inline, 1, wxALIGN_CENTER, 0);
// panel img
m_panel_img = new wxPanel(m_panel_body, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
wxPanel* m_panel_img = new wxPanel(m_panel_body, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_panel_img->SetBackgroundColour(AMS_SETTING_GREY200);
wxBoxSizer *m_sizer_img = new wxBoxSizer(wxVERTICAL);
auto img = new wxStaticBitmap(m_panel_img, wxID_ANY, create_scaled_bitmap("ams_icon", nullptr, 126), wxDefaultPosition, wxDefaultSize);
m_sizer_img->Add(img, 0, wxALIGN_CENTER | wxTOP, 26);
m_sizer_img->Add(0, 0, 0, wxTOP, 18);
/* wxBoxSizer *m_sizer_ams_img_tip = new wxBoxSizer(wxVERTICAL);
m_tip_ams_img = new wxStaticText(m_panel_img, wxID_ANY, _L("Click the automatic calibration button to enter the AMS initialization setup program"), wxDefaultPosition,
wxDefaultSize, 0);
m_tip_ams_img->SetFont(::Label::Body_13);
m_tip_ams_img->SetForegroundColour(AMS_SETTING_GREY700);
m_tip_ams_img->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_ams_img_tip->Add(m_tip_ams_img, 0, wxALIGN_CENTER, 0);
m_button_auto_demarcate = new Button(m_panel_img, _L("Auto Calibration"));
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>(wxColour(0, 174, 66), StateColor::Normal));
m_button_auto_demarcate->SetBackgroundColor(btn_bg_green);
m_button_auto_demarcate->SetBorderColor(wxColour(0, 174, 66));
m_button_auto_demarcate->SetTextColor(AMS_SETTING_GREY200);
m_button_auto_demarcate->SetMinSize(AMS_SETTING_BUTTON_SIZE);
m_button_auto_demarcate->SetCornerRadius(12);
m_button_auto_demarcate->Bind(wxEVT_LEFT_DOWN, &AMSSetting::on_select_ok, this);
m_sizer_img->Add(m_sizer_ams_img_tip, 1, wxALIGN_CENTER, 0);
m_sizer_img->Add(0, 0, 0, wxTOP, 12);
m_sizer_img->Add(m_button_auto_demarcate, 0, wxALIGN_CENTER, 0);
m_sizer_img->Add(0, 0, 0, wxBOTTOM, 17);*/
m_panel_img->SetSizer(m_sizer_img);
m_panel_img->Layout();
m_sizer_img->Fit(m_panel_img);
m_sizerl_body->Add(0,0,0,wxTOP, FromDIP(5));
m_sizerl_body->Add(m_sizer_Insert_material, 0, wxEXPAND, 0);
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
m_sizerl_body->Add(m_sizer_Insert_material_tip, 0, wxEXPAND | wxLEFT, 18);
m_sizerl_body->Add(0, 0, 0, wxTOP, 15);
m_sizerl_body->Add(m_sizer_starting, 0, wxEXPAND | wxTOP, FromDIP(8));
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
m_sizerl_body->Add(m_sizer_starting_tip, 0, wxLEFT, 18);
m_sizerl_body->Add(0, 0, 0, wxTOP, 15);
m_sizerl_body->Add(m_sizer_remain, 0, wxEXPAND | wxTOP, FromDIP(8));
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
m_sizerl_body->Add(m_sizer_remain_tip, 0, wxLEFT, 18);
m_sizerl_body->Add(0, 0, 0, wxTOP, 15);
m_sizerl_body->Add(m_sizer_switch_filament, 0, wxEXPAND | wxTOP, FromDIP(8));
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
m_sizerl_body->Add(m_sizer_switch_filament_tip, 0, wxLEFT, 18);
m_sizerl_body->Add(0, 0, 0, wxTOP, 6);
m_sizerl_body->Add(0, 0, 0, wxTOP, FromDIP(5));
m_sizerl_body->Add(m_panel_img, 1, wxEXPAND | wxALL, FromDIP(5));
m_panel_body->SetSizer(m_sizerl_body);
@ -188,6 +230,7 @@ void AMSSetting::create()
m_sizer_main->Fit(this);
this->Centre(wxBOTH);
wxGetApp().UpdateDlgDarkUI(this);
}
void AMSSetting::update_insert_material_read_mode(bool selected)
@ -222,6 +265,28 @@ void AMSSetting::update_starting_read_mode(bool selected)
Fit();
}
void AMSSetting::update_remain_mode(bool selected)
{
m_checkbox_remain->SetValue(selected);
}
void AMSSetting::update_switch_filament(bool selected)
{
if (obj->is_function_supported(PrinterFunction::FUNC_AUTO_SWITCH_FILAMENT)) {
m_checkbox_switch_filament->Show();
m_title_switch_filament->Show();
m_tip_switch_filament_line1->Show();
Layout();
} else {
m_checkbox_switch_filament->Hide();
m_title_switch_filament->Hide();
m_tip_switch_filament_line1->Hide();
Layout();
}
m_checkbox_switch_filament->SetValue(selected);
}
void AMSSetting::on_select_ok(wxMouseEvent &event)
{
if (obj) {
@ -247,8 +312,9 @@ void AMSSetting::on_insert_material_read(wxCommandEvent &event)
bool start_read_opt = m_checkbox_starting_auto_read->GetValue();
bool tray_read_opt = m_checkbox_Insert_material_auto_read->GetValue();
bool remain_opt = m_checkbox_remain->GetValue();
obj->command_ams_user_settings(ams_id, start_read_opt, tray_read_opt);
obj->command_ams_user_settings(ams_id, start_read_opt, tray_read_opt, remain_opt);
m_sizer_Insert_material_tip_inline->Layout();
Layout();
@ -272,8 +338,9 @@ void AMSSetting::on_starting_read(wxCommandEvent &event)
bool start_read_opt = m_checkbox_starting_auto_read->GetValue();
bool tray_read_opt = m_checkbox_Insert_material_auto_read->GetValue();
bool remain_opt = m_checkbox_remain->GetValue();
obj->command_ams_user_settings(ams_id, start_read_opt, tray_read_opt);
obj->command_ams_user_settings(ams_id, start_read_opt, tray_read_opt, remain_opt);
m_sizer_starting_tip_inline->Layout();
Layout();
@ -282,6 +349,22 @@ void AMSSetting::on_starting_read(wxCommandEvent &event)
event.Skip();
}
void AMSSetting::on_remain(wxCommandEvent& event)
{
bool start_read_opt = m_checkbox_starting_auto_read->GetValue();
bool tray_read_opt = m_checkbox_Insert_material_auto_read->GetValue();
bool remain_opt = m_checkbox_remain->GetValue();
obj->command_ams_user_settings(ams_id, start_read_opt, tray_read_opt, remain_opt);
event.Skip();
}
void AMSSetting::on_switch_filament(wxCommandEvent& event)
{
bool switch_filament = m_checkbox_switch_filament->GetValue();
obj->command_ams_switch_filament(switch_filament);
event.Skip();
}
wxString AMSSetting::append_title(wxString text)
{
wxString lab;
@ -303,7 +386,7 @@ wxStaticText *AMSSetting::append_text(wxString text)
void AMSSetting::on_dpi_changed(const wxRect &suggested_rect)
{
m_button_auto_demarcate->SetMinSize(AMS_SETTING_BUTTON_SIZE);
//m_button_auto_demarcate->SetMinSize(AMS_SETTING_BUTTON_SIZE);
}
}} // namespace Slic3r::GUI

View file

@ -29,9 +29,13 @@ public:
void update_insert_material_read_mode(bool selected);
void update_starting_read_mode(bool selected);
void on_select_ok(wxMouseEvent &event);
void update_remain_mode(bool selected);
void update_switch_filament(bool selected);
void on_select_ok(wxMouseEvent& event);
void on_insert_material_read(wxCommandEvent &event);
void on_starting_read(wxCommandEvent &event);
void on_remain(wxCommandEvent& event);
void on_switch_filament(wxCommandEvent& event);
wxString append_title(wxString text);
wxStaticText *append_text(wxString text);
MachineObject *obj{nullptr};
@ -47,16 +51,27 @@ protected:
wxStaticText *m_tip_Insert_material_line1;
wxStaticText *m_tip_Insert_material_line2;
wxStaticText *m_tip_Insert_material_line3;
CheckBox * m_checkbox_starting_auto_read;
wxStaticText *m_title_starting_auto_read;
wxStaticText *m_tip_starting_line1;
wxStaticText *m_tip_starting_line2;
wxPanel * m_panel_img;
CheckBox * m_checkbox_remain;
wxStaticText *m_title_remain;
wxStaticText *m_tip_remain_line1;
CheckBox* m_checkbox_switch_filament;
wxStaticText* m_title_switch_filament;
wxStaticText* m_tip_switch_filament_line1;
wxStaticText *m_tip_ams_img;
Button * m_button_auto_demarcate;
wxBoxSizer *m_sizer_Insert_material_tip_inline;
wxBoxSizer *m_sizer_starting_tip_inline;
wxBoxSizer *m_sizer_remain_inline;
wxBoxSizer *m_sizer_switch_filament_inline;
};
}} // namespace Slic3r::GUI

View file

@ -47,11 +47,7 @@ CopyrightsDialog::CopyrightsDialog()
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
this->SetFont(wxGetApp().normal_font());
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this);
#else
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#endif
this->SetBackgroundColour(*wxWHITE);
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
@ -66,6 +62,7 @@ CopyrightsDialog::CopyrightsDialog()
m_html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition,
wxSize(40 * em_unit(), 20 * em_unit()), wxHW_SCROLLBAR_AUTO);
m_html->SetMinSize(wxSize(FromDIP(870),FromDIP(520)));
m_html->SetBackgroundColour(*wxWHITE);
wxFont font = get_default_font(this);
const int fs = font.GetPointSize();
const int fs2 = static_cast<int>(1.2f*fs);
@ -81,6 +78,7 @@ CopyrightsDialog::CopyrightsDialog()
SetSizer(sizer);
sizer->SetSizeHints(this);
CenterOnParent();
wxGetApp().UpdateDlgDarkUI(this);
}
void CopyrightsDialog::fill_entries()
@ -214,9 +212,7 @@ AboutDialog::AboutDialog()
wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE)
{
SetFont(wxGetApp().normal_font());
wxColour bgr_clr = wxGetApp().get_window_default_clr();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
SetBackgroundColour(bgr_clr);
SetBackgroundColour(*wxWHITE);
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
@ -244,8 +240,8 @@ AboutDialog::AboutDialog()
// version
{
vesizer->Add(0, FromDIP(165), 1, wxEXPAND, FromDIP(5));
auto version_string = _L("SoftFever Version") + " " + std::string(SoftFever_VERSION);
auto version_text = GUI_App::format_display_version();
auto version_string = _L("SoftFever Version") + " " + std::string(version_text);
wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
wxFont version_font = GetFont();
#ifdef __WXMSW__
@ -255,8 +251,8 @@ AboutDialog::AboutDialog()
#endif
version_font.SetPointSize(FromDIP(16));
version->SetFont(version_font);
version->SetForegroundColour(wxColour(255, 255, 255));
version->SetBackgroundColour(wxColour(0, 174, 66));
version->SetForegroundColour(wxColour("#FFFFFE"));
version->SetBackgroundColour(wxColour("#00AF42"));
vesizer->Add(version, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5));
vesizer->Add(0, 0, 1, wxEXPAND, FromDIP(5));
}
@ -278,6 +274,7 @@ AboutDialog::AboutDialog()
{
auto staticText = new wxStaticText( this, wxID_ANY, wxEmptyString,wxDefaultPosition,wxSize(FromDIP(520), -1), wxALIGN_LEFT );
staticText->SetForegroundColour(wxColour(107, 107, 107));
staticText->SetBackgroundColour(*wxWHITE);
staticText->SetMinSize(wxSize(FromDIP(520), -1));
staticText->SetFont(Label::Body_12);
if (is_zh) {
@ -362,6 +359,7 @@ AboutDialog::AboutDialog()
ver_sizer->Add( 0, 0, 0, wxTOP, FromDIP(30));
button_portions->Bind(wxEVT_BUTTON, &AboutDialog::onCopyrightBtn, this);
wxGetApp().UpdateDlgDarkUI(this);
SetSizer(main_sizer);
Layout();
Fit();
@ -389,7 +387,6 @@ void AboutDialog::on_dpi_changed(const wxRect &suggested_rect)
SetMinSize(size);
Fit();
Refresh();
}
@ -413,7 +410,7 @@ void AboutDialog::onCopyrightBtn(wxEvent &)
void AboutDialog::onCopyToClipboard(wxEvent&)
{
wxTheClipboard->Open();
wxTheClipboard->SetData(new wxTextDataObject(_L("Version") + " " + std::string(SLIC3R_VERSION)));
wxTheClipboard->SetData(new wxTextDataObject(_L("Version") + " " + GUI_App::format_display_version()));
wxTheClipboard->Close();
}

View file

@ -28,6 +28,10 @@ wxDEFINE_EVENT(EVT_SET_FINISH_MAPPING, wxCommandEvent);
MaterialItem::MaterialItem(wxWindow *parent, wxColour mcolour, wxString mname)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
{
m_arraw_bitmap_gray = ScalableBitmap(this, "drop_down", FromDIP(12));
m_arraw_bitmap_white = ScalableBitmap(this, "topbar_dropdown", FromDIP(12));
m_material_coloul = mcolour;
m_material_name = mname;
m_ams_coloul = wxColour(0xEE,0xEE,0xEE);
@ -42,6 +46,7 @@ wxDEFINE_EVENT(EVT_SET_FINISH_MAPPING, wxCommandEvent);
SetBackgroundColour(*wxWHITE);
Bind(wxEVT_PAINT, &MaterialItem::paintEvent, this);
wxGetApp().UpdateDarkUI(this);
}
MaterialItem::~MaterialItem() {}
@ -163,6 +168,19 @@ void MaterialItem::doRender(wxDC &dc)
dc.DrawRectangle(FromDIP(1), FromDIP(18), MATERIAL_ITEM_REAL_SIZE.x, FromDIP(8));
////border
#if __APPLE__
if (m_material_coloul == *wxWHITE || m_ams_coloul == *wxWHITE) {
dc.SetPen(wxColour(0xAC, 0xAC, 0xAC));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(1, 1, MATERIAL_ITEM_SIZE.x - 1, MATERIAL_ITEM_SIZE.y - 1, 5);
}
if (m_selected) {
dc.SetPen(wxColour(0x00, 0xAE, 0x42));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(1, 1, MATERIAL_ITEM_SIZE.x - 1, MATERIAL_ITEM_SIZE.y - 1, 5);
}
#else
if (m_material_coloul == *wxWHITE || m_ams_coloul == *wxWHITE) {
dc.SetPen(wxColour(0xAC, 0xAC, 0xAC));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
@ -174,6 +192,18 @@ void MaterialItem::doRender(wxDC &dc)
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(0, 0, MATERIAL_ITEM_SIZE.x, MATERIAL_ITEM_SIZE.y, 5);
}
#endif
//arrow
if ( (m_ams_coloul.Red() > 160 && m_ams_coloul.Green() > 160 && m_ams_coloul.Blue() > 160) &&
(m_ams_coloul.Red() < 180 && m_ams_coloul.Green() < 180 && m_ams_coloul.Blue() < 180)) {
dc.DrawBitmap(m_arraw_bitmap_white.bmp(), GetSize().x - m_arraw_bitmap_white.GetBmpSize().x - FromDIP(7), GetSize().y - m_arraw_bitmap_white.GetBmpSize().y);
}
else {
dc.DrawBitmap(m_arraw_bitmap_gray.bmp(), GetSize().x - m_arraw_bitmap_gray.GetBmpSize().x - FromDIP(7), GetSize().y - m_arraw_bitmap_gray.GetBmpSize().y);
}
}
AmsMapingPopup::AmsMapingPopup(wxWindow *parent)
@ -334,14 +364,57 @@ void AmsMapingPopup::update_ams_data(std::map<std::string, Ams*> amsList)
Fit();
}
std::vector<TrayData> AmsMapingPopup::parse_ams_mapping(std::map<std::string, Ams*> amsList)
{
std::vector<TrayData> m_tray_data;
std::map<std::string, Ams *>::iterator ams_iter;
for (ams_iter = amsList.begin(); ams_iter != amsList.end(); ams_iter++) {
BOOST_LOG_TRIVIAL(trace) << "ams_mapping ams id " << ams_iter->first.c_str();
auto ams_indx = atoi(ams_iter->first.c_str());
Ams* ams_group = ams_iter->second;
std::vector<TrayData> tray_datas;
std::map<std::string, AmsTray*>::iterator tray_iter;
for (tray_iter = ams_group->trayList.begin(); tray_iter != ams_group->trayList.end(); tray_iter++) {
AmsTray* tray_data = tray_iter->second;
TrayData td;
td.id = ams_indx * AMS_TOTAL_COUNT + atoi(tray_data->id.c_str());
if (!tray_data->is_exists) {
td.type = EMPTY;
}
else {
if (!tray_data->is_tray_info_ready()) {
td.type = THIRD;
}
else {
td.type = NORMAL;
td.colour = AmsTray::decode_color(tray_data->color);
td.name = tray_data->get_display_filament_type();
td.filament_type = tray_data->get_filament_type();
}
}
m_tray_data.push_back(td);
}
}
return m_tray_data;
}
void AmsMapingPopup::add_ams_mapping(std::vector<TrayData> tray_data)
{
auto sizer_mapping_list = new wxBoxSizer(wxHORIZONTAL);
for (auto i = 0; i < tray_data.size(); i++) {
wxBoxSizer *sizer_mapping_item = new wxBoxSizer(wxVERTICAL);
// set number
auto number = new wxStaticText(this, wxID_ANY, wxString::Format("%02d",tray_data[i].id + 1), wxDefaultPosition, wxDefaultSize, 0);
auto number = new wxStaticText(this, wxID_ANY, wxGetApp().transition_tridid(tray_data[i].id), wxDefaultPosition, wxDefaultSize, 0);
number->SetFont(::Label::Body_13);
number->SetForegroundColour(wxColour(0X6B, 0X6B, 0X6B));
number->Wrap(-1);
@ -423,7 +496,7 @@ void AmsMapingPopup::paintEvent(wxPaintEvent &evt)
#ifdef __WINDOWS__
SetDoubleBuffered(true);
#endif //__WINDOWS__
SetBackgroundColour(*wxWHITE);
SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
Bind(wxEVT_PAINT, &MappingItem::paintEvent, this);
}
@ -434,9 +507,11 @@ void AmsMapingPopup::paintEvent(wxPaintEvent &evt)
void MappingItem::send_event(int fliament_id)
{
auto number = wxGetApp().transition_tridid(m_tray_data.id);
wxCommandEvent event(EVT_SET_FINISH_MAPPING);
event.SetInt(m_tray_data.id);
wxString param = wxString::Format("%d|%d|%d|%02d|%d", m_coloul.Red(), m_coloul.Green(), m_coloul.Blue(), m_tray_data.id + 1, fliament_id);
wxString param = wxString::Format("%d|%d|%d|%s|%d", m_coloul.Red(), m_coloul.Green(), m_coloul.Blue(), number, fliament_id);
event.SetString(param);
event.SetEventObject(this->GetParent()->GetParent());
wxPostEvent(this->GetParent()->GetParent(), event);
@ -510,7 +585,13 @@ void MappingItem::doRender(wxDC &dc)
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y,5);
if (m_coloul == *wxWHITE) {
dc.SetPen(wxPen(wxColour(0xAC, 0xAC, 0xAC),1));
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 5);
#ifdef __APPLE__
dc.DrawRoundedRectangle(1, 1, GetSize().x - 1, GetSize().y - 1, 5);
#else
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 5);
#endif // __APPLE__
}
}
@ -613,4 +694,107 @@ void AmsMapingTipPopup::OnDismiss() {}
bool AmsMapingTipPopup::ProcessLeftDown(wxMouseEvent &event) {
return wxPopupTransientWindow::ProcessLeftDown(event); }
AmsTutorialPopup::AmsTutorialPopup(wxWindow* parent)
:wxPopupTransientWindow(parent, wxBORDER_NONE)
{
Bind(wxEVT_PAINT, &AmsTutorialPopup::paintEvent, this);
SetBackgroundColour(*wxWHITE);
wxBoxSizer* sizer_main;
sizer_main = new wxBoxSizer(wxVERTICAL);
text_title = new Label(this, Label::Head_14, _L("Config which AMS slot should be used for a filament used in the print job"));
text_title->SetSize(wxSize(FromDIP(350), -1));
text_title->Wrap(FromDIP(350));
sizer_main->Add(text_title, 0, wxALIGN_CENTER | wxTOP, 18);
sizer_main->Add(0, 0, 0, wxTOP, 30);
wxBoxSizer* sizer_top;
sizer_top = new wxBoxSizer(wxHORIZONTAL);
img_top = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("ams_item_examples", this, 30), wxDefaultPosition, wxSize(FromDIP(50), FromDIP(30)), 0);
sizer_top->Add(img_top, 0, wxALIGN_CENTER, 0);
sizer_top->Add(0, 0, 0, wxLEFT, 10);
wxBoxSizer* sizer_top_tips = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sizer_tip_top = new wxBoxSizer(wxHORIZONTAL);
arrows_top = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("ams_arrow", this, 8), wxDefaultPosition, wxSize(FromDIP(24), FromDIP(8)), 0);
sizer_tip_top->Add(arrows_top, 0, wxALIGN_CENTER, 0);
tip_top = new wxStaticText(this, wxID_ANY, _L("Filament used in this print job"), wxDefaultPosition, wxDefaultSize, 0);
tip_top->SetForegroundColour(wxColour("#686868"));
sizer_tip_top->Add(tip_top, 0, wxALL, 0);
sizer_top_tips->Add(sizer_tip_top, 0, wxEXPAND, 0);
sizer_top_tips->Add(0, 0, 0, wxTOP, 6);
wxBoxSizer* sizer_tip_bottom = new wxBoxSizer(wxHORIZONTAL);
arrows_bottom = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("ams_arrow", this, 8), wxDefaultPosition, wxSize(FromDIP(24), FromDIP(8)), 0);
tip_bottom = new wxStaticText(this, wxID_ANY, _L("AMS slot used for this filament"), wxDefaultPosition, wxDefaultSize, 0);
tip_bottom->SetForegroundColour(wxColour("#686868"));
sizer_tip_bottom->Add(arrows_bottom, 0, wxALIGN_CENTER, 0);
sizer_tip_bottom->Add(tip_bottom, 0, wxALL, 0);
sizer_top_tips->Add(sizer_tip_bottom, 0, wxEXPAND, 0);
sizer_top->Add(sizer_top_tips, 0, wxALIGN_CENTER, 0);
wxBoxSizer* sizer_middle = new wxBoxSizer(wxHORIZONTAL);
img_middle= new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("ams_item_examples", this, 30), wxDefaultPosition, wxSize(FromDIP(50), FromDIP(30)), 0);
sizer_middle->Add(img_middle, 0, wxALIGN_CENTER, 0);
tip_middle = new wxStaticText(this, wxID_ANY, _L("Click to select AMS slot manually"), wxDefaultPosition, wxDefaultSize, 0);
tip_middle->SetForegroundColour(wxColour("#686868"));
sizer_middle->Add(0, 0, 0,wxLEFT, 15);
sizer_middle->Add(tip_middle, 0, wxALIGN_CENTER, 0);
sizer_main->Add(sizer_top, 0, wxLEFT, 40);
sizer_main->Add(0, 0, 0, wxTOP, 10);
sizer_main->Add(sizer_middle, 0, wxLEFT, 40);
sizer_main->Add(0, 0, 0, wxTOP, 10);
img_botton = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("ams_mapping_examples", this, 87), wxDefaultPosition, wxDefaultSize, 0);
sizer_main->Add(img_botton, 0, wxLEFT | wxRIGHT, 40);
sizer_main->Add(0, 0, 0, wxTOP, 12);
SetSizer(sizer_main);
Layout();
Fit();
}
void AmsTutorialPopup::paintEvent(wxPaintEvent& evt)
{
wxPaintDC dc(this);
dc.SetPen(wxColour(0xAC, 0xAC, 0xAC));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0);
}
void AmsTutorialPopup::OnDismiss() {}
bool AmsTutorialPopup::ProcessLeftDown(wxMouseEvent& event) {
return wxPopupTransientWindow::ProcessLeftDown(event);
}
}} // namespace Slic3r::GUI

View file

@ -70,6 +70,9 @@ public:
wxColour m_ams_coloul;
wxString m_ams_name;
ScalableBitmap m_arraw_bitmap_gray;
ScalableBitmap m_arraw_bitmap_white;
bool m_selected {false};
bool m_warning{false};
@ -134,7 +137,8 @@ public:
void on_left_down(wxMouseEvent &evt);
virtual void OnDismiss() wxOVERRIDE;
virtual bool ProcessLeftDown(wxMouseEvent &event) wxOVERRIDE;
void paintEvent(wxPaintEvent &evt);
void paintEvent(wxPaintEvent &evt);
std::vector<TrayData> parse_ams_mapping(std::map<std::string, Ams*> amsList);
};
class AmsMapingTipPopup : public wxPopupTransientWindow
@ -157,6 +161,27 @@ public:
wxStaticText * m_tip_disable_ams;
};
class AmsTutorialPopup : public wxPopupTransientWindow
{
public:
Label* text_title;
wxStaticBitmap* img_top;
wxStaticBitmap* arrows_top;
wxStaticText* tip_top;
wxStaticBitmap* arrows_bottom;
wxStaticText* tip_bottom;
wxStaticBitmap* img_middle;
wxStaticText* tip_middle;
wxStaticBitmap* img_botton;
AmsTutorialPopup(wxWindow* parent);
~AmsTutorialPopup() {};
void paintEvent(wxPaintEvent& evt);
virtual void OnDismiss() wxOVERRIDE;
virtual bool ProcessLeftDown(wxMouseEvent& event) wxOVERRIDE;
};
wxDECLARE_EVENT(EVT_SET_FINISH_MAPPING, wxCommandEvent);

View file

@ -52,7 +52,7 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia
wxSize panel_size = m_type == MODEL_PICTURE ? AUFILE_PICTURES_PANEL_SIZE : AUFILE_PANEL_SIZE;
wxPanel::Create(parent, id, pos, panel_size, style);
SetBackgroundColour(AUFILE_GREY300);
SetBackgroundColour(StateColor::darkModeColorFor(AUFILE_GREY300));
wxBoxSizer *sizer_body = new wxBoxSizer(wxVERTICAL);
SetSize(panel_size);
@ -96,26 +96,38 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia
cover_text_right = _L("Rename");
cover_text_cover = _L("Cover");
m_file_cover = ScalableBitmap(this, "auxiliary_cover", 50);
m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", 43);
m_file_delete = ScalableBitmap(this, "auxiliary_delete", 28);
m_file_cover = ScalableBitmap(this, "auxiliary_cover", 40);
m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", 30);
m_file_delete = ScalableBitmap(this, "auxiliary_delete", 20);
auto m_text_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(panel_size.x, AUFILE_TEXT_HEIGHT), wxTAB_TRAVERSAL);
m_text_panel->SetBackgroundColour(AUFILE_GREY300);
m_text_panel->SetBackgroundColour(StateColor::darkModeColorFor(AUFILE_GREY300));
wxBoxSizer *m_text_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_text_sizer = new wxBoxSizer(wxHORIZONTAL);
m_text_name = new wxStaticText(m_text_panel, wxID_ANY, m_file_name, wxDefaultPosition, wxSize(panel_size.x, -1), wxST_ELLIPSIZE_END);
m_text_name->Wrap(panel_size.x - FromDIP(10));
m_text_name->SetFont(::Label::Body_14);
m_text_name->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK));
m_input_name = new ::TextInput(m_text_panel, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(panel_size.x, FromDIP(35)), wxTE_PROCESS_ENTER);
m_input_name = new ::TextInput(m_text_panel, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(panel_size.x - FromDIP(28), FromDIP(32)), wxTE_PROCESS_ENTER);
m_input_name->GetTextCtrl()->SetFont(::Label::Body_13);
m_input_name->SetFont(::Label::Body_14);
m_input_name->Hide();
m_file_exit_rename = new wxStaticBitmap(m_text_panel, wxID_ANY, create_scaled_bitmap("auxiliary_delete", this, 20), wxDefaultPosition, wxSize(FromDIP(20), FromDIP(20)), 0);
m_file_exit_rename->Bind(wxEVT_LEFT_UP, [this](auto& e) {
exit_rename_mode();
});
m_text_sizer->Add(0, 0, 1, wxEXPAND, 0);
m_text_sizer->Add(m_text_name, 0, 0, 0);
m_text_sizer->Add(m_input_name, 0, 0, 0);
m_text_sizer->Add(m_text_name, 0, wxALIGN_CENTER, 0);
m_text_sizer->Add(m_input_name, 0, wxALIGN_CENTER, 0);
m_text_sizer->Add( 0, 0, 1, wxEXPAND, 0 );
m_text_sizer->Add(m_file_exit_rename, 0, wxALIGN_CENTER, 0);
m_file_exit_rename->Hide();
m_text_panel->SetSizer(m_text_sizer);
m_text_panel->Layout();
@ -138,6 +150,7 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia
void AuFile::enter_rename_mode()
{
m_input_name->Show();
m_file_exit_rename->Show();
m_text_name->Hide();
auto name = m_file_name.SubString(0, (m_file_name.Find(".") - 1));
m_input_name->GetTextCtrl()->SetLabelText(name);
@ -147,6 +160,7 @@ void AuFile::enter_rename_mode()
void AuFile::exit_rename_mode()
{
m_input_name->Hide();
m_file_exit_rename->Hide();
m_text_name->Show();
Layout();
}
@ -193,7 +207,7 @@ void AuFile::PaintBackground(wxDC &dc)
{
auto pen_width = FromDIP(2);
dc.SetPen(wxPen(AUFILE_GREY500, pen_width));
dc.SetBrush(AUFILE_GREY200);
dc.SetBrush(StateColor::darkModeColorFor(AUFILE_GREY200));
dc.DrawRoundedRectangle(pen_width / 2, pen_width / 2, size.x - pen_width / 2, size.y - pen_width / 2, AUFILE_ROUNDING);
auto line_length = FromDIP(50);
@ -226,7 +240,7 @@ void AuFile::PaintForeground(wxDC &dc)
if (m_type == AddFileButton) {
auto pen_width = FromDIP(2);
dc.SetPen(wxPen(AUFILE_BRAND, pen_width));
dc.SetBrush(AUFILE_BRAND_TRANSPARENT);
dc.SetBrush(StateColor::darkModeColorFor(AUFILE_BRAND_TRANSPARENT));
dc.DrawRoundedRectangle(pen_width / 2, pen_width / 2, size.x - pen_width / 2, size.y - pen_width / 2, AUFILE_ROUNDING);
auto line_length = FromDIP(50);
@ -247,7 +261,7 @@ void AuFile::PaintForeground(wxDC &dc)
}
dc.SetFont(Label::Body_14);
dc.SetFont(Label::Body_12);
dc.SetTextForeground(*wxWHITE);
if (m_type == MODEL_PICTURE) {
// left text
@ -265,12 +279,12 @@ void AuFile::PaintForeground(wxDC &dc)
dc.DrawText(cover_text_right, pos);
// Split
dc.SetPen(AUFILE_GREY700);
dc.SetBrush(AUFILE_GREY700);
dc.SetPen(*wxWHITE);
dc.SetBrush(*wxWHITE);
pos = wxPoint(0, 0);
pos.x = size.x / 2 - 1;
pos.y = size.y - FromDIP(30) - (m_file_edit_mask.GetBmpSize().y - FromDIP(30)) / 2;
dc.DrawRectangle(pos.x, pos.y, 2, FromDIP(30));
pos.y = size.y - FromDIP(24) - (m_file_edit_mask.GetBmpSize().y - FromDIP(24)) / 2;
dc.DrawRectangle(pos.x, pos.y, 2, FromDIP(24));
} else {
// right text
/* auto sizet = dc.GetTextExtent(cover_text_right);
@ -292,7 +306,7 @@ void AuFile::PaintForeground(wxDC &dc)
dc.DrawText(cover_text_cover, pos);
}
if (m_hover) { dc.DrawBitmap(m_file_delete.bmp(), size.x - m_file_delete.GetBmpSize().x - FromDIP(15), FromDIP(15)); }
if (m_hover) { dc.DrawBitmap(m_file_delete.bmp(), size.x - m_file_delete.GetBmpSize().x - FromDIP(10), FromDIP(10)); }
}
void AuFile::on_mouse_enter(wxMouseEvent &evt)
@ -365,12 +379,12 @@ void AuFile::on_input_enter(wxCommandEvent &evt)
fs::path newPath(new_dir_path);
fs::rename(oldPath, newPath);
} else {
MessageDialog msg_wingow(nullptr, info_line, wxEmptyString,
/*MessageDialog msg_wingow(nullptr, info_line, "",
wxICON_WARNING | wxOK);
if (msg_wingow.ShowModal() == wxID_CANCEL) {
m_input_name->GetTextCtrl()->SetValue(wxEmptyString);
return;
}
}*/
return;
}
@ -407,7 +421,7 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt)
auto pos = evt.GetPosition();
// set cover
auto mask_size = m_file_edit_mask.GetBmpSize();
auto mask_size = wxSize(GetSize().x, m_file_edit_mask.GetBmpSize().y);
auto cover_left = 0;
auto cover_top = size.y - mask_size.y;
auto cover_right = mask_size.x / 2;
@ -429,10 +443,10 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt)
if (pos.x > rename_left && pos.x < rename_right && pos.y > rename_top && pos.y < rename_bottom) { on_set_rename(); return; }
// close
auto close_left = size.x - m_file_delete.GetBmpSize().x - FromDIP(15);
auto close_top = FromDIP(15);
auto close_right = size.x - FromDIP(15);
auto close_bottom = m_file_delete.GetBmpSize().y + FromDIP(15);
auto close_left = size.x - m_file_delete.GetBmpSize().x - FromDIP(10);
auto close_top = FromDIP(10);
auto close_right = size.x - FromDIP(10);
auto close_bottom = m_file_delete.GetBmpSize().y + FromDIP(10);
if (pos.x > close_left && pos.x < close_right && pos.y > close_top && pos.y < close_bottom) { on_set_delete(); return; }
exit_rename_mode();
@ -442,7 +456,7 @@ void AuFile::on_set_cover()
{
if (wxGetApp().plater()->model().model_info == nullptr) { wxGetApp().plater()->model().model_info = std::make_shared<ModelInfo>(); }
wxGetApp().plater()->model().model_info->cover_file = std::string(m_file_name.ToUTF8().data());
wxGetApp().plater()->model().model_info->cover_file = m_file_name.ToStdString();
auto full_path = m_file_path.branch_path();
auto full_root_path = full_path.branch_path();
@ -528,9 +542,9 @@ AuFile::~AuFile() {}
void AuFile::msw_rescale()
{
m_file_cover = ScalableBitmap(this, "auxiliary_cover", 50);
m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", 43);
m_file_delete = ScalableBitmap(this, "auxiliary_delete", 28);
m_file_cover = ScalableBitmap(this, "auxiliary_cover", 40);
m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", FromDIP(30));
m_file_delete = ScalableBitmap(this, "auxiliary_delete", 20);
if (m_type == MODEL_PICTURE) {
if (m_file_path.empty()) { return;}
@ -577,12 +591,12 @@ AuFolderPanel::AuFolderPanel(wxWindow *parent, AuxiliaryFolderType type, wxWindo
std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Normal));
StateColor btn_bd_white(std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
m_button_add = new Button(m_scrolledWindow, _L("Add"), "auxiliary_add_file", 12, 12);
m_button_add->SetBackgroundColor(btn_bg_white);
//m_button_add = new AuFile(m_scrolledWindow, fs::path(), "", AddFileButton, -1);
/*m_button_add->SetBackgroundColor(btn_bg_white);
m_button_add->SetBorderColor(btn_bd_white);
m_button_add->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_add->SetCornerRadius(FromDIP(12));
m_button_add->SetFont(Label::Body_14);
m_button_add->SetFont(Label::Body_14);*/
m_big_button_add = new AuFile(m_scrolledWindow, fs::path(), "", AddFileButton, -1);
@ -596,14 +610,14 @@ AuFolderPanel::AuFolderPanel(wxWindow *parent, AuxiliaryFolderType type, wxWindo
sizer_top->Add(0, 0, 0, wxLEFT, FromDIP(10));
m_gsizer_content = new wxWrapSizer(wxHORIZONTAL, wxWRAPSIZER_DEFAULT_FLAGS);
if (m_type == MODEL_PICTURE) {
sizer_top->Add(m_button_add, 0, wxALL, 0);
m_big_button_add->Hide();
}
else {
//if (m_type == MODEL_PICTURE) {
// //sizer_top->Add(m_button_add, 0, wxALL, 0);
// //m_big_button_add->Hide();
//}
//else {
m_gsizer_content->Add(m_big_button_add, 0, wxALL, FromDIP(8));
m_button_add->Hide();
}
//m_button_add->Hide();
//}
// sizer_top->Add(m_button_del, 0, wxALL, 0);
sizer_body->Add(sizer_top, 0, wxEXPAND | wxTOP, FromDIP(35));
sizer_body->AddSpacer(FromDIP(14));
@ -622,7 +636,7 @@ AuFolderPanel::AuFolderPanel(wxWindow *parent, AuxiliaryFolderType type, wxWindo
evt.SetEventObject(m_parent);
wxPostEvent(m_parent, evt);
});
m_button_add->Bind(wxEVT_BUTTON, &AuFolderPanel::on_add, this);
//m_button_add->Bind(wxEVT_LEFT_UP, &AuFolderPanel::on_add, this);
}
void AuFolderPanel::clear()
@ -640,8 +654,8 @@ void AuFolderPanel::update(std::vector<fs::path> paths)
{
clear();
for (auto i = 0; i < paths.size(); i++) {
std::string temp_name = fs::path(paths[i].c_str()).filename().string();
auto name = encode_path(temp_name.c_str());
std::string temp_name = fs::path(paths[i].c_str()).filename().string();
auto name = encode_path(temp_name.c_str());
auto aufile = new AuFile(m_scrolledWindow, paths[i], name, m_type, wxID_ANY);
m_gsizer_content->Add(aufile, 0, wxALL, FromDIP(8));
@ -656,14 +670,14 @@ void AuFolderPanel::update(std::vector<fs::path> paths)
void AuFolderPanel::msw_rescale()
{
m_button_add->SetMinSize(wxSize(-1, FromDIP(24)));
//m_button_add->SetMinSize(wxSize(-1, FromDIP(24)));
for (auto i = 0; i < m_aufiles_list.GetCount(); i++) {
AuFiles *aufile = m_aufiles_list[i];
aufile->file->msw_rescale();
}
}
void AuFolderPanel::on_add(wxCommandEvent& event)
void AuFolderPanel::on_add(wxMouseEvent& event)
{
auto evt = wxCommandEvent(EVT_AUXILIARY_IMPORT);
evt.SetString(s_default_folders[m_type]);
@ -806,7 +820,7 @@ void AuxiliaryPanel::init_tabpanel()
wxBoxSizer *sizer_side_tools = new wxBoxSizer(wxVERTICAL);
sizer_side_tools->Add(m_side_tools, 1, wxEXPAND, 0);
m_tabpanel = new Tabbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, sizer_side_tools, wxNB_LEFT | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
m_tabpanel->SetBackgroundColour(*wxWHITE);
m_tabpanel->SetBackgroundColour(wxColour("#FEFFFF"));
m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent &e) { ; });
m_designer_panel = new DesignerPanel(m_tabpanel, AuxiliaryFolderType::DESIGNER);
@ -921,7 +935,8 @@ void AuxiliaryPanel::on_import_file(wxCommandEvent &event)
strftime(ch1, sizeof(ch1), "%T", localtime(&t1));
std::string time_text = ch1;
auto before_name = replaceSpace(src_bfs_path.filename().string(), src_bfs_path.extension().string(), "");
wxString name = src_bfs_path.filename().generic_wstring();
auto before_name = replaceSpace(name.ToStdString(), src_bfs_path.extension().string(), "");
time_text = replaceSpace(time_text, ":", "_");
dir_path += "/" + before_name + "_" + time_text + src_bfs_path.extension().wstring();
}
@ -1185,7 +1200,6 @@ void DesignerPanel::on_input_enter_model(wxCommandEvent &evt)
}
}
void DesignerPanel::update_info()
{
if (wxGetApp().plater()->model().design_info != nullptr) {

View file

@ -53,8 +53,10 @@
#define AUFILE_GREY200 wxColour(248, 248, 248)
#define AUFILE_BRAND wxColour(0, 174, 66)
#define AUFILE_BRAND_TRANSPARENT wxColour(215, 232, 222)
#define AUFILE_PICTURES_SIZE wxSize(FromDIP(300), FromDIP(300))
#define AUFILE_PICTURES_PANEL_SIZE wxSize(FromDIP(300), FromDIP(340))
//#define AUFILE_PICTURES_SIZE wxSize(FromDIP(300), FromDIP(300))
//#define AUFILE_PICTURES_PANEL_SIZE wxSize(FromDIP(300), FromDIP(340))
#define AUFILE_PICTURES_SIZE wxSize(FromDIP(168), FromDIP(168))
#define AUFILE_PICTURES_PANEL_SIZE wxSize(FromDIP(168), FromDIP(208))
#define AUFILE_SIZE wxSize(FromDIP(168), FromDIP(168))
#define AUFILE_PANEL_SIZE wxSize(FromDIP(168), FromDIP(208))
#define AUFILE_TEXT_HEIGHT FromDIP(40)
@ -95,6 +97,7 @@ public:
ScalableBitmap m_file_cover;
ScalableBitmap m_file_edit_mask;
ScalableBitmap m_file_delete;
wxStaticBitmap* m_file_exit_rename;
ScalableBitmap m_bitmap_excel;
ScalableBitmap m_bitmap_pdf;
@ -110,7 +113,7 @@ public:
void PaintForeground(wxDC &dc);
void on_mouse_enter(wxMouseEvent &evt);
void on_mouse_leave(wxMouseEvent &evt);
void on_input_enter(wxCommandEvent &evt);
void on_input_enter(wxCommandEvent& evt);
void on_dclick(wxMouseEvent &evt);
void on_mouse_left_up(wxMouseEvent &evt);
@ -156,12 +159,12 @@ public:
AuxiliaryFolderType m_type;
wxScrolledWindow * m_scrolledWindow{nullptr};
wxWrapSizer * m_gsizer_content{nullptr};
Button * m_button_add{nullptr};
//AuFile * m_button_add{nullptr};
Button * m_button_del{nullptr};
AuFile * m_big_button_add{ nullptr };
AuFilesHash m_aufiles_list;
void on_add(wxCommandEvent& event);
void on_add(wxMouseEvent& event);
void on_delete(wxCommandEvent &event);
};

View file

@ -117,6 +117,11 @@ void BBLStatusBar::set_range(int val)
}
}
void BBLStatusBar::clear_percent()
{
}
void BBLStatusBar::show_progress(bool show)
{
if (show) {

View file

@ -44,6 +44,7 @@ public:
void set_progress(int) override;
int get_range() const override;
void set_range(int = 100) override;
void clear_percent() override;
void show_progress(bool);
void start_busy(int = 100);
void stop_busy();

View file

@ -27,7 +27,7 @@ BBLStatusBarBind::BBLStatusBarBind(wxWindow *parent, int id)
//wxBoxSizer *m_sizer_bottom = new wxBoxSizer(wxHORIZONTAL);
/* m_status_text = new wxStaticText(m_self, wxID_ANY, L(""), wxDefaultPosition, wxDefaultSize, 0);
/* m_status_text = new wxStaticText(m_self, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
m_status_text->SetForegroundColour(wxColour(107, 107, 107));
m_status_text->SetFont(::Label::Body_13);
m_status_text->Wrap(-1);
@ -37,7 +37,7 @@ BBLStatusBarBind::BBLStatusBarBind(wxWindow *parent, int id)
m_prog->SetValue(0);
m_stext_percent = new wxStaticText(m_self, wxID_ANY, _L(""), wxDefaultPosition, wxDefaultSize, 0);
m_stext_percent = new wxStaticText(m_self, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
m_stext_percent->SetForegroundColour(wxColour(107, 107, 107));
m_stext_percent->SetFont(::Label::Body_13);
m_stext_percent->Wrap(-1);
@ -92,6 +92,11 @@ void BBLStatusBarBind::set_range(int val)
}
}
void BBLStatusBarBind::clear_percent()
{
}
void BBLStatusBarBind::show_progress(bool show)
{
if (show) {

View file

@ -47,6 +47,7 @@ public:
void set_progress(int) override;
int get_range() const override;
void set_range(int = 100) override;
void clear_percent() override;
void show_progress(bool);
void start_busy(int = 100);
void stop_busy();

View file

@ -26,11 +26,11 @@ BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
wxBoxSizer *m_sizer_body = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_sizer_bottom = new wxBoxSizer(wxHORIZONTAL);
m_status_text = new wxStaticText(m_self, wxID_ANY, L(""), wxDefaultPosition, wxSize(m_self->FromDIP(280), -1), 0);
m_status_text = new wxStaticText(m_self, wxID_ANY, wxEmptyString);
m_status_text->SetForegroundColour(wxColour(107, 107, 107));
m_status_text->SetFont(::Label::Body_13);
m_status_text->Wrap(m_self->FromDIP(280));
m_status_text->SetSize(wxSize(m_self->FromDIP(280), m_self->FromDIP(46)));
m_status_text->SetMaxSize(wxSize(m_self->FromDIP(280), m_self->FromDIP(46)));
m_prog = new wxGauge(m_self, wxID_ANY, 100, wxDefaultPosition, wxSize(-1, m_self->FromDIP(6)), wxGA_HORIZONTAL);
m_prog->SetValue(0);
@ -42,10 +42,12 @@ BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
m_sizer_bottom->Add(m_prog, 1, wxALIGN_CENTER, 0);
StateColor btn_bd_white(std::pair<wxColour, int>(*wxWHITE, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
m_cancelbutton = new Button(m_self, _L("Cancel"));
m_cancelbutton->SetMinSize(wxSize(m_self->FromDIP(64), m_self->FromDIP(24)));
m_cancelbutton->SetTextColor(wxColour(107, 107, 107));
m_cancelbutton->SetBackgroundColor(wxColour(255, 255, 255));
m_cancelbutton->SetBorderColor(btn_bd_white);
m_cancelbutton->SetCornerRadius(m_self->FromDIP(12));
m_cancelbutton->Bind(wxEVT_BUTTON,
[this](wxCommandEvent &evt) {
@ -54,7 +56,7 @@ BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
m_cancel_cb_fina();
});
m_stext_percent = new wxStaticText(m_self, wxID_ANY, L(""), wxDefaultPosition, wxDefaultSize, 0);
m_stext_percent = new wxStaticText(m_self, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
m_stext_percent->SetForegroundColour(wxColour(107, 107, 107));
m_stext_percent->SetFont(::Label::Body_13);
m_stext_percent->Wrap(-1);
@ -99,6 +101,7 @@ void BBLStatusBarSend::set_progress(int val)
}
m_prog->SetValue(val);
set_percent_text(wxString::Format("%d%%", val));
m_sizer->Layout();
}
@ -114,6 +117,11 @@ void BBLStatusBarSend::set_range(int val)
}
}
void BBLStatusBarSend::clear_percent()
{
set_percent_text(wxEmptyString);
}
void BBLStatusBarSend::show_progress(bool show)
{
if (show) {
@ -168,15 +176,66 @@ wxPanel* BBLStatusBarSend::get_panel()
return m_self;
}
bool BBLStatusBarSend::is_english_text(wxString str)
{
std::regex reg("^[0-9a-zA-Z]+$");
std::smatch matchResult;
std::string pattern_Special = "{}[]<>~!@#$%^&*(),.?/ :";
for (auto i = 0; i < str.Length(); i++) {
std::string regex_str = wxString(str[i]).ToStdString();
if (std::regex_match(regex_str, matchResult, reg)) {
continue;
}
else {
int result = pattern_Special.find(regex_str.c_str());
if (result < 0 || result > pattern_Special.length()) {
return false;
}
}
}
return true;
}
bool BBLStatusBarSend::format_text(wxStaticText* dc, int width, const wxString& text, wxString& multiline_text)
{
bool multiline = false;
multiline_text = text;
if (width > 0 && dc->GetTextExtent(text).x > width) {
size_t start = 0;
while (true) {
size_t idx = size_t(-1);
for (size_t i = start; i < multiline_text.Len(); i++) {
if (multiline_text[i] == ' ') {
if (dc->GetTextExtent(multiline_text.SubString(start, i)).x < width)
idx = i;
else {
if (idx == size_t(-1)) idx = i;
break;
}
}
}
if (idx == size_t(-1)) break;
multiline = true;
multiline_text[idx] = '\n';
start = idx + 1;
if (dc->GetTextExtent(multiline_text.Mid(start)).x < width) break;
}
}
return multiline;
//return dc->GetTextExtent(multiline_text);
}
void BBLStatusBarSend::set_status_text(const wxString& txt)
{
//auto txtss = "Sending the printing task has timed out.\nPlease try again!";
//auto txtss = "The printing project is being uploaded... 25%%";
//m_status_text->SetLabelText(txtss);
m_status_text->SetLabelText(txt);
m_status_text->SetSize(wxSize(m_self->FromDIP(280), -1));
m_status_text->SetMaxSize(wxSize(m_self->FromDIP(280), -1));
m_status_text->Wrap(m_self->FromDIP(280));
wxString str;
format_text(m_status_text, m_self->FromDIP(280), txt, str);
m_status_text->SetLabelText(str);
//if (is_english_text(str)) m_status_text->Wrap(m_self->FromDIP(280));
}
void BBLStatusBarSend::set_percent_text(const wxString &txt)
@ -206,6 +265,7 @@ wxString BBLStatusBarSend::get_status_text() const
bool BBLStatusBarSend::update_status(wxString &msg, bool &was_cancel, int percent, bool yield)
{
//auto test_txt = _L("Unkown Error.") + _L("status=150, body=Timeout was reached: Connection timed out after 10009 milliseconds [Error 28]");
set_status_text(msg);
if (percent >= 0)
@ -225,7 +285,6 @@ void BBLStatusBarSend::reset()
set_percent_text(wxString::Format("%d%%", 0));
}
void BBLStatusBarSend::set_font(const wxFont &font)
{
m_self->SetFont(font);

View file

@ -48,6 +48,7 @@ public:
void set_progress(int) override;
int get_range() const override;
void set_range(int = 100) override;
void clear_percent() override;
void show_progress(bool);
void start_busy(int = 100);
void stop_busy();
@ -56,7 +57,9 @@ public:
void set_cancel_callback(CancelFn = CancelFn()) override;
inline void reset_cancel_callback() { set_cancel_callback(); }
wxPanel * get_panel();
void set_status_text(const wxString &txt);
bool is_english_text(wxString str);
bool format_text(wxStaticText* dc, int width, const wxString& text, wxString& multiline_text);
void set_status_text(const wxString& txt);
void set_percent_text(const wxString &txt);
void msw_rescale();
void set_status_text(const std::string &txt);
@ -69,7 +72,6 @@ public:
bool is_slice_info_shown();
bool update_status(wxString &msg, bool &was_cancel, int percent = -1, bool yield = true);
void reset();
// Temporary methods to satisfy Perl side
void show_cancel_button();
void hide_cancel_button();

View file

@ -250,13 +250,12 @@ void BBLTopbar::Init(wxFrame* parent)
this->AddSpacer(FromDIP(10));
this->AddStretchSpacer(1);
// #if !BBL_RELEASE_TO_PUBLIC
/*wxBitmap m_publish_bitmap = create_scaled_bitmap("topbar_publish", nullptr, TOPBAR_ICON_SIZE);
m_publish_item = this->AddTool(ID_PUBLISH, "", m_publish_bitmap);
wxBitmap m_publish_disable_bitmap = create_scaled_bitmap("topbar_publish_disable", nullptr, TOPBAR_ICON_SIZE);
m_publish_bitmap = create_scaled_bitmap("topbar_publish", nullptr, TOPBAR_ICON_SIZE);
m_publish_item = this->AddTool(ID_PUBLISH, "", m_publish_bitmap);
m_publish_disable_bitmap = create_scaled_bitmap("topbar_publish_disable", nullptr, TOPBAR_ICON_SIZE);
m_publish_item->SetDisabledBitmap(m_publish_disable_bitmap);
this->AddSpacer(FromDIP(12));*/
// #endif
this->EnableTool(m_publish_item->GetId(), false);
this->AddSpacer(FromDIP(12));
/*wxBitmap model_store_bitmap = create_scaled_bitmap("topbar_store", nullptr, TOPBAR_ICON_SIZE);
m_model_store_item = this->AddTool(ID_MODEL_STORE, "", model_store_bitmap);
@ -310,7 +309,7 @@ void BBLTopbar::Init(wxFrame* parent)
this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnRedo, this, wxID_REDO);
this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnUndo, this, wxID_UNDO);
//this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnModelStoreClicked, this, ID_MODEL_STORE);
//this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnPublishClicked, this, ID_PUBLISH);
this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnPublishClicked, this, ID_PUBLISH);
}
BBLTopbar::~BBLTopbar()
@ -320,6 +319,12 @@ BBLTopbar::~BBLTopbar()
m_file_menu = nullptr;
}
void BBLTopbar::show_publish_button(bool show)
{
this->EnableTool(m_publish_item->GetId(), show);
Refresh();
}
void BBLTopbar::OnOpenProject(wxAuiToolBarEvent& event)
{
MainFrame* main_frame = dynamic_cast<MainFrame*>(m_frame);
@ -374,11 +379,21 @@ void BBLTopbar::OnModelStoreClicked(wxAuiToolBarEvent& event)
void BBLTopbar::OnPublishClicked(wxAuiToolBarEvent& event)
{
if (GUI::wxGetApp().plater()->model().objects.empty()) return;
if (!wxGetApp().getAgent()) {
BOOST_LOG_TRIVIAL(info) << "publish: no agent";
return;
}
if (!wxGetApp().is_user_login()) return;
//no more check
//if (GUI::wxGetApp().plater()->model().objects.empty()) return;
if (!wxGetApp().check_login())
return;
#ifdef ENABLE_PUBLISHING
wxGetApp().plater()->show_publish_dialog();
#endif
wxGetApp().open_publish_page_dialog();
}
void BBLTopbar::SetFileMenu(wxMenu* file_menu)
@ -539,7 +554,7 @@ void BBLTopbar::OnFileToolItem(wxAuiToolBarEvent& evt)
tb->SetToolSticky(evt.GetId(), true);
if (!m_skip_popup_file_menu) {
this->PopupMenu(m_file_menu, wxPoint(0, this->GetSize().GetHeight() - 2));
this->PopupMenu(m_file_menu, wxPoint(FromDIP(1), this->GetSize().GetHeight() - 2));
}
else {
m_skip_popup_file_menu = false;
@ -556,7 +571,7 @@ void BBLTopbar::OnDropdownToolItem(wxAuiToolBarEvent& evt)
tb->SetToolSticky(evt.GetId(), true);
if (!m_skip_popup_dropdown_menu) {
PopupMenu(&m_top_menu, wxPoint(0, this->GetSize().GetHeight() - 2));
PopupMenu(&m_top_menu, wxPoint(FromDIP(1), this->GetSize().GetHeight() - 2));
}
else {
m_skip_popup_dropdown_menu = false;

View file

@ -16,6 +16,7 @@ public:
BBLTopbar(wxFrame* parent);
void Init(wxFrame *parent);
~BBLTopbar();
void show_publish_button(bool show);
void UpdateToolbarWidth(int width);
void Rescale();
void OnIconize(wxAuiToolBarEvent& event);
@ -63,11 +64,14 @@ private:
wxAuiToolBarItem* m_account_item;
wxAuiToolBarItem* m_model_store_item;
//wxAuiToolBarItem *m_publish_item;
wxAuiToolBarItem *m_publish_item;
wxAuiToolBarItem* m_undo_item;
wxAuiToolBarItem* m_redo_item;
wxAuiToolBarItem* maximize_btn;
wxBitmap m_publish_bitmap;
wxBitmap m_publish_disable_bitmap;
wxBitmap maximize_bitmap;
wxBitmap window_bitmap;

View file

@ -69,10 +69,10 @@ bool SlicingProcessCompletedEvent::invalidate_plater() const
return false;
}
std::pair<std::string, bool> SlicingProcessCompletedEvent::format_error_message() const
std::pair<std::string, size_t> SlicingProcessCompletedEvent::format_error_message() const
{
std::string error;
bool monospace = false;
size_t monospace = 0;
try {
this->rethrow_exception();
} catch (const std::bad_alloc &ex) {
@ -84,7 +84,10 @@ std::pair<std::string, bool> SlicingProcessCompletedEvent::format_error_message(
_u8L("Please save project and restart the program. ");
} catch (PlaceholderParserError &ex) {
error = ex.what();
monospace = true;
monospace = 1;
} catch (SlicingError &ex) {
error = ex.what();
monospace = ex.objectId();
} catch (std::exception &ex) {
error = ex.what();
} catch (...) {
@ -661,7 +664,10 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn
{
assert(m_print != nullptr);
assert(config.opt_enum<PrinterTechnology>("printer_technology") == m_print->technology());
Print::ApplyStatus invalidated = m_print->apply(model, config);
// TODO: add partplate config
DynamicPrintConfig new_config = config;
new_config.apply(*m_current_plate->config());
Print::ApplyStatus invalidated = m_print->apply(model, new_config);
if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF &&
!m_fff_print->is_step_done(psGCodeExport)) {
// Some FFF status was invalidated, and the G-code was not exported yet.

View file

@ -60,7 +60,7 @@ public:
void rethrow_exception() const { assert(this->error()); assert(m_exception); std::rethrow_exception(m_exception); }
// Produce a human readable message to be displayed by a notification or a message box.
// 2nd parameter defines whether the output should be displayed with a monospace font.
std::pair<std::string, bool> format_error_message() const;
std::pair<std::string, size_t> format_error_message() const;
private:
StatusType m_status;

View file

@ -140,7 +140,7 @@ void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const Co
main_sizer->Add(m_panel, 1, wxEXPAND);
main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
wxGetApp().UpdateDlgDarkUI(this, true);
wxGetApp().UpdateDlgDarkUI(this);
SetSizer(main_sizer);
SetMinSize(GetSize());
@ -201,7 +201,7 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
Line line{ "", "" };
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
wxButton* shape_btn = new wxButton(parent, wxID_ANY, _L("Load shape from STL..."));
Button* shape_btn = new Button(parent, _L("Load shape from STL..."));
wxSizer* shape_sizer = new wxBoxSizer(wxHORIZONTAL);
shape_sizer->Add(shape_btn, 1, wxEXPAND);
@ -270,7 +270,7 @@ void BedShapePanel::activate_options_page(ConfigOptionsGroupShp options_group)
wxPanel* BedShapePanel::init_texture_panel()
{
wxPanel* panel = new wxPanel(this);
wxGetApp().UpdateDarkUI(panel, true);
panel->SetBackgroundColour(*wxWHITE);
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _L("Texture"));
optgroup->label_width = 10;
@ -281,7 +281,17 @@ wxPanel* BedShapePanel::init_texture_panel()
Line line{ "", "" };
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
wxButton* load_btn = new wxButton(parent, wxID_ANY, _L("Load..."));
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Disabled), std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
StateColor btn_bd_white(std::pair<wxColour, int>(*wxWHITE, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
Button* load_btn = new Button(parent, _L("Load..."));
load_btn->SetBackgroundColor(btn_bg_white);
load_btn->SetBorderColor(btn_bd_white);
load_btn->SetBackgroundColour(*wxWHITE);
wxSizer* load_sizer = new wxBoxSizer(wxHORIZONTAL);
load_sizer->Add(load_btn, 1, wxEXPAND);
@ -290,10 +300,16 @@ wxPanel* BedShapePanel::init_texture_panel()
wxSizer* filename_sizer = new wxBoxSizer(wxHORIZONTAL);
filename_sizer->Add(filename_lbl, 1, wxEXPAND);
wxButton* remove_btn = new wxButton(parent, wxID_ANY, _L("Remove"));
Button* remove_btn = new Button(parent, _L("Remove"));
remove_btn->SetBackgroundColor(btn_bg_white);
remove_btn->SetBorderColor(btn_bd_white);
remove_btn->SetBackgroundColour(*wxWHITE);
wxSizer* remove_sizer = new wxBoxSizer(wxHORIZONTAL);
remove_sizer->Add(remove_btn, 1, wxEXPAND);
wxGetApp().UpdateDarkUI(load_btn);
wxGetApp().UpdateDarkUI(remove_btn);
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(filename_sizer, 1, wxEXPAND);
sizer->Add(load_sizer, 1, wxEXPAND);
@ -341,7 +357,7 @@ wxPanel* BedShapePanel::init_texture_panel()
wxPanel* BedShapePanel::init_model_panel()
{
wxPanel* panel = new wxPanel(this);
wxGetApp().UpdateDarkUI(panel, true);
panel->SetBackgroundColour(*wxWHITE);
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _L("Model"));
optgroup->label_width = 10;
@ -349,10 +365,21 @@ wxPanel* BedShapePanel::init_model_panel()
update_shape();
};
Line line{ "", "" };
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
wxButton* load_btn = new wxButton(parent, wxID_ANY, _L("Load..."));
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Disabled), std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
StateColor btn_bd_white(std::pair<wxColour, int>(*wxWHITE, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
Button* load_btn = new Button(parent, _L("Load..."));
load_btn->SetBackgroundColor(btn_bg_white);
load_btn->SetBorderColor(btn_bd_white);
load_btn->SetBackgroundColour(*wxWHITE);
wxSizer* load_sizer = new wxBoxSizer(wxHORIZONTAL);
load_sizer->Add(load_btn, 1, wxEXPAND);
@ -360,10 +387,16 @@ wxPanel* BedShapePanel::init_model_panel()
wxSizer* filename_sizer = new wxBoxSizer(wxHORIZONTAL);
filename_sizer->Add(filename_lbl, 1, wxEXPAND);
wxButton* remove_btn = new wxButton(parent, wxID_ANY, _L("Remove"));
Button* remove_btn = new Button(parent, _L("Remove"));
remove_btn->SetBackgroundColor(btn_bg_white);
remove_btn->SetBorderColor(btn_bd_white);
remove_btn->SetBackgroundColour(*wxWHITE);
wxSizer* remove_sizer = new wxBoxSizer(wxHORIZONTAL);
remove_sizer->Add(remove_btn, 1, wxEXPAND);
wxGetApp().UpdateDarkUI(load_btn);
wxGetApp().UpdateDarkUI(remove_btn);
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(filename_sizer, 1, wxEXPAND);
sizer->Add(load_sizer, 1, wxEXPAND);

View file

@ -37,7 +37,9 @@ namespace GUI {
wxBoxSizer *m_sizere_left_h = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizere_left_v= new wxBoxSizer(wxVERTICAL);
auto m_printer_img = new wxStaticBitmap(m_panel_left, wxID_ANY, create_scaled_bitmap("printer_thumbnail", nullptr, 96), wxDefaultPosition, wxSize(FromDIP(100), FromDIP(96)), 0);
m_printer_img = new wxStaticBitmap(m_panel_left, wxID_ANY, create_scaled_bitmap("printer_thumbnail", nullptr, FromDIP(100)), wxDefaultPosition, wxSize(FromDIP(120), FromDIP(120)), 0);
m_printer_img->SetBackgroundColour(BIND_DIALOG_GREY200);
m_printer_img->Hide();
m_printer_name = new wxStaticText(m_panel_left, wxID_ANY, wxEmptyString);
m_printer_name->SetBackgroundColour(BIND_DIALOG_GREY200);
m_printer_name->SetFont(::Label::Head_14);
@ -133,7 +135,7 @@ namespace GUI {
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_bind->SetBackgroundColor(btn_bg_green);
m_button_bind->SetBorderColor(wxColour(0, 174, 66));
m_button_bind->SetTextColor(*wxWHITE);
m_button_bind->SetTextColor(wxColour("#FFFFFE"));
m_button_bind->SetSize(BIND_DIALOG_BUTTON_SIZE);
m_button_bind->SetMinSize(BIND_DIALOG_BUTTON_SIZE);
m_button_bind->SetCornerRadius(FromDIP(12));
@ -182,6 +184,8 @@ namespace GUI {
this->Connect(EVT_BIND_MACHINE_SUCCESS, wxCommandEventHandler(BindMachineDialog::on_bind_success), NULL, this);
this->Connect(EVT_BIND_UPDATE_MESSAGE, wxCommandEventHandler(BindMachineDialog::on_update_message), NULL, this);
m_simplebook->SetSelection(1);
wxGetApp().UpdateDlgDarkUI(this);
}
BindMachineDialog::~BindMachineDialog()
@ -271,9 +275,18 @@ void BindMachineDialog::on_dpi_changed(const wxRect &suggested_rect)
void BindMachineDialog::on_show(wxShowEvent &event)
{
//m_printer_name->SetLabelText(m_machine_info->get_printer_type_string());
m_printer_name->SetLabelText(from_u8(m_machine_info->dev_name));
Layout();
if (event.IsShown()) {
auto img = m_machine_info->get_printer_thumbnail_img_str();
if (wxGetApp().dark_mode()) { img += "_dark"; }
auto bitmap = create_scaled_bitmap(img, this, FromDIP(100));
m_printer_img->SetBitmap(bitmap);
m_printer_img->Refresh();
m_printer_img->Show();
m_printer_name->SetLabelText(from_u8(m_machine_info->dev_name));
Layout();
event.Skip();
}
}
@ -299,8 +312,9 @@ UnBindMachineDialog::UnBindMachineDialog(Plater *plater /*= nullptr*/)
wxBoxSizer *m_sizere_left_h = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizere_left_v= new wxBoxSizer(wxVERTICAL);
auto m_printer_img = new wxStaticBitmap(m_panel_left, wxID_ANY, create_scaled_bitmap("printer_thumbnail", nullptr, 96), wxDefaultPosition, wxSize(FromDIP(100), FromDIP(96)),
0);
m_printer_img = new wxStaticBitmap(m_panel_left, wxID_ANY, create_scaled_bitmap("printer_thumbnail", nullptr, FromDIP(100)), wxDefaultPosition, wxSize(FromDIP(120), FromDIP(120)), 0);
m_printer_img->SetBackgroundColour(BIND_DIALOG_GREY200);
m_printer_img->Hide();
m_printer_name = new wxStaticText(m_panel_left, wxID_ANY, wxEmptyString);
m_printer_name->SetFont(::Label::Head_14);
m_printer_name->SetBackgroundColour(BIND_DIALOG_GREY200);
@ -392,7 +406,7 @@ UnBindMachineDialog::UnBindMachineDialog(Plater *plater /*= nullptr*/)
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_unbind->SetBackgroundColor(btn_bg_green);
m_button_unbind->SetBorderColor(wxColour(0, 174, 66));
m_button_unbind->SetTextColor(*wxWHITE);
m_button_unbind->SetTextColor(wxColour("#FFFFFE"));
m_button_unbind->SetSize(BIND_DIALOG_BUTTON_SIZE);
m_button_unbind->SetMinSize(BIND_DIALOG_BUTTON_SIZE);
m_button_unbind->SetCornerRadius(FromDIP(12));
@ -426,6 +440,7 @@ UnBindMachineDialog::UnBindMachineDialog(Plater *plater /*= nullptr*/)
Bind(wxEVT_SHOW, &UnBindMachineDialog::on_show, this);
m_button_unbind->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDialog::on_unbind_printer), NULL, this);
m_button_cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDialog::on_cancel), NULL, this);
wxGetApp().UpdateDlgDarkUI(this);
}
UnBindMachineDialog::~UnBindMachineDialog()
@ -484,9 +499,18 @@ void UnBindMachineDialog::on_unbind_printer(wxCommandEvent &event)
void UnBindMachineDialog::on_show(wxShowEvent &event)
{
//m_printer_name->SetLabelText(m_machine_info->get_printer_type_string());
m_printer_name->SetLabelText(from_u8(m_machine_info->dev_name));
Layout();
if (event.IsShown()) {
auto img = m_machine_info->get_printer_thumbnail_img_str();
if (wxGetApp().dark_mode()) { img += "_dark"; }
auto bitmap = create_scaled_bitmap(img, this, FromDIP(100));
m_printer_img->SetBitmap(bitmap);
m_printer_img->Refresh();
m_printer_img->Show();
m_printer_name->SetLabelText(from_u8(m_machine_info->dev_name));
Layout();
event.Skip();
}
}
}} // namespace Slic3r::GUI

View file

@ -55,6 +55,7 @@ private:
Button * m_button_cancel;
wxSimplebook *m_simplebook;
wxStaticBitmap *m_avatar;
wxStaticBitmap *m_printer_img;
wxWebRequest web_request;
MachineObject * m_machine_info{nullptr};
@ -86,6 +87,7 @@ protected:
Button * m_button_cancel;
MachineObject *m_machine_info{nullptr};
wxStaticBitmap *m_avatar;
wxStaticBitmap *m_printer_img;
public:
UnBindMachineDialog(Plater *plater = nullptr);

View file

@ -316,18 +316,34 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_
+ (grayscale ? "-gs" : "")
+ new_color;
auto it = m_map.find(bitmap_key);
/*auto it = m_map.find(bitmap_key);
if (it != m_map.end())
return it->second;
return it->second;*/
// map of color replaces
std::map<std::string, std::string> replaces;
if (dark_mode)
replaces["\"#808080\""] = "\"#FFFFFF\"";
if (!new_color.empty())
replaces["\"#ED6B21\""] = "\"" + new_color + "\"";
if (dark_mode) {
replaces["\"#262E30\""] = "\"#EFEFF0\"";
replaces["\"#323A3D\""] = "\"#B3B3B5\"";
replaces["\"#808080\""] = "\"#818183\"";
//replaces["\"#ACACAC\""] = "\"#54545A\"";
replaces["\"#CECECE\""] = "\"#54545B\"";
replaces["\"#6B6B6B\""] = "\"#818182\"";
replaces["\"#909090\""] = "\"#FFFFFF\"";
replaces["\"#00FF00\""] = "\"#FF0000\"";
}
//if (!new_color.empty())
// replaces["\"#ED6B21\""] = "\"" + new_color + "\"";
NSVGimage *image = nullptr;
if (strstr(bitmap_name.c_str(), "printer_thumbnail") == NULL) {
image = nsvgParseFromFileWithReplace(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f, replaces);
}
else {
std::map<std::string, std::string> temp_replaces;
image = nsvgParseFromFileWithReplace(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f, temp_replaces);
}
NSVGimage *image = nsvgParseFromFileWithReplace(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f, replaces);
if (image == nullptr)
return nullptr;

View file

@ -17,13 +17,13 @@
#include <wx/listbook.h>
#include <wx/window.h>
#ifdef _WIN32
#ifdef __WINDOWS__
#include <wx/msw/dcclient.h>
#include <wx/msw/private.h>
#ifdef _MSW_DARK_MODE
#include <wx/msw/dark_mode.h>
#include "dark_mode.hpp"
#endif //_MSW_DARK_MODE
#endif
#endif //__WINDOWS__
#include "libslic3r/libslic3r.h"
#include "libslic3r/PrintConfig.hpp"
@ -254,11 +254,11 @@ void BitmapComboBox::DrawBackground_(wxDC& dc, const wxRect& rect, int WXUNUSED(
dc.SetTextForeground(flags & ODCB_PAINTING_DISABLED ? wxColour(108,108,108) : wxGetApp().get_label_clr_default());
wxColour selCol = flags & ODCB_PAINTING_DISABLED ?
#ifdef _MSW_DARK_MODE
wxRGBToColour(NppDarkMode::GetSofterBackgroundColor()) :
#else
//#ifdef _MSW_DARK_MODE
//wxRGBToColour(NppDarkMode::GetSofterBackgroundColor()) :
//#else
wxGetApp().get_highlight_default_clr() :
#endif
//#endif
wxGetApp().get_window_default_clr();
dc.SetPen(selCol);
dc.SetBrush(selCol);

View file

@ -11,6 +11,9 @@
#include "Widgets/RoundedRectangle.hpp"
#include "Widgets/StaticBox.hpp"
static wxColour FG_COLOR = wxColour(0x32, 0x3A, 0x3D);
static wxColour BG_COLOR = wxColour(0xF8, 0xF8, 0xF8);
namespace Slic3r { namespace GUI {
CalibrationDialog::CalibrationDialog(Plater *plater)
@ -31,17 +34,39 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
body_panel->SetBackgroundColour(*wxWHITE);
auto cali_left_panel = new StaticBox(body_panel, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(303), FromDIP(243)));
cali_left_panel->SetBackgroundColor(wxColour(0xF8, 0xF8, 0xF8));
cali_left_panel->SetBorderColor(wxColour(0xF8, 0xF8, 0xF8));
cali_left_panel->SetBackgroundColor(BG_COLOR);
cali_left_panel->SetBorderColor(BG_COLOR);
wxBoxSizer *cali_left_sizer = new wxBoxSizer(wxVERTICAL);
cali_left_sizer->Add(0, 0, 0, wxTOP, FromDIP(25));
// calibration step selection
auto cali_step_select_title = new wxStaticText(cali_left_panel, wxID_ANY, _L("Calibration step selection"), wxDefaultPosition, wxDefaultSize, 0);
cali_step_select_title->SetFont(::Label::Head_14);
cali_step_select_title->Wrap(-1);
cali_step_select_title->SetForegroundColour(FG_COLOR);
cali_step_select_title->SetBackgroundColour(BG_COLOR);
cali_left_sizer->Add(cali_step_select_title, 0, wxLEFT, FromDIP(15));
select_xcam_cali = create_check_option(_L("Micro lidar calibration"), cali_left_panel, _L("Micro lidar calibration"), "xcam_cali");
select_bed_leveling = create_check_option(_L("Bed leveling"), cali_left_panel, _L("Bed leveling"), "bed_leveling");
select_vibration = create_check_option(_L("Resonance frequency identification"), cali_left_panel, _L("Resonance frequency identification"), "vibration");
m_checkbox_list["xcam_cali"]->SetValue(true);
m_checkbox_list["bed_leveling"]->SetValue(true);
m_checkbox_list["vibration"]->SetValue(true);
cali_left_sizer->Add(0, FromDIP(18), 0, wxEXPAND, 0);
cali_left_sizer->Add(select_xcam_cali, 0, wxLEFT, FromDIP(15));
cali_left_sizer->Add(select_bed_leveling, 0, wxLEFT, FromDIP(15));
cali_left_sizer->Add(select_vibration, 0, wxLEFT, FromDIP(15));
cali_left_sizer->Add(0, FromDIP(30), 0, wxEXPAND, 0);
auto cali_left_text_top = new wxStaticText(cali_left_panel, wxID_ANY, _L("Calibration program"), wxDefaultPosition, wxDefaultSize, 0);
cali_left_text_top->SetFont(::Label::Head_14);
cali_left_text_top->Wrap(-1);
cali_left_text_top->SetForegroundColour(wxColour(0x32, 0x3A, 0x3D));
cali_left_text_top->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
cali_left_text_top->SetForegroundColour(FG_COLOR);
cali_left_text_top->SetBackgroundColour(BG_COLOR);
cali_left_sizer->Add(cali_left_text_top, 0, wxLEFT, FromDIP(15));
@ -53,7 +78,7 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
wxDefaultPosition, wxSize(FromDIP(260), -1), 0);
cali_left_text_body->Wrap(FromDIP(260));
cali_left_text_body->SetForegroundColour(wxColour(0x6B, 0x6B, 0x6B));
cali_left_text_body->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
cali_left_text_body->SetBackgroundColour(BG_COLOR);
cali_left_text_body->SetFont(::Label::Body_13);
cali_left_sizer->Add(cali_left_text_body, 0, wxLEFT, FromDIP(15));
@ -86,25 +111,25 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
wxBoxSizer *cali_right_sizer_v = new wxBoxSizer(wxVERTICAL);
auto cali_right_panel = new StaticBox(body_panel, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(182), FromDIP(160)));
cali_right_panel->SetBackgroundColor(wxColour(0xF8, 0xF8, 0xF8));
cali_right_panel->SetBorderColor(wxColour(0xF8, 0xF8, 0xF8));
cali_right_panel->SetBackgroundColor(BG_COLOR);
cali_right_panel->SetBorderColor(BG_COLOR);
auto cali_text_right_top = new wxStaticText(cali_right_panel, wxID_ANY, _L("Calibration Flow"), wxDefaultPosition, wxDefaultSize, 0);
cali_text_right_top->Wrap(-1);
cali_text_right_top->SetFont(::Label::Head_14);
cali_text_right_top->SetForegroundColour(wxColour(0x00, 0xAE, 0x42));
cali_text_right_top->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
cali_text_right_top->SetBackgroundColour(BG_COLOR);
auto staticline = new ::StaticLine(cali_right_panel);
staticline->SetLineColour(wxColour(0x00, 0xAE, 0x42));
auto calibration_panel = new wxPanel(cali_right_panel);
calibration_panel->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
calibration_panel->SetBackgroundColour(BG_COLOR);
auto calibration_sizer = new wxBoxSizer(wxVERTICAL);
calibration_panel->SetMinSize(wxSize(FromDIP(170), FromDIP(160)));
calibration_panel->SetSize(wxSize(FromDIP(170), FromDIP(160)));
m_calibration_flow = new StepIndicator(calibration_panel, wxID_ANY);
StateColor bg_color(std::pair<wxColour, int>(wxColour(248, 248, 248), StateColor::Normal));
StateColor bg_color(std::pair<wxColour, int>(BG_COLOR, StateColor::Normal));
m_calibration_flow->SetBackgroundColor(bg_color);
m_calibration_flow->SetFont(Label::Body_12);
@ -122,7 +147,7 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
m_calibration_btn = new Button(cali_right_panel, _L("Start Calibration"));
m_calibration_btn->SetBackgroundColor(btn_bg_green);
m_calibration_btn->SetBorderColor(btn_bd_green);
m_calibration_btn->SetTextColor(*wxWHITE);
m_calibration_btn->SetTextColor(wxColour("#FFFFFE"));
m_calibration_btn->SetSize(wxSize(FromDIP(128), FromDIP(26)));
m_calibration_btn->SetMinSize(wxSize(FromDIP(128), FromDIP(26)));
@ -149,15 +174,55 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
Fit();
m_calibration_btn->Bind(wxEVT_LEFT_DOWN, &CalibrationDialog::on_start_calibration, this);
wxGetApp().UpdateDlgDarkUI(this);
}
CalibrationDialog::~CalibrationDialog() {}
void CalibrationDialog::on_dpi_changed(const wxRect &suggested_rect) {}
wxWindow* CalibrationDialog::create_check_option(wxString title, wxWindow* parent, wxString tooltip, std::string param)
{
auto checkbox = new wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
checkbox->SetBackgroundColour(BG_COLOR);
wxBoxSizer* sizer_checkbox = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer_check = new wxBoxSizer(wxVERTICAL);
auto check = new ::CheckBox(checkbox);
sizer_check->Add(check, 0, wxBOTTOM | wxEXPAND | wxTOP, FromDIP(5));
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, wxST_ELLIPSIZE_END);
text->SetFont(::Label::Body_13);
text->SetForegroundColour(wxColour(107, 107, 107));
text->Wrap(-1);
sizer_checkbox->Add(text, 0, wxBOTTOM | wxEXPAND | wxTOP, FromDIP(5));
checkbox->SetSizer(sizer_checkbox);
checkbox->Layout();
sizer_checkbox->Fit(checkbox);
checkbox->SetToolTip(tooltip);
text->SetToolTip(tooltip);
text->Bind(wxEVT_LEFT_DOWN, [this, check](wxMouseEvent&) { check->SetValue(check->GetValue() ? false : true); });
m_checkbox_list[param] = check;
return checkbox;
}
void CalibrationDialog::update_cali(MachineObject *obj)
{
if (!obj) return;
if (obj->is_function_supported(PrinterFunction::FUNC_AI_MONITORING)) {
select_xcam_cali->Show();
} else {
select_xcam_cali->Hide();
}
if (obj->is_calibration_running() || obj->is_calibration_done()) {
if (obj->is_calibration_done()) {
m_calibration_btn->Enable();
@ -218,7 +283,11 @@ void CalibrationDialog::on_start_calibration(wxMouseEvent &event)
Close();
} else {
BOOST_LOG_TRIVIAL(info) << "on_start_calibration";
m_obj->command_start_calibration();
m_obj->command_start_calibration(
m_checkbox_list["vibration"]->GetValue(),
m_checkbox_list["bed_leveling"]->GetValue(),
m_checkbox_list["xcam_cali"]->GetValue()
);
}
}
}

View file

@ -30,11 +30,21 @@
#include "Widgets/Label.hpp"
#include "Widgets/Button.hpp"
#include "Widgets/StepCtrl.hpp"
#include "Widgets/CheckBox.hpp"
namespace Slic3r { namespace GUI {
class CalibrationDialog : public DPIDialog
{
private:
std::map<std::string, ::CheckBox*> m_checkbox_list;
wxWindow* select_xcam_cali { nullptr };
wxWindow* select_bed_leveling { nullptr };
wxWindow* select_vibration { nullptr };
wxWindow* create_check_option(wxString title, wxWindow *parent, wxString tooltip, std::string param);
public:
CalibrationDialog(Plater *plater = nullptr);
~CalibrationDialog();

View file

@ -7,6 +7,7 @@
#include <wx/progdlg.h>
#include <wx/clipbrd.h>
#include <wx/dcgraph.h>
#include "GUI_App.hpp"
namespace Slic3r {
namespace GUI {
@ -20,9 +21,10 @@ wxBEGIN_EVENT_TABLE(CameraPopup, wxPopupTransientWindow)
EVT_KILL_FOCUS(CameraPopup::OnKillFocus )
wxEND_EVENT_TABLE()
wxDEFINE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
wxDEFINE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
static const wxFont TEXT_FONT = Label::Body_14;
static wxColour TEXT_COL = wxColour(43, 52, 54);
const wxColour TEXT_COL = wxColour(43, 52, 54);
CameraPopup::CameraPopup(wxWindow *parent, MachineObject* obj)
: wxPopupTransientWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS),
@ -33,62 +35,106 @@ CameraPopup::CameraPopup(wxWindow *parent, MachineObject* obj)
#endif
m_panel = new wxScrolledWindow(this, wxID_ANY);
m_panel->SetBackgroundColour(*wxWHITE);
m_panel->SetMinSize(wxSize(FromDIP(180),-1));
m_panel->Bind(wxEVT_MOTION, &CameraPopup::OnMouse, this);
wxBoxSizer * main_sizer = new wxBoxSizer(wxHORIZONTAL);
wxFlexGridSizer* top_sizer = new wxFlexGridSizer(0, 2, 0, 0);
main_sizer = new wxBoxSizer(wxVERTICAL);
wxFlexGridSizer* top_sizer = new wxFlexGridSizer(0, 2, 0, FromDIP(50));
top_sizer->AddGrowableCol(0);
top_sizer->SetFlexibleDirection(wxBOTH);
top_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
m_text_timelapse = new wxStaticText(m_panel, wxID_ANY, _L("Timelapse"));
m_text_timelapse->Wrap(-1);
m_text_timelapse->SetFont(TEXT_FONT);
m_text_timelapse->SetForegroundColour(TEXT_COL);
m_switch_timelapse = new SwitchButton(m_panel);
if (obj)
m_switch_timelapse->SetValue(obj->camera_timelapse);
m_text_recording = new wxStaticText(m_panel, wxID_ANY, _L("Monitoring Recording"));
//recording
m_text_recording = new wxStaticText(m_panel, wxID_ANY, _L("Auto-record Monitoring"));
m_text_recording->Wrap(-1);
m_text_recording->SetFont(TEXT_FONT);
m_text_recording->SetFont(Label::Head_14);
m_text_recording->SetForegroundColour(TEXT_COL);
m_switch_recording = new SwitchButton(m_panel);
if (obj)
m_switch_recording->SetValue(obj->camera_recording);
m_switch_recording->SetValue(obj->camera_recording_when_printing);
//vcamera
m_text_vcamera = new wxStaticText(m_panel, wxID_ANY, _L("Go Live"));
m_text_vcamera->Wrap(-1);
m_text_vcamera->SetFont(Label::Head_14);
m_text_vcamera->SetForegroundColour(TEXT_COL);
m_switch_vcamera = new SwitchButton(m_panel);
top_sizer->Add(m_text_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
top_sizer->Add(m_text_vcamera, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_vcamera, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
//resolution
m_text_resolution = new wxStaticText(m_panel, wxID_ANY, _L("Resolution"));
m_text_resolution->Wrap(-1);
m_text_resolution->SetFont(Label::Head_14);
m_text_resolution->SetForegroundColour(TEXT_COL);
top_sizer->Add(m_text_resolution, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(0, 0, wxALL, 0);
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i)
{
m_resolution_options[i] = create_item_radiobox(to_resolution_label_string(CameraResolution(i)), m_panel, wxEmptyString, FromDIP(10));
top_sizer->Add(m_resolution_options[i], 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(0, 0, wxALL, 0);
}
if (obj)
sync_resolution_setting(obj->camera_resolution);
top_sizer->Add(m_text_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
top_sizer->Add(m_text_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
top_sizer->Add(m_switch_recording, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
main_sizer->Add(top_sizer, 0, wxALL, FromDIP(10));
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/virtual-camera", L"en");
vcamera_guide_link = new wxHyperlinkCtrl(m_panel, wxID_ANY, _L("Show \"Live Video\" guide page."),
url, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
vcamera_guide_link->Hide();
main_sizer->Add(vcamera_guide_link, 0, wxALL, FromDIP(15));
m_panel->SetSizer(main_sizer);
m_panel->Layout();
main_sizer->Fit(m_panel);
SetClientSize(m_panel->GetSize());
m_switch_timelapse->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(CameraPopup::on_switch_timelapse), NULL, this);
m_switch_recording->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(CameraPopup::on_switch_recording), NULL, this);
m_switch_vcamera->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
wxMouseEvent evt(EVT_VCAMERA_SWITCH);
evt.SetEventObject(this);
GetEventHandler()->ProcessEvent(evt);
});
#ifdef __APPLE__
m_panel->Bind(wxEVT_LEFT_UP, &CameraPopup::OnLeftUp, this);
#endif //APPLE
check_func_supported();
wxGetApp().UpdateDarkUIWin(this);
}
void CameraPopup::on_switch_timelapse(wxCommandEvent& event)
void CameraPopup::sdcard_absent_hint()
{
if (!m_obj) return;
bool value = m_switch_timelapse->GetValue();
m_switch_timelapse->SetValue(!value);
m_obj->command_ipcam_timelapse(!value);
wxCommandEvent evt(EVT_SDCARD_ABSENT_HINT);
evt.SetEventObject(this);
GetEventHandler()->ProcessEvent(evt);
}
void CameraPopup::on_switch_recording(wxCommandEvent& event)
{
if (!m_obj) return;
if (m_obj->sdcard_state != MachineObject::SdcardState::HAS_SDCARD_NORMAL) {
sdcard_absent_hint();
return;
}
bool value = m_switch_recording->GetValue();
m_switch_recording->SetValue(!value);
m_obj->command_ipcam_record(!value);
}
void CameraPopup::on_set_resolution()
{
if (!m_obj) return;
m_obj->command_ipcam_resolution_set(to_resolution_msg_string(curr_sel_resolution));
}
void CameraPopup::Popup(wxWindow *WXUNUSED(focus))
{
wxPoint curr_position = this->GetPosition();
@ -98,6 +144,222 @@ void CameraPopup::Popup(wxWindow *WXUNUSED(focus))
wxPopupTransientWindow::Popup();
}
wxWindow* CameraPopup::create_item_radiobox(wxString title, wxWindow* parent, wxString tooltip, int padding_left)
{
wxWindow *item = new wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(20)));
item->SetBackgroundColour(*wxWHITE);
RadioBox *radiobox = new RadioBox(item);
radiobox->SetPosition(wxPoint(padding_left, (item->GetSize().GetHeight() - radiobox->GetSize().GetHeight()) / 2));
resolution_rbtns.push_back(radiobox);
int btn_idx = resolution_rbtns.size() - 1;
radiobox->Bind(wxEVT_LEFT_DOWN, [this, btn_idx](wxMouseEvent &e) {
if (m_obj && allow_alter_resolution) {
select_curr_radiobox(btn_idx);
on_set_resolution();
}
});
wxStaticText *text = new wxStaticText(item, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
resolution_texts.push_back(text);
text->SetPosition(wxPoint(padding_left + radiobox->GetSize().GetWidth() + 10, (item->GetSize().GetHeight() - text->GetSize().GetHeight()) / 2));
text->SetFont(Label::Body_13);
text->SetForegroundColour(0x6B6B6B);
text->Bind(wxEVT_LEFT_DOWN, [this, btn_idx](wxMouseEvent &e) {
if (m_obj && allow_alter_resolution) {
select_curr_radiobox(btn_idx);
on_set_resolution();
}
});
radiobox->SetToolTip(tooltip);
text->SetToolTip(tooltip);
return item;
}
void CameraPopup::select_curr_radiobox(int btn_idx)
{
if (!m_obj) return;
int len = resolution_rbtns.size();
for (int i = 0; i < len; ++i) {
if (i == btn_idx) {
curr_sel_resolution = CameraResolution(i);
resolution_rbtns[i]->SetValue(true);
}
else {
resolution_rbtns[i]->SetValue(false);
}
}
}
void CameraPopup::sync_resolution_setting(std::string resolution)
{
if (resolution == "") {
reset_resolution_setting();
return;
}
int res = 0;
for (CameraResolution i = RESOLUTION_720P; i < RESOLUTION_OPTIONS_NUM; i = CameraResolution(i+1)){
if (resolution == to_resolution_msg_string(i)) {
res = int(i);
break;
}
}
select_curr_radiobox(res);
}
void CameraPopup::reset_resolution_setting()
{
int len = resolution_rbtns.size();
for (int i = 0; i < len; ++i) {
resolution_rbtns[i]->SetValue(false);
}
curr_sel_resolution = RESOLUTION_OPTIONS_NUM;
}
void CameraPopup::sync_vcamera_state(bool show_vcamera)
{
is_vcamera_show = show_vcamera;
if (is_vcamera_show) {
m_switch_vcamera->SetValue(true);
vcamera_guide_link->Show();
}
else {
m_switch_vcamera->SetValue(false);
vcamera_guide_link->Hide();
}
rescale();
}
void CameraPopup::check_func_supported()
{
// function supported
if (m_obj->is_function_supported(PrinterFunction::FUNC_RECORDING) && m_obj->has_ipcam) {
m_text_recording->Show();
m_switch_recording->Show();
} else {
m_text_recording->Hide();
m_switch_recording->Hide();
}
if (m_obj->is_function_supported(PrinterFunction::FUNC_VIRTUAL_CAMERA) && m_obj->has_ipcam) {
m_text_vcamera->Show();
m_switch_vcamera->Show();
if (is_vcamera_show)
vcamera_guide_link->Show();
} else {
m_text_vcamera->Hide();
m_switch_vcamera->Hide();
vcamera_guide_link->Hide();
}
allow_alter_resolution = (m_obj->is_function_supported(PrinterFunction::FUNC_ALTER_RESOLUTION) && m_obj->has_ipcam);
//resolution supported
std::vector<std::string> resolution_supported = m_obj->get_resolution_supported();
auto support_count = resolution_supported.size();
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i){
auto curr_res = to_resolution_msg_string(CameraResolution(i));
std::vector <std::string> ::iterator it = std::find(resolution_supported.begin(), resolution_supported.end(), curr_res);
if ((it == resolution_supported.end())||(support_count <= 1))
m_resolution_options[i] -> Hide();
}
//hide resolution if there is only one choice
if (support_count <= 1) {
m_text_resolution->Hide();
}
}
void CameraPopup::update(bool vcamera_streaming)
{
if (!m_obj) return;
m_switch_recording->SetValue(m_obj->camera_recording_when_printing);
sync_resolution_setting(m_obj->camera_resolution);
sync_vcamera_state(vcamera_streaming);
rescale();
}
wxString CameraPopup::to_resolution_label_string(CameraResolution resolution) {
switch (resolution) {
case RESOLUTION_720P:
return _L("720p");
case RESOLUTION_1080P:
return _L("1080p");
default:
return "";
}
return "";
}
std::string CameraPopup::to_resolution_msg_string(CameraResolution resolution) {
switch (resolution) {
case RESOLUTION_720P:
return std::string("720p");
case RESOLUTION_1080P:
return std::string("1080p");
default:
return "";
}
return "";
}
void CameraPopup::rescale()
{
m_panel->Layout();
main_sizer->Fit(m_panel);
SetClientSize(m_panel->GetSize());
wxPopupTransientWindow::Update();
}
void CameraPopup::OnLeftUp(wxMouseEvent &event)
{
auto mouse_pos = ClientToScreen(event.GetPosition());
auto wxscroll_win_pos = m_panel->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > wxscroll_win_pos.x && mouse_pos.y > wxscroll_win_pos.y && mouse_pos.x < (wxscroll_win_pos.x + m_panel->GetSize().x) && mouse_pos.y < (wxscroll_win_pos.y + m_panel->GetSize().y)) {
//recording
auto recording_rect = m_switch_recording->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > recording_rect.x && mouse_pos.y > recording_rect.y && mouse_pos.x < (recording_rect.x + m_switch_recording->GetSize().x) && mouse_pos.y < (recording_rect.y + m_switch_recording->GetSize().y)) {
wxMouseEvent recording_evt(wxEVT_LEFT_DOWN);
m_switch_recording->GetEventHandler()->ProcessEvent(recording_evt);
return;
}
//vcamera
auto vcamera_rect = m_switch_vcamera->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > vcamera_rect.x && mouse_pos.y > vcamera_rect.y && mouse_pos.x < (vcamera_rect.x + m_switch_vcamera->GetSize().x) && mouse_pos.y < (vcamera_rect.y + m_switch_vcamera->GetSize().y)) {
wxMouseEvent vcamera_evt(wxEVT_LEFT_DOWN);
m_switch_vcamera->GetEventHandler()->ProcessEvent(vcamera_evt);
return;
}
//resolution
for (int i = 0; i < (int)RESOLUTION_OPTIONS_NUM; ++i){
auto resolution_rbtn = resolution_rbtns[i];
auto rbtn_rect = resolution_rbtn->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > rbtn_rect.x && mouse_pos.y > rbtn_rect.y && mouse_pos.x < (rbtn_rect.x + resolution_rbtn->GetSize().x) && mouse_pos.y < (rbtn_rect.y + resolution_rbtn->GetSize().y)) {
wxMouseEvent resolution_evt(wxEVT_LEFT_DOWN);
resolution_rbtn->GetEventHandler()->ProcessEvent(resolution_evt);
return;
}
auto resolution_txt = resolution_texts[i];
auto txt_rect = resolution_txt->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > txt_rect.x && mouse_pos.y > txt_rect.y && mouse_pos.x < (txt_rect.x + resolution_txt->GetSize().x) && mouse_pos.y < (txt_rect.y + resolution_txt->GetSize().y)) {
wxMouseEvent resolution_evt(wxEVT_LEFT_DOWN);
resolution_txt->GetEventHandler()->ProcessEvent(resolution_evt);
return;
}
}
//hyper link
auto h_rect = vcamera_guide_link->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > h_rect.x && mouse_pos.y > h_rect.y && mouse_pos.x < (h_rect.x + vcamera_guide_link->GetSize().x) && mouse_pos.y < (h_rect.y + vcamera_guide_link->GetSize().y)) {
auto url = wxString::Format(L"https://wiki.bambulab.com/%s/software/bambu-studio/virtual-camera", L"en");
wxLaunchDefaultBrowser(url);
}
}
}
void CameraPopup::OnDismiss() {
wxPopupTransientWindow::OnDismiss();
}
@ -106,6 +368,7 @@ bool CameraPopup::ProcessLeftDown(wxMouseEvent &event)
{
return wxPopupTransientWindow::ProcessLeftDown(event);
}
bool CameraPopup::Show(bool show)
{
return wxPopupTransientWindow::Show(show);
@ -131,18 +394,15 @@ void CameraPopup::OnMouse(wxMouseEvent &event)
event.Skip();
}
CameraItem::CameraItem(wxWindow *parent,std::string off_normal, std::string on_normal, std::string off_hover, std::string on_hover)
CameraItem::CameraItem(wxWindow *parent, std::string normal, std::string hover)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
{
#ifdef __WINDOWS__
SetDoubleBuffered(true);
#endif //__WINDOWS__
m_bitmap_on_normal = ScalableBitmap(this, on_normal, 20);
m_bitmap_off_normal = ScalableBitmap(this, off_normal, 20);
m_bitmap_on_hover = ScalableBitmap(this, on_hover, 20);
m_bitmap_off_hover = ScalableBitmap(this, off_hover, 20);
m_bitmap_normal = ScalableBitmap(this, normal, 20);
m_bitmap_hover = ScalableBitmap(this, hover, 20);
SetSize(wxSize(FromDIP(20), FromDIP(20)));
SetMinSize(wxSize(FromDIP(20), FromDIP(20)));
@ -154,12 +414,9 @@ CameraItem::CameraItem(wxWindow *parent,std::string off_normal, std::string on_n
CameraItem::~CameraItem() {}
void CameraItem::msw_rescale() {}
void CameraItem::set_switch(bool is_on)
{
m_on = is_on;
Refresh();
void CameraItem::msw_rescale() {
m_bitmap_normal.msw_rescale();
m_bitmap_hover.msw_rescale();
}
void CameraItem::on_enter_win(wxMouseEvent &evt)
@ -206,20 +463,12 @@ void CameraItem::render(wxDC &dc)
void CameraItem::doRender(wxDC &dc)
{
if (m_on) {
if (m_hover) {
dc.DrawBitmap(m_bitmap_on_hover.bmp(), wxPoint((GetSize().x - m_bitmap_on_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_on_hover.GetBmpSize().y) / 2));
} else {
dc.DrawBitmap(m_bitmap_on_normal.bmp(), wxPoint((GetSize().x - m_bitmap_on_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_on_normal.GetBmpSize().y) / 2));
}
if (m_hover) {
dc.DrawBitmap(m_bitmap_hover.bmp(), wxPoint((GetSize().x - m_bitmap_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_hover.GetBmpSize().y) / 2));
} else {
if (m_hover) {
dc.DrawBitmap(m_bitmap_off_hover.bmp(), wxPoint((GetSize().x - m_bitmap_off_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_off_hover.GetBmpSize().y) / 2));
} else {
dc.DrawBitmap(m_bitmap_off_normal.bmp(), wxPoint((GetSize().x - m_bitmap_off_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_off_normal.GetBmpSize().y) / 2));
}
dc.DrawBitmap(m_bitmap_normal.bmp(), wxPoint((GetSize().x - m_bitmap_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_normal.GetBmpSize().y) / 2));
}
}
}
}

View file

@ -10,11 +10,16 @@
#include <wx/sizer.h>
#include <wx/gbsizer.h>
#include <wx/webrequest.h>
#include <wx/hyperlink.h>
#include "Widgets/SwitchButton.hpp"
#include "Widgets/RadioBox.hpp"
namespace Slic3r {
namespace GUI {
wxDECLARE_EVENT(EVT_VCAMERA_SWITCH, wxMouseEvent);
wxDECLARE_EVENT(EVT_SDCARD_ABSENT_HINT, wxCommandEvent);
class CameraPopup : public wxPopupTransientWindow
{
public:
@ -27,22 +32,53 @@ public:
virtual bool ProcessLeftDown(wxMouseEvent &event) wxOVERRIDE;
virtual bool Show(bool show = true) wxOVERRIDE;
void sync_vcamera_state(bool show_vcamera);
void check_func_supported();
void update(bool vcamera_streaming);
enum CameraResolution
{
RESOLUTION_720P = 0,
RESOLUTION_1080P = 1,
RESOLUTION_OPTIONS_NUM = 2
};
void rescale();
protected:
void on_switch_timelapse(wxCommandEvent& event);
void on_switch_recording(wxCommandEvent& event);
void on_set_resolution();
void sdcard_absent_hint();
wxWindow * create_item_radiobox(wxString title, wxWindow *parent, wxString tooltip, int padding_left);
void select_curr_radiobox(int btn_idx);
void sync_resolution_setting(std::string resolution);
void reset_resolution_setting();
wxString to_resolution_label_string(CameraResolution resolution);
std::string to_resolution_msg_string(CameraResolution resolution);
private:
MachineObject* m_obj { nullptr };
wxStaticText* m_text_recording;
SwitchButton* m_switch_recording;
wxStaticText* m_text_timelapse;
SwitchButton* m_switch_timelapse;
wxStaticText* m_text_vcamera;
SwitchButton* m_switch_vcamera;
wxStaticText* m_text_resolution;
wxWindow* m_resolution_options[RESOLUTION_OPTIONS_NUM];
wxScrolledWindow *m_panel;
wxBoxSizer* main_sizer;
std::vector<RadioBox*> resolution_rbtns;
std::vector<wxStaticText*> resolution_texts;
CameraResolution curr_sel_resolution = RESOLUTION_1080P;
wxHyperlinkCtrl* vcamera_guide_link { nullptr };
bool is_vcamera_show = false;
bool allow_alter_resolution = false;
void OnMouse(wxMouseEvent &event);
void OnSize(wxSizeEvent &event);
void OnSetFocus(wxFocusEvent &event);
void OnKillFocus(wxFocusEvent &event);
void OnLeftUp(wxMouseEvent& event);
private:
wxDECLARE_ABSTRACT_CLASS(CameraPopup);
@ -53,20 +89,15 @@ private:
class CameraItem : public wxPanel
{
public:
CameraItem(wxWindow *parent, std::string off_normal, std::string on_normal, std::string off_hover, std::string on_hover);
CameraItem(wxWindow *parent, std::string normal, std::string hover);
~CameraItem();
MachineObject *m_obj{nullptr};
bool m_on{false};
bool m_hover{false};
ScalableBitmap m_bitmap_on_normal;
ScalableBitmap m_bitmap_on_hover;
ScalableBitmap m_bitmap_off_normal;
ScalableBitmap m_bitmap_off_hover;
ScalableBitmap m_bitmap_normal;
ScalableBitmap m_bitmap_hover;
void msw_rescale();
void set_switch(bool is_on);
bool get_switch_status() { return m_on; };
void on_enter_win(wxMouseEvent &evt);
void on_level_win(wxMouseEvent &evt);
void paintEvent(wxPaintEvent &evt);

View file

@ -131,7 +131,8 @@ void ConfigManipulation::check_bed_temperature_difference(int bed_type, DynamicP
}
if (first_layer_bed_temp > vitrification || bed_temp > vitrification) {
const wxString msg_text = wxString::Format(_L("Bed temperature is higher than vitrification temperature of this filament.\nThis may cause nozzle blocked and printing failure\nPlease keep the printer open during the printing process to ensure air circulation or reduce the temperature of the hot bed"));
const wxString msg_text = wxString::Format(
_L("Bed temperature is higher than vitrification temperature of this filament.\nThis may cause nozzle blocked and printing failure\nPlease keep the printer open during the printing process to ensure air circulation or reduce the temperature of the hot bed"));
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
is_msg_dlg_already_exist = true;
dialog.ShowModal();
@ -141,6 +142,26 @@ void ConfigManipulation::check_bed_temperature_difference(int bed_type, DynamicP
}
}
void ConfigManipulation::check_filament_max_volumetric_speed(DynamicPrintConfig *config)
{
//if (is_msg_dlg_already_exist) return;
//float max_volumetric_speed = config->opt_float("filament_max_volumetric_speed");
float max_volumetric_speed = config->has("filament_max_volumetric_speed") ? config->opt_float("filament_max_volumetric_speed", (float) 0.5) : 0.5;
// BBS: limite the min max_volumetric_speed
if (max_volumetric_speed < 0.5) {
const wxString msg_text = _(L("Too small max volumetric speed.\nReset to 0.5"));
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
DynamicPrintConfig new_conf = *config;
is_msg_dlg_already_exist = true;
dialog.ShowModal();
new_conf.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats({0.5}));
apply(config, &new_conf);
is_msg_dlg_already_exist = false;
}
}
void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config)
{
// #ys_FIXME_to_delete
@ -255,6 +276,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
sparse_infill_density == 0 &&
! config->opt_bool("enable_support") &&
config->opt_int("enforce_support_layers") == 0 &&
config->opt_bool("ensure_vertical_shell_thickness") &&
! config->opt_bool("detect_thin_wall")))
{
wxString msg_text = _(L("Spiral mode only works when wall loops is 1, \n"
@ -275,6 +297,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
new_conf.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
new_conf.set_key_value("enable_support", new ConfigOptionBool(false));
new_conf.set_key_value("enforce_support_layers", new ConfigOptionInt(0));
new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(true));
new_conf.set_key_value("detect_thin_wall", new ConfigOptionBool(false));
sparse_infill_density = 0;
support = false;
@ -291,6 +314,37 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
is_msg_dlg_already_exist = false;
}
//BBS
if (config->opt_enum<PerimeterGeneratorType>("wall_generator") == PerimeterGeneratorType::Arachne &&
config->opt_bool("enable_overhang_speed"))
{
wxString msg_text = _(L("Arachne engine only works when overhang slowing down is disabled.\n"
"This may cause decline in the quality of overhang surface when print fastly\n"));
if (is_global_config)
msg_text += "\n" + _(L("Disable overhang slowing down automatically? \n"
"Yes - Enable arachne and disable overhang slowing down\n"
"No - Give up using arachne this time"));
MessageDialog dialog(m_msg_dlg_parent, msg_text, "",
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config;
is_msg_dlg_already_exist = true;
auto answer = dialog.ShowModal();
bool enable_overhang_slow_down = true;
if (!is_global_config || answer == wxID_YES) {
new_conf.set_key_value("enable_overhang_speed", new ConfigOptionBool(false));
enable_overhang_slow_down = false;
}
else {
new_conf.set_key_value("wall_generator", new ConfigOptionEnum<PerimeterGeneratorType>(PerimeterGeneratorType::Classic));
}
apply(config, &new_conf);
if (cb_value_change) {
if (!enable_overhang_slow_down)
cb_value_change("enable_overhang_speed", false);
}
is_msg_dlg_already_exist = false;
}
// BBS
int filament_cnt = wxGetApp().preset_bundle->filament_presets.size();
#if 0
@ -415,7 +469,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
if (opt != nullptr) {
if (opt->getInt() > filament_cnt) {
DynamicPrintConfig new_conf = *config;
new_conf.set_key_value(key, new ConfigOptionInt(filament_cnt));
new_conf.set_key_value(key, new ConfigOptionInt(0));
apply(config, &new_conf);
}
}
@ -425,7 +479,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
void ConfigManipulation::apply_null_fff_config(DynamicPrintConfig *config, std::vector<std::string> const &keys, std::map<ObjectBase *, ModelConfig *> const &configs)
{
for (auto &k : keys) {
if (k == "adaptive_layer_height" || k == "independent_support_layer_height" || k == "enable_support" || k == "detect_thin_wall")
if (/*k == "adaptive_layer_height" || */k == "independent_support_layer_height" || k == "enable_support" || k == "detect_thin_wall")
config->set_key_value(k, new ConfigOptionBool(true));
else if (k == "wall_loops")
config->set_key_value(k, new ConfigOptionInt(0));
@ -449,7 +503,7 @@ void ConfigManipulation::apply_null_fff_config(DynamicPrintConfig *config, std::
void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, const bool is_global_config)
{
bool have_perimeters = config->opt_int("wall_loops") > 0;
for (auto el : { "detect_thin_wall", "detect_overhang_wall",
for (auto el : { "ensure_vertical_shell_thickness", "detect_thin_wall", "detect_overhang_wall",
"seam_position", "wall_infill_order", "outer_wall_line_width",
"inner_wall_speed", "outer_wall_speed", "small_perimeter_speed", "small_perimeter_threshold" })
toggle_field(el, have_perimeters);
@ -511,9 +565,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
bool have_support_soluble = have_support_material && config->opt_float("support_top_z_distance") == 0;
auto support_style = config->opt_enum<SupportMaterialStyle>("support_style");
for (auto el : { "support_style", "support_base_pattern",
"support_base_pattern_spacing", "support_angle",
"support_base_pattern_spacing", "support_expansion", "support_angle",
"support_interface_pattern", "support_interface_top_layers", "support_interface_bottom_layers",
"bridge_no_support", "max_bridge_length", "support_top_z_distance",
"bridge_no_support", "max_bridge_length", "support_top_z_distance", "support_bottom_z_distance",
//BBS: add more support params to dependent of enable_support
"support_type", "support_on_build_plate_only", "support_critical_regions_only",
"support_object_xy_distance", "independent_support_layer_height"})
@ -521,7 +575,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
toggle_field("support_threshold_angle", have_support_material && (support_type == stNormalAuto || support_type == stTreeAuto || support_type==stHybridAuto));
//toggle_field("support_closing_radius", have_support_material && support_style == smsSnug);
for (auto el : {"tree_support_branch_angle", "tree_support_wall_count", "tree_support_with_infill", "tree_support_branch_distance", "tree_support_branch_diameter"})
for (auto el : {"tree_support_branch_angle", "tree_support_wall_count", "tree_support_branch_distance", "tree_support_branch_diameter"})
toggle_field(el, config->opt_bool("enable_support") && (support_type == stTreeAuto || support_type == stTree || support_type == stHybridAuto));
// hide tree support settings when normal is selected
@ -530,7 +584,6 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
toggle_line("tree_support_branch_diameter", support_is_tree);
toggle_line("tree_support_branch_angle", support_is_tree);
toggle_line("tree_support_wall_count", support_is_tree);
toggle_line("tree_support_with_infill", support_is_tree);
toggle_line("max_bridge_length", support_is_tree);
// tree support use max_bridge_length instead of bridge_no_support
@ -558,7 +611,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
bool has_ironing = (config->opt_enum<IroningType>("ironing_type") != IroningType::NoIroning);
for (auto el : { "ironing_flow", "ironing_spacing", "ironing_speed" })
toggle_field(el, has_ironing);
toggle_line(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" })
@ -568,19 +621,37 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
toggle_field("standby_temperature_delta", have_ooze_prevention);
bool have_prime_tower = config->opt_bool("enable_prime_tower");
for (auto el : { "prime_tower_width", "prime_volume"})
for (auto el : { "prime_tower_width", "prime_volume", "prime_tower_brim_width"})
toggle_line(el, have_prime_tower);
for (auto el : {"flush_into_infill", "flush_into_support", "flush_into_objects"})
toggle_field(el, have_prime_tower);
bool have_avoid_crossing_perimeters = config->opt_bool("reduce_crossing_wall");
toggle_field("max_travel_detour_distance", have_avoid_crossing_perimeters);
toggle_line("max_travel_detour_distance", have_avoid_crossing_perimeters);
bool has_overhang_speed = config->opt_bool("enable_overhang_speed");
toggle_line("overhang_1_4_speed", has_overhang_speed);
toggle_line("overhang_2_4_speed", has_overhang_speed);
toggle_line("overhang_3_4_speed", has_overhang_speed);
toggle_line("overhang_4_4_speed", has_overhang_speed);
for (auto el : { "overhang_1_4_speed", "overhang_2_4_speed", "overhang_3_4_speed", "overhang_4_4_speed"})
toggle_line(el, has_overhang_speed);
toggle_line("flush_into_objects", !is_global_config);
bool has_fuzzy_skin = (config->opt_enum<FuzzySkinType>("fuzzy_skin") != FuzzySkinType::None);
for (auto el : { "fuzzy_skin_thickness", "fuzzy_skin_point_distance"})
toggle_line(el, has_fuzzy_skin);
// C11 printer is not support smooth timelapse
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
std::string str_preset_type = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
toggle_field("timelapse_type", str_preset_type != "C11");
bool have_arachne = config->opt_enum<PerimeterGeneratorType>("wall_generator") == PerimeterGeneratorType::Arachne;
for (auto el : { "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"min_feature_size", "min_bead_width", "wall_distribution_count" })
toggle_line(el, have_arachne);
toggle_field("detect_thin_wall", !have_arachne);
toggle_field("enable_overhang_speed", !have_arachne);
toggle_field("only_one_wall_top", !have_arachne);
}
void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/)

View file

@ -76,6 +76,7 @@ public:
void check_nozzle_temperature_range(DynamicPrintConfig* config);
void check_nozzle_temperature_initial_layer_range(DynamicPrintConfig* config);
void check_bed_temperature_difference(int bed_type, DynamicPrintConfig* config);
void check_filament_max_volumetric_speed(DynamicPrintConfig *config);
// SLA print
void update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config = false);

View file

@ -47,6 +47,7 @@
#include "format.hpp"
#include "MsgDialog.hpp"
#include "UnsavedChangesDialog.hpp"
#include "MainFrame.hpp"
#if defined(__linux__) && defined(__WXGTK3__)
#define wxLinux_gtk3 true
@ -344,9 +345,14 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
if (titles.size() > 1 || is_variants) {
// It only makes sense to add the All / None buttons if there's multiple printers
// All Standard button is added when there are more variants for at least one printer
auto *sel_all_std = new wxButton(this, wxID_ANY, titles.size() > 1 ? _L("All standard") : _L("Standard"));
auto *sel_all = new wxButton(this, wxID_ANY, _L("All"));
auto *sel_none = new wxButton(this, wxID_ANY, _L("None"));
auto *sel_all_std = new Button(this, titles.size() > 1 ? _L("All standard") : _L("Standard"));
auto *sel_all = new Button(this, _L("All"));
auto *sel_none = new Button(this, _L("None"));
wxGetApp().UpdateDarkUI(sel_all_std);
wxGetApp().UpdateDarkUI(sel_all);
wxGetApp().UpdateDarkUI(sel_none);
if (is_variants)
sel_all_std->Bind(wxEVT_BUTTON, [this](const wxCommandEvent& event) { this->select_all(true, false); });
sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true, true); });
@ -449,13 +455,12 @@ ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxStrin
, shortname(std::move(shortname))
, indent(indent)
{
wxGetApp().UpdateDarkUI(this);
auto *sizer = new wxBoxSizer(wxVERTICAL);
auto *text = new wxStaticText(this, wxID_ANY, std::move(title), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
const auto font = GetFont().MakeBold().Scaled(1.5);
text->SetFont(font);
text->SetForegroundColour(*wxBLACK);
sizer->Add(text, 0, wxALIGN_LEFT, 0);
sizer->AddSpacer(10);
@ -473,6 +478,8 @@ ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxStrin
this->Layout();
event.Skip();
});
wxGetApp().UpdateDarkUI(this);
}
ConfigWizardPage::~ConfigWizardPage() {}
@ -639,6 +646,7 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
, list_vendor(new StringList(this))
, list_profile(new PresetList(this))
{
SetBackgroundColour(*wxWHITE);
append_spacer(VERTICAL_SPACING);
const int em = parent->em_unit();
@ -650,8 +658,6 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
list_vendor->SetMinSize(wxSize(13*em, list_h));
list_profile->SetMinSize(wxSize(23*em, list_h));
grid = new wxFlexGridSizer(4, em/2, em);
grid->AddGrowableCol(3, 1);
grid->AddGrowableRow(1, 1);
@ -667,8 +673,13 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
grid->Add(list_profile, 1, wxEXPAND);
auto *btn_sizer = new wxBoxSizer(wxHORIZONTAL);
auto *sel_all = new wxButton(this, wxID_ANY, _L("All"));
auto *sel_none = new wxButton(this, wxID_ANY, _L("None"));
auto *sel_all = new Button(this, _L("All"));
auto *sel_none = new Button(this, _L("None"));
wxGetApp().UpdateDarkUI(sel_all);
wxGetApp().UpdateDarkUI(sel_none);
btn_sizer->Add(sel_all, 0, wxRIGHT, em / 2);
btn_sizer->Add(sel_none);
@ -677,6 +688,7 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
wxGetApp().UpdateDarkUI(list_vendor);
wxGetApp().UpdateDarkUI(sel_all);
wxGetApp().UpdateDarkUI(sel_none);
wxGetApp().UpdateDarkUI(list_profile);
grid->Add(new wxBoxSizer(wxHORIZONTAL));
grid->Add(new wxBoxSizer(wxHORIZONTAL));
@ -755,16 +767,16 @@ void PageMaterials::reload_presets()
void PageMaterials::set_compatible_printers_html_window(const std::vector<std::string>& printer_names, bool all_printers)
{
const auto bgr_clr =
#if defined(__APPLE__)
html_window->GetParent()->GetBackgroundColour();
#else
#if defined(_WIN32)
wxGetApp().get_window_default_clr();
#else
wxSystemSettings::GetColour(wxSYS_COLOUR_MENU);
#endif
#endif
const auto bgr_clr = html_window->GetParent()->GetBackgroundColour();
//#if defined(__APPLE__)
// html_window->GetParent()->GetBackgroundColour();
//#else
//#if defined(_WIN32)
// html_window->GetParent()->GetBackgroundColour();
//#else
// wxSystemSettings::GetColour(wxSYS_COLOUR_MENU);
//#endif
//#endif
const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
const auto text_clr = wxGetApp().get_label_clr_default();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
@ -1048,7 +1060,7 @@ void PageMaterials::update_lists(int sel_type, int sel_vendor, int last_selected
sel_vendor_prev = sel_vendor;
}
wxGetApp().UpdateDarkUI(list_profile);
//wxGetApp().UpdateDarkUI(list_profile);
}
void PageMaterials::sort_list_data(StringList* list, bool add_All_item, bool material_type_ordering)
@ -1218,72 +1230,70 @@ PageCustom::PageCustom(ConfigWizard *parent)
append(cb_custom);
append(label);
append(tc_profile_name);
wxGetApp().UpdateDarkUI(this);
}
#ifdef _WIN32
PageFilesAssociation::PageFilesAssociation(ConfigWizard* parent)
: ConfigWizardPage(parent, _L("Files association"), _L("Files association"))
PageFirmware::PageFirmware(ConfigWizard *parent)
: ConfigWizardPage(parent, _L("Firmware Type"), _L("Firmware"), 1)
, gcode_opt(*print_config_def.get("gcode_flavor"))
, gcode_picker(nullptr)
{
cb_3mf = new wxCheckBox(this, wxID_ANY, _L("Associate with 3mf files"));
cb_stl = new wxCheckBox(this, wxID_ANY, _L("Associate with stl files"));
//cb_gcode = new wxCheckBox(this, wxID_ANY, _L("Associate with gcode files"));
append_text(_L("Choose the type of firmware used by your printer."));
append_text(_(gcode_opt.tooltip));
append(cb_3mf);
append(cb_stl);
//append(cb_gcode);
wxArrayString choices;
choices.Alloc(gcode_opt.enum_labels.size());
for (const auto &label : gcode_opt.enum_labels) {
choices.Add(label);
}
gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
wxGetApp().UpdateDarkUI(gcode_picker);
const auto &enum_values = gcode_opt.enum_values;
auto needle = enum_values.cend();
if (gcode_opt.default_value) {
needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize());
}
if (needle != enum_values.cend()) {
gcode_picker->SetSelection(needle - enum_values.cbegin());
} else {
gcode_picker->SetSelection(0);
}
append(gcode_picker);
}
#endif // _WIN32
PageVendors::PageVendors(ConfigWizard *parent)
: ConfigWizardPage(parent, _L("Other Vendors"), _L("Other Vendors"))
void PageFirmware::apply_custom_config(DynamicPrintConfig &config)
{
const AppConfig &appconfig = this->wizard_p()->appconfig_new;
append_text(_L("Pick another vendor:"));
auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
boldfont.SetWeight(wxFONTWEIGHT_BOLD);
for (const auto &pair : wizard_p()->bundles) {
const VendorProfile *vendor = pair.second.vendor_profile;
//BBS: add BBL as default
if (vendor->id == PresetBundle::BBL_BUNDLE) { continue; }
auto *cbox = new wxCheckBox(this, wxID_ANY, vendor->name);
cbox->Bind(wxEVT_CHECKBOX, [=](wxCommandEvent &event) {
wizard_p()->on_3rdparty_install(vendor, cbox->IsChecked());
});
const auto &vendors = appconfig.vendors();
const bool enabled = vendors.find(pair.first) != vendors.end();
if (enabled) {
cbox->SetValue(true);
auto pages = wizard_p()->pages_3rdparty.find(vendor->id);
wxCHECK_RET(pages != wizard_p()->pages_3rdparty.end(), _L("Internal error: third party vendor printers not created"));
for (PagePrinters* page : { pages->second.first, pages->second.second })
if (page) page->install = true;
}
append(cbox);
auto sel = gcode_picker->GetSelection();
if (sel >= 0 && (size_t)sel < gcode_opt.enum_labels.size()) {
auto *opt = new ConfigOptionEnum<GCodeFlavor>(static_cast<GCodeFlavor>(sel));
config.set_key_value("gcode_flavor", opt);
}
}
/*PageBedShape::PageBedShape(ConfigWizard *parent)
PageBedShape::PageBedShape(ConfigWizard* parent)
: ConfigWizardPage(parent, _L("Bed Shape and Size"), _L("Bed Shape"), 1)
, shape_panel(new BedShapePanel(this))
{
append_text(_L("Set the shape of your printer's bed."));
shape_panel->build_panel(*wizard_p()->custom_config->option<ConfigOptionPoints>("printable_area"), {}, {});
shape_panel->build_panel(*wizard_p()->custom_config->option<ConfigOptionPoints>("printable_area"),
*wizard_p()->custom_config->option<ConfigOptionString>("bed_custom_texture"),
*wizard_p()->custom_config->option<ConfigOptionString>("bed_custom_model"));
append(shape_panel);
}
void PageBedShape::apply_custom_config(DynamicPrintConfig &config)
void PageBedShape::apply_custom_config(DynamicPrintConfig& config)
{
const std::vector<Vec2d>& points = shape_panel->get_shape();
const std::string& custom_texture = shape_panel->get_custom_texture();
const std::string& custom_model = shape_panel->get_custom_model();
config.set_key_value("printable_area", new ConfigOptionPoints(points));
}*/
config.set_key_value("bed_custom_texture", new ConfigOptionString(custom_texture));
config.set_key_value("bed_custom_model", new ConfigOptionString(custom_model));
}
static void focus_event(wxFocusEvent& e, wxTextCtrl* ctrl, double def_value)
{
@ -1460,19 +1470,231 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent)
append(sizer_bed);
}
void PageTemperatures::apply_custom_config(DynamicPrintConfig &config)
void PageTemperatures::apply_custom_config(DynamicPrintConfig& config)
{
// BBS
#if 0
auto *opt_extr = new ConfigOptionInts(1, spin_extr->GetValue());
/*
auto* opt_extr = new ConfigOptionInts(1, spin_extr->GetValue());
config.set_key_value("nozzle_temperature", opt_extr);
auto *opt_extr1st = new ConfigOptionInts(1, spin_extr->GetValue());
auto* opt_extr1st = new ConfigOptionInts(1, spin_extr->GetValue());
config.set_key_value("nozzle_temperature_initial_layer", opt_extr1st);
auto *opt_bed = new ConfigOptionInts(1, spin_bed->GetValue());
auto* opt_bed = new ConfigOptionInts(1, spin_bed->GetValue());
config.set_key_value("bed_temperature", opt_bed);
auto *opt_bed1st = new ConfigOptionInts(1, spin_bed->GetValue());
auto* opt_bed1st = new ConfigOptionInts(1, spin_bed->GetValue());
config.set_key_value("bed_temperature_initial_layer", opt_bed1st);
#endif
*/
}
ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent)
: wxPanel(parent)
, bg(ScalableBitmap(parent, "BambuStudio_192px_transparent.png", 192))
, bullet_black(ScalableBitmap(parent, "bullet_black.png"))
, bullet_blue(ScalableBitmap(parent, "bullet_blue.png"))
, bullet_white(ScalableBitmap(parent, "bullet_white.png"))
, item_active(NO_ITEM)
, item_hover(NO_ITEM)
, last_page((size_t)-1)
{
#ifndef __WXOSX__
SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX
#endif //__WXOSX__
SetMinSize(bg.bmp().GetSize());
const wxSize size = GetTextExtent("m");
em_w = size.x;
em_h = size.y;
Bind(wxEVT_PAINT, &ConfigWizardIndex::on_paint, this);
Bind(wxEVT_SIZE, [this](wxEvent& e) { e.Skip(); Refresh(); });
Bind(wxEVT_MOTION, &ConfigWizardIndex::on_mouse_move, this);
Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &evt) {
if (item_hover != -1) {
item_hover = -1;
Refresh();
}
evt.Skip();
});
Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &evt) {
if (item_hover >= 0) { go_to(item_hover); }
});
}
wxDECLARE_EVENT(EVT_INDEX_PAGE, wxCommandEvent);
void ConfigWizardIndex::add_page(ConfigWizardPage *page)
{
if (!page)
return;
last_page = items.size();
items.emplace_back(Item { page->shortname, page->indent, page });
Refresh();
}
void ConfigWizardIndex::add_label(wxString label, unsigned indent)
{
items.emplace_back(Item { std::move(label), indent, nullptr });
Refresh();
}
ConfigWizardPage* ConfigWizardIndex::active_page() const
{
if (item_active >= items.size()) { return nullptr; }
return items[item_active].page;
}
void ConfigWizardIndex::go_prev()
{
// Search for a preceiding item that is a page (not a label, ie. page != nullptr)
if (item_active == NO_ITEM) { return; }
for (size_t i = item_active; i > 0; i--) {
if (items[i - 1].page != nullptr) {
go_to(i - 1);
return;
}
}
}
void ConfigWizardIndex::go_next()
{
// Search for a next item that is a page (not a label, ie. page != nullptr)
if (item_active == NO_ITEM) { return; }
for (size_t i = item_active + 1; i < items.size(); i++) {
if (items[i].page != nullptr) {
go_to(i);
return;
}
}
}
// This one actually performs the go-to op
void ConfigWizardIndex::go_to(size_t i)
{
if (i != item_active
&& i < items.size()
&& items[i].page != nullptr) {
auto *new_active = items[i].page;
auto *former_active = active_page();
if (former_active != nullptr) {
former_active->Hide();
}
item_active = i;
new_active->Show();
wxCommandEvent evt(EVT_INDEX_PAGE, GetId());
AddPendingEvent(evt);
Refresh();
new_active->on_activate();
}
}
void ConfigWizardIndex::go_to(const ConfigWizardPage *page)
{
if (page == nullptr) { return; }
for (size_t i = 0; i < items.size(); i++) {
if (items[i].page == page) {
go_to(i);
return;
}
}
}
void ConfigWizardIndex::clear()
{
auto *former_active = active_page();
if (former_active != nullptr) { former_active->Hide(); }
items.clear();
item_active = NO_ITEM;
}
void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
{
const auto size = GetClientSize();
if (size.GetHeight() == 0 || size.GetWidth() == 0) { return; }
wxPaintDC dc(this);
const auto bullet_w = bullet_black.bmp().GetSize().GetWidth();
const auto bullet_h = bullet_black.bmp().GetSize().GetHeight();
const int yoff_icon = bullet_h < em_h ? (em_h - bullet_h) / 2 : 0;
const int yoff_text = bullet_h > em_h ? (bullet_h - em_h) / 2 : 0;
const int yinc = item_height();
int index_width = 0;
unsigned y = 0;
for (size_t i = 0; i < items.size(); i++) {
const Item& item = items[i];
unsigned x = em_w/2 + item.indent * em_w;
if (i == item_active || (item_hover >= 0 && i == (size_t)item_hover)) {
dc.DrawBitmap(bullet_blue.bmp(), x, y + yoff_icon, false);
}
else if (i < item_active) { dc.DrawBitmap(bullet_black.bmp(), x, y + yoff_icon, false); }
else if (i > item_active) { dc.DrawBitmap(bullet_white.bmp(), x, y + yoff_icon, false); }
x += + bullet_w + em_w/2;
const auto text_size = dc.GetTextExtent(item.label);
dc.SetTextForeground(wxGetApp().get_label_clr_default());
dc.DrawText(item.label, x, y + yoff_text);
y += yinc;
index_width = std::max(index_width, (int)x + text_size.x);
}
//draw logo
if (int y = size.y - bg.GetBmpHeight(); y>=0) {
dc.DrawBitmap(bg.bmp(), 0, y, false);
index_width = std::max(index_width, bg.GetBmpWidth() + em_w / 2);
}
if (GetMinSize().x < index_width) {
CallAfter([this, index_width]() {
SetMinSize(wxSize(index_width, GetMinSize().y));
Refresh();
});
}
}
void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt)
{
const wxClientDC dc(this);
const wxPoint pos = evt.GetLogicalPosition(dc);
const ssize_t item_hover_new = pos.y / item_height();
if (item_hover_new < ssize_t(items.size()) && item_hover_new != item_hover) {
item_hover = item_hover_new;
Refresh();
}
evt.Skip();
}
void ConfigWizardIndex::msw_rescale()
{
const wxSize size = GetTextExtent("m");
em_w = size.x;
em_h = size.y;
bg.msw_rescale();
SetMinSize(bg.bmp().GetSize());
bullet_black.msw_rescale();
bullet_blue.msw_rescale();
bullet_white.msw_rescale();
Refresh();
}
// Materials
@ -1562,8 +1784,29 @@ void ConfigWizard::priv::load_pages()
wxWindowUpdateLocker freeze_guard(q);
(void)freeze_guard;
const ConfigWizardPage *former_active = index->active_page();
index->clear();
// Printers
if (!only_sla_mode) {
index->add_page(page_custom);
if (page_custom->custom_wanted()) {
index->add_page(page_firmware);
index->add_page(page_bed);
index->add_page(page_diams);
//index->add_page(page_temps);
}
// Filaments & Materials
if (any_fff_selected) { index->add_page(page_filaments); }
}
if (any_sla_selected) { index->add_page(page_sla_materials); }
// there should to be selected at least one printer
btn_finish->Enable();
btn_finish->Enable(any_fff_selected || any_sla_selected || custom_printer_selected);
index->go_to(former_active); // Will restore the active item/page if possible
q->Layout();
// This Refresh() is needed to avoid ugly artifacts after printer selection, when no one vendor was selected from the very beginnig
@ -1584,6 +1827,12 @@ void ConfigWizard::priv::init_dialog_size()
9*disp_rect.width / 10,
9*disp_rect.height / 10);
const int width_hint = index->GetSize().GetWidth() + 90 * em()/*std::max(90 * em(), (only_sla_mode ? page_msla->get_width() : page_fff->get_width()) + 30 * em())*/; // XXX: magic constant, I found no better solution
if (width_hint < window_rect.width) {
window_rect.x += (window_rect.width - width_hint) / 2;
window_rect.width = width_hint;
}
q->SetSize(window_rect);
}
@ -1668,16 +1917,20 @@ void ConfigWizard::priv::enable_next(bool enable)
void ConfigWizard::priv::set_start_page(ConfigWizard::StartPage start_page)
{
switch (start_page) {
case ConfigWizard::SP_PRINTERS:
case ConfigWizard::SP_CUSTOM:
index->go_to(page_custom);
btn_next->SetFocus();
break;
case ConfigWizard::SP_FILAMENTS:
index->go_to(page_filaments);
btn_finish->SetFocus();
break;
case ConfigWizard::SP_MATERIALS:
index->go_to(page_sla_materials);
btn_finish->SetFocus();
break;
default:
index->go_to(page_custom);
btn_next->SetFocus();
break;
}
@ -1714,7 +1967,7 @@ void ConfigWizard::priv::create_3rdparty_pages()
add_page(pageSLA);
}
pages_3rdparty.insert({vendor->id, {pageFFF, pageSLA}});
//pages_3rdparty.insert({vendor->id, {pageFFF, pageSLA}});
}
}
@ -1932,19 +2185,19 @@ void ConfigWizard::priv::select_default_materials_for_printer_models(Technology
void ConfigWizard::priv::on_3rdparty_install(const VendorProfile *vendor, bool install)
{
auto it = pages_3rdparty.find(vendor->id);
wxCHECK_RET(it != pages_3rdparty.end(), "Internal error: GUI page not found for 3rd party vendor profile");
//auto it = pages_3rdparty.find(vendor->id);
//wxCHECK_RET(it != pages_3rdparty.end(), "Internal error: GUI page not found for 3rd party vendor profile");
for (PagePrinters* page : { it->second.first, it->second.second })
if (page) {
if (page->install && !install)
page->select_all(false);
page->install = install;
// if some 3rd vendor is selected, select first printer for them
if (install)
page->printer_pickers[0]->select_one(0, true);
page->Layout();
}
//for (PagePrinters* page : { it->second.first, it->second.second })
// if (page) {
// if (page->install && !install)
// page->select_all(false);
// page->install = install;
// // if some 3rd vendor is selected, select first printer for them
// if (install)
// page->printer_pickers[0]->select_one(0, true);
// page->Layout();
// }
load_pages();
}
@ -1960,6 +2213,7 @@ bool ConfigWizard::priv::on_bnt_finish()
* than last changes wouldn't be updated for filaments/materials.
* SO, do that before close of Wizard
*/
update_materials(T_ANY);
if (any_fff_selected)
page_filaments->reload_presets();
@ -2323,30 +2577,42 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
app_config->set_vendors(appconfig_new);
#ifdef _WIN32
app_config->set_bool("associate_3mf", page_files_association->associate_3mf());
app_config->set_bool("associate_stl", page_files_association->associate_stl());
if (wxGetApp().is_editor()) {
if (page_files_association->associate_3mf())
wxGetApp().associate_files(L"3mf");
if (page_files_association->associate_stl())
wxGetApp().associate_files(L"stl");
}
// else {
// if (page_files_association->associate_gcode())
// wxGetApp().associate_gcode_files();
// }
#endif // _WIN32
if (check_unsaved_preset_changes)
preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem,
{preferred_model, preferred_variant, first_added_filament, first_added_sla_material});
if (!only_sla_mode && page_custom->custom_wanted()) {
// if unsaved changes was not cheched till this moment
if (!check_unsaved_preset_changes &&
!wxGetApp().check_and_keep_current_preset_changes(caption, _L("Custom printer was installed and it will be activated."), act_btns, &apply_keeped_changes))
return false;
page_firmware->apply_custom_config(*custom_config);
page_bed->apply_custom_config(*custom_config);
page_diams->apply_custom_config(*custom_config);
//page_temps->apply_custom_config(*custom_config);
#if ENABLE_COPY_CUSTOM_BED_MODEL_AND_TEXTURE
copy_bed_model_and_texture_if_needed(*custom_config);
#endif // ENABLE_COPY_CUSTOM_BED_MODEL_AND_TEXTURE
custom_config->set_key_value("filament_colour", wxGetApp().preset_bundle->project_config.option("filament_colour"));
const std::string profile_name = page_custom->profile_name();
Semver semver(SLIC3R_VERSION);
preset_bundle->load_config_from_wizard(profile_name, *custom_config, semver, true);
wxGetApp().plater()->sidebar().update_presets(Slic3r::Preset::Type::TYPE_PRINTER);
wxGetApp().plater()->sidebar().update_presets(Slic3r::Preset::Type::TYPE_FILAMENT);
wxGetApp().plater()->sidebar().update_presets(Slic3r::Preset::Type::TYPE_PRINT);
}
// Update the selections from the compatibilty.
preset_bundle->export_selections(*app_config);
// Update Preset Combobox
//auto evt = new SimpleEvent(EVT_UPDATE_PRESET_CB);
//wxQueueEvent(wxGetApp().mainframe, evt);
return true;
}
void ConfigWizard::priv::update_presets_in_config(const std::string& section, const std::string& alias_key, bool add)
@ -2370,11 +2636,7 @@ void ConfigWizard::priv::update_presets_in_config(const std::string& section, co
bool ConfigWizard::priv::check_fff_selected()
{
bool ret = page_fff->any_selected();
for (const auto& printer: pages_3rdparty)
if (printer.second.first) // FFF page
ret |= printer.second.first->any_selected();
return ret;
return false;
}
bool ConfigWizard::priv::check_sla_selected()
@ -2386,17 +2648,20 @@ bool ConfigWizard::priv::check_sla_selected()
// Public
ConfigWizard::ConfigWizard(wxWindow *parent)
: DPIDialog(parent, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(name()), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
: DPIDialog(parent, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(name()), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE /*| wxRESIZE_BORDER*/)
, p(new priv(this))
{
this->SetFont(wxGetApp().normal_font());
SetBackgroundColour(*wxWHITE);
p->load_vendors();
//BBS: add bed exclude areas
p->custom_config.reset(DynamicPrintConfig::new_from_defaults_keys({
"gcode_flavor", "printable_area", "bed_exclude_area", "filament_diameter", "nozzle_temperature", "thumbnails"/*"bed_temperature",*/
"gcode_flavor", "printable_area", "bed_exclude_area", "bed_custom_texture", "bed_custom_model", "nozzle_diameter", "filament_diameter", "thumbnails"
//, "nozzle_temperature", "bed_temperature"
}));
p->index = new ConfigWizardIndex(this);
auto *vsizer = new wxBoxSizer(wxVERTICAL);
auto *topsizer = new wxBoxSizer(wxHORIZONTAL);
auto* hline = new StaticLine(this);
@ -2408,23 +2673,25 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
p->hscroll_sizer = new wxBoxSizer(wxHORIZONTAL);
p->hscroll->SetSizer(p->hscroll_sizer);
wxGetApp().UpdateDarkUI(p->hscroll);
topsizer->Add(p->index, 0, wxEXPAND);
topsizer->AddSpacer(INDEX_MARGIN);
topsizer->Add(p->hscroll, 1, wxEXPAND);
p->btn_sel_all = new wxButton(this, wxID_ANY, _L("Select all standard printers"));
p->btnsizer->Add(p->btn_sel_all);
p->btn_prev = new wxButton(this, wxID_ANY, _L("< &Back"));
p->btn_next = new wxButton(this, wxID_ANY, _L("&Next >"));
p->btn_finish = new wxButton(this, wxID_APPLY, _L("&Finish"));
p->btn_cancel = new wxButton(this, wxID_CANCEL, _L("Cancel")); // Note: The label needs to be present, otherwise we get accelerator bugs on Mac
p->btn_prev = new Button(this, _L("<Back"));
p->btn_next = new Button(this, _L("Next>"));
p->btn_finish = new Button(this,_L("Finish"));
p->btn_finish->SetId(wxID_APPLY);
p->btn_cancel = new Button(this, _L("Cancel")); // Note: The label needs to be present, otherwise we get accelerator bugs on Mac
p->btn_cancel->SetId(wxID_CANCEL);
p->btnsizer->AddStretchSpacer();
p->btnsizer->Add(p->btn_prev, 0, wxLEFT, BTN_SPACING);
p->btnsizer->Add(p->btn_next, 0, wxLEFT, BTN_SPACING);
p->btnsizer->Add(p->btn_finish, 0, wxLEFT, BTN_SPACING);
p->btnsizer->Add(p->btn_cancel, 0, wxLEFT, BTN_SPACING);
wxGetApp().UpdateDarkUI(p->btn_sel_all);
wxGetApp().UpdateDarkUI(p->btn_prev);
wxGetApp().UpdateDarkUI(p->btn_next);
wxGetApp().UpdateDarkUI(p->btn_finish);
@ -2435,36 +2702,22 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
wxCHECK_RET(bbl_it != p->bundles.cend(), "Vendor BambooLab not found");
const VendorProfile * vendor_bbl = bbl_it->second.vendor_profile;
p->page_fff = new PagePrinters(this, _L("BBL FFF Technology Printers"), "BBL FFF", *vendor_bbl, 0, T_FFF);
p->only_sla_mode = false;
if (!p->only_sla_mode) {
p->add_page(p->page_fff);
p->page_fff->is_primary_printer_page = true;
}
if (!p->only_sla_mode) {
// Pages for 3rd party vendors
p->create_3rdparty_pages(); // Needs to be done _before_ creating PageVendors
p->add_page(p->page_vendors = new PageVendors(this));
//p->add_page(p->page_custom = new PageCustom(this));
//p->custom_printer_selected = p->page_custom->custom_wanted();
}
p->any_sla_selected = p->check_sla_selected();
if (p->only_sla_mode)
p->any_fff_selected = p->check_fff_selected();
p->update_materials(T_ANY);
if (!p->only_sla_mode)
p->add_page(p->page_filaments = new PageMaterials(this, &p->filaments,
_L("Filament Profiles Selection"), _L("Filaments"), _L("Type:") ));
p->add_page(p->page_custom = new PageCustom(this));
p->custom_printer_selected = p->page_custom->custom_wanted();
#ifdef _WIN32
p->add_page(p->page_files_association = new PageFilesAssociation(this));
#endif // _WIN32
//p->add_page(p->page_bed = new PageBedShape(this));
p->add_page(p->page_firmware = new PageFirmware(this));
p->add_page(p->page_bed = new PageBedShape(this));
p->add_page(p->page_diams = new PageDiameters(this));
p->add_page(p->page_temps = new PageTemperatures(this));
//p->add_page(p->page_temps = new PageTemperatures(this));
p->update_materials(T_ANY);
p->add_page(p->page_filaments = new PageMaterials(this, &p->filaments,
_L("Filament Profiles Selection"), _L("Filaments"), _L("Type:")));
p->load_pages();
@ -2484,7 +2737,12 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
p->btn_next->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &)
{
;
ConfigWizardPage* active_page = this->p->index->active_page();
if ((active_page == p->page_filaments || active_page == p->page_sla_materials) &&
!p->check_and_install_missing_materials(dynamic_cast<PageMaterials*>(active_page)->materials->technology))
// In that case don't leave the page and the function above queried the user whether to install default materials.
return;
this->p->index->go_next();
});
p->btn_finish->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &)
@ -2493,16 +2751,21 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
this->EndModal(wxID_OK);
});
p->btn_sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) {
p->any_sla_selected = true;
p->load_pages();
p->page_fff->select_all(true, false);
p->index->Bind(EVT_INDEX_PAGE, [this](const wxCommandEvent &) {
const bool is_last = p->index->active_is_last();
p->btn_next->Show(! is_last);
if (is_last)
p->btn_finish->SetFocus();
Layout();
});
if (wxLinux_gtk3)
this->Bind(wxEVT_SHOW, [this, vsizer](const wxShowEvent& e) {
;
});
wxGetApp().UpdateDlgDarkUI(this);
}
ConfigWizard::~ConfigWizard() {}
@ -2558,13 +2821,9 @@ void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect)
msw_buttons_rescale(this, em, { wxID_APPLY,
wxID_CANCEL,
p->btn_sel_all->GetId(),
p->btn_next->GetId(),
p->btn_prev->GetId() });
for (auto printer_picker: p->page_fff->printer_pickers)
msw_buttons_rescale(this, em, printer_picker->get_button_indexes());
p->init_dialog_size();
Refresh();

View file

@ -32,6 +32,7 @@ public:
SP_PRINTERS,
SP_FILAMENTS,
SP_MATERIALS,
SP_CUSTOM,
};
ConfigWizard(wxWindow *parent);

View file

@ -24,9 +24,10 @@
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "slic3r/Utils/PresetUpdater.hpp"
//#include "BedShapeDialog.hpp"
#include "BedShapeDialog.hpp"
#include "GUI.hpp"
#include "wxExtensions.hpp"
#include "Widgets/Button.hpp"
namespace fs = boost::filesystem;
@ -162,7 +163,7 @@ struct PrinterPickerEvent;
typedef std::function<bool(const VendorProfile::PrinterModel&)> ModelFilter;
struct PrinterPicker: wxPanel
struct PrinterPicker: wxPanel //TO check
{
struct Checkbox : wxCheckBox
{
@ -240,7 +241,7 @@ struct PageWelcome: ConfigWizardPage
virtual void set_run_reason(ConfigWizard::RunReason run_reason) override;
};
struct PagePrinters: ConfigWizardPage
struct PagePrinters: ConfigWizardPage //TO check
{
std::vector<PrinterPicker *> printer_pickers;
Technology technology;
@ -386,50 +387,59 @@ private:
};
struct PageUpdate: ConfigWizardPage
//struct PageUpdate: ConfigWizardPage
//{
// bool version_check;
// bool preset_update;
//
// PageUpdate(ConfigWizard *parent);
//};
//struct PageReloadFromDisk : ConfigWizardPage
//{
// bool full_pathnames;
//
// PageReloadFromDisk(ConfigWizard* parent);
//};
//#ifdef _WIN32
//struct PageFilesAssociation : ConfigWizardPage
//{
//private:
// wxCheckBox* cb_3mf{ nullptr };
// wxCheckBox* cb_stl{ nullptr };
//// wxCheckBox* cb_gcode;
//
//public:
// PageFilesAssociation(ConfigWizard* parent);
//
// bool associate_3mf() const { return cb_3mf->IsChecked(); }
// bool associate_stl() const { return cb_stl->IsChecked(); }
//// bool associate_gcode() const { return cb_gcode->IsChecked(); }
//};
//#endif // _WIN32
//struct PageVendors: ConfigWizardPage
//{
// PageVendors(ConfigWizard *parent);
//};
struct PageFirmware: ConfigWizardPage
{
bool version_check;
bool preset_update;
const ConfigOptionDef &gcode_opt;
wxChoice *gcode_picker;
PageUpdate(ConfigWizard *parent);
};
struct PageReloadFromDisk : ConfigWizardPage
{
bool full_pathnames;
PageReloadFromDisk(ConfigWizard* parent);
};
#ifdef _WIN32
struct PageFilesAssociation : ConfigWizardPage
{
private:
wxCheckBox* cb_3mf{ nullptr };
wxCheckBox* cb_stl{ nullptr };
// wxCheckBox* cb_gcode;
public:
PageFilesAssociation(ConfigWizard* parent);
bool associate_3mf() const { return cb_3mf->IsChecked(); }
bool associate_stl() const { return cb_stl->IsChecked(); }
// bool associate_gcode() const { return cb_gcode->IsChecked(); }
};
#endif // _WIN32
struct PageVendors: ConfigWizardPage
{
PageVendors(ConfigWizard *parent);
};
/*struct PageBedShape: ConfigWizardPage
{
BedShapePanel *shape_panel;
PageBedShape(ConfigWizard *parent);
PageFirmware(ConfigWizard *parent);
virtual void apply_custom_config(DynamicPrintConfig &config);
};*/
};
struct PageBedShape : ConfigWizardPage
{
BedShapePanel* shape_panel;
PageBedShape(ConfigWizard* parent);
virtual void apply_custom_config(DynamicPrintConfig& config);
};
struct PageDiameters: ConfigWizardPage
{
@ -454,6 +464,62 @@ typedef std::map<std::string /* = vendor ID */,
std::pair<PagePrinters* /* = FFF page */,
PagePrinters* /* = SLA page */>> Pages3rdparty;
class ConfigWizardIndex: public wxPanel
{
public:
ConfigWizardIndex(wxWindow *parent);
void add_page(ConfigWizardPage *page);
void add_label(wxString label, unsigned indent = 0);
size_t active_item() const { return item_active; }
ConfigWizardPage* active_page() const;
bool active_is_last() const { return item_active < items.size() && item_active == last_page; }
void go_prev();
void go_next();
void go_to(size_t i);
void go_to(const ConfigWizardPage *page);
void clear();
void msw_rescale();
int em() const { return em_w; }
static const size_t NO_ITEM = size_t(-1);
private:
struct Item
{
wxString label;
unsigned indent;
ConfigWizardPage *page; // nullptr page => label-only item
bool operator==(ConfigWizardPage *page) const { return this->page == page; }
};
int em_w;
int em_h;
ScalableBitmap bg;
ScalableBitmap bullet_black;
ScalableBitmap bullet_blue;
ScalableBitmap bullet_white;
std::vector<Item> items;
size_t item_active;
ssize_t item_hover;
size_t last_page;
int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em_w) + em_w; }
void on_paint(wxPaintEvent &evt);
void on_mouse_move(wxMouseEvent &evt);
};
wxDEFINE_EVENT(EVT_INDEX_PAGE, wxCommandEvent);
// ConfigWizard private data
typedef std::map<std::string, std::set<std::string>> PresetAliases;
@ -482,26 +548,28 @@ struct ConfigWizard::priv
wxBoxSizer *hscroll_sizer = nullptr;
wxBoxSizer *btnsizer = nullptr;
ConfigWizardPage *page_current = nullptr;
wxButton *btn_sel_all = nullptr;
wxButton *btn_prev = nullptr;
wxButton *btn_next = nullptr;
wxButton *btn_finish = nullptr;
wxButton *btn_cancel = nullptr;
ConfigWizardIndex *index = nullptr;
//wxButton *btn_sel_all = nullptr;
Button *btn_prev = nullptr;
Button *btn_next = nullptr;
Button *btn_finish = nullptr;
Button *btn_cancel = nullptr;
PagePrinters *page_fff = nullptr;
PagePrinters *page_msla = nullptr;
//PagePrinters *page_fff = nullptr;
//PagePrinters *page_msla = nullptr;
PageMaterials *page_filaments = nullptr;
PageMaterials *page_sla_materials = nullptr;
PageCustom *page_custom = nullptr;
PageReloadFromDisk *page_reload_from_disk = nullptr;
#ifdef _WIN32
PageFilesAssociation* page_files_association = nullptr;
#endif // _WIN32
PageVendors *page_vendors = nullptr;
Pages3rdparty pages_3rdparty;
//PageReloadFromDisk *page_reload_from_disk = nullptr;
//#ifdef _WIN32
// PageFilesAssociation* page_files_association = nullptr;
//#endif // _WIN32
//PageVendors *page_vendors = nullptr;
//Pages3rdparty pages_3rdparty;
// Custom setup pages
//PageBedShape *page_bed = nullptr;
PageFirmware *page_firmware = nullptr;
PageBedShape *page_bed = nullptr;
PageDiameters *page_diams = nullptr;
PageTemperatures *page_temps = nullptr;

View file

@ -1,190 +0,0 @@
#include "ConfirmHintDialog.hpp"
#include <slic3r/GUI/I18N.hpp>
#include <wx/dcgraph.h>
#include <wx/dcmemory.h>
#include <slic3r/GUI/Widgets/Label.hpp>
namespace Slic3r { namespace GUI {
wxDEFINE_EVENT(EVT_CONFIRM_HINT, wxCommandEvent);
ConfirmHintDialog::ConfirmHintDialog(wxWindow* parent, wxWindowID id, const wxString& title, 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();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
auto* main_sizer = new wxBoxSizer(wxVERTICAL);
auto* button_sizer = new wxBoxSizer(wxHORIZONTAL);
wxPanel* m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_button_confirm = new Button(this, _L("Confirm"));
m_button_confirm->SetFont(Label::Body_14);
m_button_confirm->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_confirm->SetCornerRadius(FromDIP(12));
StateColor confirm_btn_bg(std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_confirm->SetBackgroundColor(confirm_btn_bg);
m_button_confirm->SetBorderColor(wxColour(0, 174, 66));
m_button_confirm->SetTextColor(*wxWHITE);
m_button_close = new Button(this, _L("Cancel"));
m_button_close->SetFont(Label::Body_14);
m_button_close->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_close->SetCornerRadius(FromDIP(12));
StateColor close_btn_bg(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
m_button_close->SetBackgroundColor(close_btn_bg);
m_button_close->SetBorderColor(wxColour(38, 46, 48));
m_button_close->SetTextColor(wxColour(38, 46, 48));
button_sizer->AddStretchSpacer();
button_sizer->Add(m_button_confirm);
button_sizer->AddSpacer(FromDIP(20));
button_sizer->Add(m_button_close);
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));
SetSizer(main_sizer);
CenterOnParent();
this->SetSize(wxSize(wxSize(FromDIP(475), FromDIP(100)).x, -1));
this->SetMinSize(wxSize(wxSize(FromDIP(475), FromDIP(100)).x, -1));
Layout();
Fit();
this->Bind(wxEVT_PAINT, &ConfirmHintDialog::OnPaint, this);
m_button_confirm->Bind(wxEVT_BUTTON, &ConfirmHintDialog::on_button_confirm, this);
m_button_close->Bind(wxEVT_BUTTON, &ConfirmHintDialog::on_button_close, this);
}
ConfirmHintDialog::~ConfirmHintDialog() {}
void ConfirmHintDialog::SetHint(const wxString& hint){
firm_up_hint = hint;
}
void ConfirmHintDialog::OnPaint(wxPaintEvent& event){
wxPaintDC dc(this);
render(dc);
}
void ConfirmHintDialog::render(wxDC& dc) {
wxSize size = GetSize();
dc.SetFont(Label::Body_14);
dc.SetTextForeground(text_color);
wxPoint pos_start = wxPoint(FromDIP(25), FromDIP(25));
wxSize firm_up_hint_size = dc.GetTextExtent(firm_up_hint);
wxPoint pos_firm_up_hint = pos_start;
if (firm_up_hint_size.x + pos_firm_up_hint.x + FromDIP(25) > wxSize(FromDIP(475), FromDIP(100)).x) {
bool is_ch = false;
if (firm_up_hint[0] > 0x80 && firm_up_hint[1] > 0x80)
is_ch = true;
wxString fisrt_line;
wxString remaining_line;
wxString count_txt;
int new_line_pos = 0;
for (int i = 0; i < firm_up_hint.length(); i++) {
count_txt += firm_up_hint[i];
auto text_size = dc.GetTextExtent(count_txt);
if (text_size.x + pos_firm_up_hint.x + FromDIP(25) < wxSize(FromDIP(475), FromDIP(100)).x)
{
if (firm_up_hint[i] == ' ') {
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) {
fisrt_line = firm_up_hint.SubString(0, new_line_pos);
remaining_line = firm_up_hint.SubString(new_line_pos + 1, firm_up_hint.length());
break;
}
else {
fisrt_line = firm_up_hint.SubString(0, i - 1);
remaining_line = firm_up_hint.SubString(i, firm_up_hint.length());
break;
}
count_txt = "";
}
}
dc.DrawText(fisrt_line, pos_firm_up_hint);
count_txt = "";
new_line_pos = 0;
for (int i = 0; i < remaining_line.length(); i++) {
count_txt += remaining_line[i];
auto text_size = dc.GetTextExtent(count_txt);
if (text_size.x + FromDIP(25) + FromDIP(25) < wxSize(FromDIP(475), FromDIP(100)).x)
{
if (remaining_line[i] == ' ' || remaining_line[i] == '\n')
new_line_pos = i;
}
else {
if (!is_ch){
remaining_line[new_line_pos] = '\n';
}
else {
remaining_line.insert(i, '\n');
}
count_txt = "";
}
}
wxPoint pos_txt = pos_firm_up_hint;
pos_txt.y += dc.GetCharHeight();
dc.DrawText(remaining_line, pos_txt);
}
else
dc.DrawText(firm_up_hint, pos_firm_up_hint);
}
void ConfirmHintDialog::on_button_confirm(wxCommandEvent& event) {
wxCommandEvent evt(EVT_CONFIRM_HINT, GetId());
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(evt);
if (this->IsModal())
this->EndModal(wxID_OK);
else
this->Close();
}
void ConfirmHintDialog::on_button_close(wxCommandEvent& event) {
this->Close();
}
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));
if (m_button_close->IsShown()) {
m_button_close->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_close->SetCornerRadius(FromDIP(12));
}
Layout();
}
}} // namespace Slic3r::GUI

View file

@ -1,54 +0,0 @@
#ifndef slic3r_GUI_ConfirmHintDialog_hpp_
#define slic3r_GUI_ConfirmHintDialog_hpp_
#include "GUI_Utils.hpp"
#include <wx/statbmp.h>
#include "Widgets/Button.hpp"
#include <wx/stattext.h>
namespace Slic3r { namespace GUI {
wxDECLARE_EVENT(EVT_CONFIRM_HINT, wxCommandEvent);
class ConfirmHintDialog : public DPIDialog
{
private:
wxStaticText* m_staticText_hint;
Button* m_button_confirm;
Button* m_button_close;
wxStaticBitmap* m_bitmap_home;
ScalableBitmap m_home_bmp;
wxString firm_up_hint = "";
void OnPaint(wxPaintEvent& event);
void render(wxDC& dc);
void on_button_confirm(wxCommandEvent& event);
void on_button_close(wxCommandEvent& event);
void on_dpi_changed(const wxRect& suggested_rect) override;
public:
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);
const wxColour text_color = wxColour(107, 107, 107);
void SetHint(const wxString &hint);
bool Show(bool show) override;
~ConfirmHintDialog();
};
}} // namespace Slic3r::GUI
#endif

View file

@ -1,4 +1,5 @@
#include "ConnectPrinter.hpp"
#include "GUI_App.hpp"
#include <slic3r/GUI/I18N.hpp>
#include <slic3r/GUI/Widgets/Label.hpp>
#include "libslic3r/AppConfig.hpp"
@ -8,7 +9,7 @@ ConnectPrinterDialog::ConnectPrinterDialog(wxWindow *parent, wxWindowID id, cons
: DPIDialog(parent, id, _L("ConnectPrinter(LAN)"), pos, size, style)
{
init_bitmap();
SetBackgroundColour(*wxWHITE);
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
wxBoxSizer *main_sizer;
@ -50,6 +51,7 @@ ConnectPrinterDialog::ConnectPrinterDialog(wxWindow *parent, wxWindowID id, cons
m_button_confirm->SetFont(Label::Body_12);
m_button_confirm->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_confirm->SetCornerRadius(FromDIP(12));
m_button_confirm->SetTextColor(wxColour("#FFFFFE"));
StateColor btn_bg(
std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed),
@ -101,10 +103,16 @@ ConnectPrinterDialog::ConnectPrinterDialog(wxWindow *parent, wxWindowID id, cons
m_textCtrl_code->Bind(wxEVT_TEXT, &ConnectPrinterDialog::on_input_enter, this);
m_button_confirm->Bind(wxEVT_BUTTON, &ConnectPrinterDialog::on_button_confirm, this);
wxGetApp().UpdateDlgDarkUI(this);
}
ConnectPrinterDialog::~ConnectPrinterDialog() {}
void ConnectPrinterDialog::end_modal(wxStandardID id)
{
EndModal(id);
}
void ConnectPrinterDialog::init_bitmap()
{
AppConfig *config = get_app_config();
@ -141,6 +149,7 @@ void ConnectPrinterDialog::on_button_confirm(wxCommandEvent &event)
}
if (m_obj) {
m_obj->set_access_code(code.ToStdString());
wxGetApp().getDeviceManager()->set_selected_machine(m_obj->dev_id);
}
EndModal(wxID_OK);
}

View file

@ -45,6 +45,7 @@ public:
~ConnectPrinterDialog();
void end_modal(wxStandardID id);
void init_bitmap();
void set_machine_object(MachineObject* obj);
void on_input_enter(wxCommandEvent& evt);

File diff suppressed because it is too large Load diff

View file

@ -11,18 +11,25 @@
#include "libslic3r/ProjectTask.hpp"
#include "slic3r/Utils/json_diff.hpp"
#include "slic3r/Utils/NetworkAgent.hpp"
#include "CameraPopup.hpp"
#define USE_LOCAL_SOCKET_BIND 0
#define DISCONNECT_TIMEOUT 30000.f // milliseconds
#define PUSHINFO_TIMEOUT 15000.f // milliseconds
#define TIMEOUT_FOR_STRAT 20000.f // milliseconds
#define REQUEST_PUSH_MIN_TIME 15000.f // milliseconds
#define REQUEST_START_MIN_TIME 15000.f // milliseconds
#define FILAMENT_MAX_TEMP 300
#define FILAMENT_DEF_TEMP 220
#define FILAMENT_MIN_TEMP 120
#define BED_TEMP_LIMIT 120
#define HOLD_COUNT_MAX 3
#define HOLD_COUNT_CAMERA 6
#define GET_VERSION_RETRYS 10
#define RETRY_INTERNAL 2000
inline int correct_filament_temperature(int filament_temp)
{
@ -61,7 +68,9 @@ enum PrinterFunction {
FUNC_TIMELAPSE,
FUNC_RECORDING,
FUNC_FIRSTLAYER_INSPECT,
FUNC_SPAGHETTI,
FUNC_AI_MONITORING,
FUNC_BUILDPLATE_MARKER_DETECT,
FUNC_AUTO_RECOVERY_STEP_LOSS,
FUNC_FLOW_CALIBRATION,
FUNC_AUTO_LEVELING,
FUNC_CHAMBER_TEMP,
@ -70,6 +79,12 @@ enum PrinterFunction {
FUNC_REMOTE_TUNNEL,
FUNC_LOCAL_TUNNEL,
FUNC_PRINT_WITHOUT_SD,
FUNC_VIRTUAL_CAMERA,
FUNC_USE_AMS,
FUNC_ALTER_RESOLUTION,
FUNC_SEND_TO_SDCARD,
FUNC_AUTO_SWITCH_FILAMENT,
FUNC_CHAMBER_FAN,
FUNC_MAX
};
@ -126,6 +141,12 @@ enum AmsRfidStatus {
AMS_RFID_HAS_FILAMENT = 6
};
enum AmsOptionType {
AMS_OP_STARTUP_READ,
AMS_OP_TRAY_READ,
AMS_OP_CALIBRATE_REMAIN
};
class AmsTray {
public:
AmsTray(std::string tray_id) {
@ -177,6 +198,7 @@ public:
bool is_bbl;
bool is_exists = false;
int hold_count = 0;
int remain = 0; // filament remain: 0 ~ 100
AmsRoadPosition road_position;
AmsStep step_state;
@ -199,6 +221,7 @@ public:
id = ams_id;
}
std::string id;
int humidity = 5;
bool startup_read_opt{true};
bool tray_read_opt{false};
bool is_exists{false};
@ -288,6 +311,8 @@ private:
NetworkAgent* m_agent { nullptr };
bool check_valid_ip();
void _parse_print_option_ack(int option);
public:
enum LIGHT_EFFECT {
@ -310,6 +335,18 @@ public:
UpgradingFinished = 3
};
enum ExtruderAxisStatus {
LOAD = 0,
UNLOAD =1,
STATUS_NUMS = 2
};
enum ExtruderAxisStatus extruder_axis_status = LOAD;
enum PrintOption {
PRINT_OP_AUTO_RECOVERY = 0,
PRINT_OP_MAX,
};
class ModuleVersionInfo
{
public:
@ -320,10 +357,18 @@ public:
std::string sw_new_ver;
};
enum SdcardState {
NO_SDCARD = 0,
HAS_SDCARD_NORMAL = 1,
HAS_SDCARD_ABNORMAL = 2,
SDCARD_STATE_NUM = 3
};
/* static members and functions */
static inline int m_sequence_id = 20000;
static std::string parse_printer_type(std::string type_str);
static std::string get_preset_printer_model_name(std::string printer_type);
static std::string get_preset_printer_thumbnail_img(std::string printer_type);
static bool is_bbl_filament(std::string tag_uid);
typedef std::function<void()> UploadedFn;
@ -343,8 +388,13 @@ public:
bool is_lan_mode_printer();
//PRINTER_TYPE printer_type = PRINTER_3DPrinter_UKNOWN;
std::string printer_type; /* model_id */
std::string printer_thumbnail_img;
std::string monitor_upgrade_printer_img;
wxString get_printer_type_display_str();
std::string get_printer_thumbnail_img_str();
std::string product_name; // set by iot service, get /user/print
std::string bind_user_name;
@ -353,10 +403,14 @@ public:
bool is_avaliable() { return bind_state == "free"; }
time_t last_alive;
bool m_is_online;
bool m_lan_mode_connection_state{false};
void set_lan_mode_connection_state(bool state) {m_lan_mode_connection_state = state;};
bool get_lan_mode_connection_state() {return m_lan_mode_connection_state;};
int parse_msg_count = 0;
std::chrono::system_clock::time_point last_update_time; /* last received print data from machine */
std::chrono::system_clock::time_point last_push_time; /* last received print push from machine */
std::chrono::system_clock::time_point last_request_push; /* last received print push from machine */
std::chrono::system_clock::time_point last_request_start; /* last received print push from machine */
/* ams properties */
std::map<std::string, Ams*> amsList; // key: ams[id], start with 0
@ -368,7 +422,10 @@ public:
int ams_rfid_status = 0;
bool ams_insert_flag { false };
bool ams_power_on_flag { false };
bool ams_calibrate_remain_flag { false };
bool ams_auto_switch_filament_flag { false };
bool ams_support_use_ams { false };
int ams_humidity;
int ams_user_setting_hold_count = 0;
AmsStatusMain ams_status_main;
int ams_status_sub;
@ -388,13 +445,14 @@ public:
// parse amsStatusMain and ams_status_sub
void _parse_ams_status(int ams_status);
bool has_ams() { return ams_exist_bits != 0; }
bool can_unload_filament();
bool is_U0_firmware();
bool is_support_ams_mapping();
bool is_only_support_cloud_print();
static bool is_support_ams_mapping_version(std::string module, std::string version);
int ams_filament_mapping(std::vector<FilamentInfo> filaments, std::vector<FilamentInfo> &result, std::vector<int> exclude_id = std::vector<int>());
bool is_valid_mapping_result(std::vector<FilamentInfo>& result);
bool is_valid_mapping_result(std::vector<FilamentInfo>& result, bool check_empty_slot = false);
// exceed index start with 0
bool is_mapping_exceed_filament(std::vector<FilamentInfo>& result, int &exceed_index);
void reset_mapping_result(std::vector<FilamentInfo>& result);
@ -402,6 +460,8 @@ public:
/*online*/
bool online_rfid;
bool online_ahb;
int online_version = -1;
int last_online_version = -1;
/* temperature */
float nozzle_temp;
@ -416,6 +476,7 @@ public:
int cooling_fan_speed = 0;
int big_fan1_speed = 0;
int big_fan2_speed = 0;
uint32_t fan_gear = 0;
/* signals */
std::string wifi_signal;
@ -431,7 +492,7 @@ public:
/* upgrade */
bool upgrade_force_upgrade { false };
bool upgrade_new_version { false };
bool upgrade_consistency_request;
bool upgrade_consistency_request { false };
int upgrade_display_state = 0; // 0 : upgrade unavailable, 1: upgrade idle, 2: upgrading, 3: upgrade_finished
PrinterFirmwareType firmware_type; // engineer|production
std::string upgrade_progress;
@ -441,6 +502,7 @@ public:
std::string ams_new_version_number;
std::string ota_new_version_number;
std::string ahb_new_version_number;
int get_version_retry = 0;
std::map<std::string, ModuleVersionInfo> module_vers;
std::map<std::string, ModuleVersionInfo> new_ver_list;
bool m_new_ver_list_exist = false;
@ -452,12 +514,17 @@ public:
bool is_upgrading_avalable();
int get_upgrade_percent();
std::string get_ota_version();
bool check_version_valid();
wxString get_upgrade_result_str(int upgrade_err_code);
// key: ams_id start as 0,1,2,3
std::map<int, ModuleVersionInfo> get_ams_version();
/* printing */
std::string print_type;
float nozzle { 0.0f };
bool is_220V_voltage { false };
int mc_print_stage;
int mc_print_sub_stage;
int mc_print_error_code;
@ -487,6 +554,7 @@ public:
bool is_calibration_done();
void parse_state_changed_event();
void parse_status(int flag);
/* printing status */
std::string print_status; /* enum string: FINISH, RUNNING, PAUSE, INIT, FAILED */
@ -494,17 +562,32 @@ public:
PrintingSpeedLevel printing_speed_lvl;
int printing_speed_mag = 100;
PrintingSpeedLevel _parse_printing_speed_lvl(int lvl);
int get_bed_temperature_limit();
/* camera */
bool has_ipcam { false };
bool camera_recording { false };
bool camera_recording_when_printing { false };
bool camera_timelapse { false };
bool camera_has_sdcard { false };
int camera_recording_hold_count = 0;
int camera_timelapse_hold_count = 0;
int camera_resolution_hold_count = 0;
std::string camera_resolution = "";
bool xcam_first_layer_inspector { false };
int xcam_first_layer_hold_count = 0;
bool xcam_spaghetti_detector { false };
bool xcam_spaghetti_print_halt{ false };
int xcam_spaghetti_hold_count = 0;
bool xcam_ai_monitoring{ false };
int xcam_ai_monitoring_hold_count = 0;
std::string xcam_ai_monitoring_sensitivity;
bool xcam_buildplate_marker_detector{ false };
int xcam_buildplate_marker_hold_count = 0;
bool xcam_auto_recovery_step_loss{ false };
int xcam_auto_recovery_hold_count = 0;
int ams_print_option_count = 0;
/* sdcard */
MachineObject::SdcardState sdcard_state { NO_SDCARD };
MachineObject::SdcardState get_sdcard_state();
/* HMS */
std::vector<HMSItem> hms_list;
@ -523,6 +606,7 @@ public:
BBLSliceInfo* slice_info {nullptr};
boost::thread* get_slice_info_thread { nullptr };
int plate_index { -1 };
std::string m_gcode_file;
int gcode_file_prepare_percent = 0;
@ -531,26 +615,30 @@ public:
std::string subtask_name;
bool is_sdcard_printing();
bool has_sdcard();
bool has_timelapse();
bool has_recording();
bool is_timelapse();
bool is_recording_enable();
bool is_recording();
MachineObject(NetworkAgent* agent, std::string name, std::string id, std::string ip);
~MachineObject();
/* command commands */
int command_get_version();
int command_get_version(bool with_retry = true);
int command_request_push_all();
int command_pushing(std::string cmd);
/* command upgrade */
int command_upgrade_confirm();
int command_consistency_upgrade_confirm();
int command_upgrade_firmware(FirmwareInfo info);
int command_upgrade_module(std::string url, std::string module_type, std::string version);
/* control apis */
int command_xyz_abs();
int command_auto_leveling();
int command_go_home();
int command_control_fan(FanType fan_type, bool on_off);
int command_control_fan_val(FanType fan_type, int val);
int command_task_abort();
int command_task_pause();
int command_task_resume();
@ -559,7 +647,9 @@ public:
// ams controls
int command_ams_switch(int tray_index, int old_temp = 210, int new_temp = 210);
int command_ams_change_filament(int tray_id, int old_temp = 210, int new_temp = 210);
int command_ams_user_settings(int ams_id, bool start_read_opt, bool tray_read_opt);
int command_ams_user_settings(int ams_id, bool start_read_opt, bool tray_read_opt, bool remain_flag = false);
int command_ams_user_settings(int ams_id, AmsOptionType op, bool value);
int command_ams_switch_filament(bool switch_filament);
int command_ams_calibrate(int ams_id);
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);
@ -571,20 +661,27 @@ public:
// set printing speed
int command_set_printing_speed(PrintingSpeedLevel lvl);
// set print option
int command_set_printing_option(bool auto_recovery);
// axis string is X, Y, Z, E
int command_axis_control(std::string axis, double unit = 1.0f, double value = 1.0f, int speed = 3000);
// calibration printer
int command_start_calibration();
bool is_support_command_calibration();
int command_start_calibration(bool vibration, bool bed_leveling, bool xcam_cali);
int command_unload_filament();
// camera control
int command_ipcam_record(bool on_off);
int command_ipcam_timelapse(bool on_off);
int command_xcam_control(std::string module_name, bool on_off, bool print_halt);
int command_ipcam_resolution_set(std::string resolution);
int command_xcam_control(std::string module_name, bool on_off, std::string lvl = "");
int command_xcam_control_ai_monitoring(bool on_off, std::string lvl);
int command_xcam_control_first_layer_inspector(bool on_off, bool print_halt);
int command_xcam_control_spaghetti_detector(bool on_off, bool print_halt);
int command_xcam_control_buildplate_marker_detector(bool on_off);
int command_xcam_control_auto_recovery_step_loss(bool on_off);
/* common apis */
inline bool is_local() { return !dev_ip.empty(); }
@ -609,6 +706,7 @@ public:
bool is_online() { return m_is_online; }
bool is_info_ready();
bool is_function_supported(PrinterFunction func);
std::vector<std::string> get_resolution_supported();
bool is_support_print_with_timelapse();
@ -645,6 +743,8 @@ public:
std::map<std::string, MachineObject*> localMachineList; /* dev_id -> MachineObject*, localMachine SSDP */
std::map<std::string, MachineObject*> userMachineList; /* dev_id -> MachineObject* cloudMachine of User */
void check_pushing();
MachineObject* get_default_machine();
MachineObject* get_local_selected_machine();
MachineObject* get_local_machine(std::string dev_id);
@ -677,8 +777,11 @@ public:
static json function_table;
static std::string parse_printer_type(std::string type_str);
static std::string get_printer_display_name(std::string type_str);
static std::string get_printer_thumbnail_img(std::string type_str);
static bool is_function_supported(std::string type_str, std::string function_name);
static std::vector<std::string> get_resolution_supported(std::string type_str);
static bool get_bed_temperature_limit(std::string type_str, int& limit);
static bool load_functional_config(std::string config_file);
};

View file

@ -114,6 +114,7 @@ DownloadProgressDialog::DownloadProgressDialog(wxString title)
CentreOnParent();
Bind(wxEVT_CLOSE_WINDOW, &DownloadProgressDialog::on_close, this);
wxGetApp().UpdateDlgDarkUI(this);
}
wxString DownloadProgressDialog::format_text(wxStaticText* st, wxString str, int warp)
@ -141,12 +142,12 @@ 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 = make_job(m_status_bar);
m_upgrade_job->set_event_handle(this);
m_status_bar->set_progress(0);
Bind(EVT_UPGRADE_NETWORK_SUCCESS, [this](wxCommandEvent& evt) {
m_status_bar->change_button_label(_L("Finish"));
wxGetApp().restart_networking();
m_status_bar->change_button_label(_L("Close"));
on_finish();
m_status_bar->set_cancel_callback_fina(
[this]() {
this->Close();
@ -205,4 +206,8 @@ void DownloadProgressDialog::on_dpi_changed(const wxRect &suggested_rect) {}
void DownloadProgressDialog::update_release_note(std::string release_note, std::string version) {}
std::shared_ptr<UpgradeNetworkJob> DownloadProgressDialog::make_job(std::shared_ptr<ProgressIndicator> pri) { return std::make_shared<UpgradeNetworkJob>(pri); }
void DownloadProgressDialog::on_finish() { wxGetApp().restart_networking(); }
}} // namespace Slic3r::GUI

View file

@ -50,7 +50,9 @@ public:
std::shared_ptr<UpgradeNetworkJob> m_upgrade_job { nullptr };
wxPanel * m_panel_download;
protected:
virtual std::shared_ptr<UpgradeNetworkJob> make_job(std::shared_ptr<ProgressIndicator> pri);
virtual void on_finish();
};

View file

@ -313,13 +313,18 @@ wxWindow* BitmapChoiceRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelR
labelRect.GetTopLeft(), wxSize(labelRect.GetWidth(), -1),
0, nullptr, wxCB_READONLY | CB_NO_DROP_ICON | CB_NO_TEXT);
c_editor->GetDropDown().SetUseContentWidth(true);
// BBS
if (has_default_extruder && has_default_extruder())
c_editor->Append(_L("default"), *get_default_extruder_color_icon());
for (size_t i = 0; i < icons.size(); i++)
c_editor->Append(wxString::Format("%d", i+1), *icons[i]);
c_editor->SetSelection(atoi(data.GetText().c_str()) - 1);
if (has_default_extruder && has_default_extruder())
c_editor->SetSelection(atoi(data.GetText().c_str()));
else
c_editor->SetSelection(atoi(data.GetText().c_str()) - 1);
#ifdef __linux__
c_editor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
// to avoid event propagation to other sidebar items

View file

@ -153,11 +153,13 @@ public:
void set_can_create_editor_ctrl_function(std::function<bool()> can_create_fn) { can_create_editor_ctrl = can_create_fn; }
void set_default_extruder_idx(std::function<int()> default_extruder_idx_fn) { get_default_extruder_idx = default_extruder_idx_fn; }
void set_has_default_extruder(std::function<bool()> has_default_extruder_fn) { has_default_extruder = has_default_extruder_fn; }
private:
DataViewBitmapText m_value;
std::function<bool()> can_create_editor_ctrl { nullptr };
std::function<int()> get_default_extruder_idx{ nullptr };
std::function<bool()> has_default_extruder{ nullptr };
};

View file

@ -26,6 +26,7 @@
#include "Widgets/TextInput.hpp"
#include "Widgets/SpinInput.hpp"
#include "Widgets/ComboBox.hpp"
#include "Widgets/TextCtrl.h"
#ifdef __WXOSX__
#define wxOSX true
@ -730,7 +731,7 @@ void CheckBox::BUILD() {
// BBS: use ::CheckBox
auto temp = new ::CheckBox(m_parent);
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
temp->SetBackgroundColour(*wxWHITE);
//temp->SetBackgroundColour(*wxWHITE);
temp->SetValue(check_value);
temp->Bind(wxEVT_TOGGLEBUTTON, ([this](wxCommandEvent & e) {
@ -986,13 +987,46 @@ using choice_ctrl = ::ComboBox; // BBS
using choice_ctrl = ::ComboBox; // BBS
#endif // __WXOSX__
void Choice::BUILD() {
static std::map<std::string, DynamicList*> dynamic_lists;
void Choice::register_dynamic_list(std::string const &optname, DynamicList *list) { dynamic_lists.emplace(optname, list); }
void DynamicList::update()
{
for (auto c : m_choices) apply_on(c);
}
void DynamicList::add_choice(Choice *choice)
{
auto iter = std::find(m_choices.begin(), m_choices.end(), choice);
if (iter != m_choices.end()) return;
apply_on(choice);
m_choices.push_back(choice);
}
void DynamicList::remove_choice(Choice *choice)
{
auto iter = std::find(m_choices.begin(), m_choices.end(), choice);
if (iter != m_choices.end()) m_choices.erase(iter);
}
Choice::~Choice()
{
if (m_list) { m_list->remove_choice(this); }
}
void Choice::BUILD()
{
wxSize size(def_width_wider() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
choice_ctrl* temp;
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open) {
auto dynamic_list = dynamic_lists.find(m_opt.opt_key);
if (dynamic_list != dynamic_lists.end())
m_list = dynamic_list->second;
if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open
&& m_list == nullptr) {
m_is_editable = true;
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER);
}
@ -1009,6 +1043,7 @@ void Choice::BUILD() {
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY);
#endif //__WXOSX__
}
temp->GetDropDown().SetUseContentWidth(true);
if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double) temp->GetTextCtrl()->GetSize().GetHeight() / m_em_unit;
@ -1035,11 +1070,25 @@ void Choice::BUILD() {
temp->Append(el);
} else {
// Append localized enum_labels
for (auto el : m_opt.enum_labels)
temp->Append(_(el));
int i = 0;
boost::filesystem::path image_path(Slic3r::resources_dir());
image_path /= "images";
for (auto el : m_opt.enum_labels) {
auto icon_name = "param_" + m_opt.enum_values[i];
if (boost::filesystem::exists(image_path / (icon_name + ".svg"))) {
ScalableBitmap bm(temp, icon_name, 24);
temp->Append(_(el), bm.bmp());
} else {
temp->Append(_(el));
}
++i;
}
}
set_selection();
}
} else if (m_list) {
m_list->add_choice(this);
set_selection();
}
temp->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) {
if (m_suppress_scroll && !m_is_dropped)
@ -1212,7 +1261,9 @@ void Choice::set_value(const boost::any& value, bool change_event)
break;
++idx;
}
if (idx == enums.size()) {
if (m_list)
field->SetSelection(m_list->index_of(text_value));
else if (idx == enums.size()) {
// For editable Combobox under OSX is needed to set selection to -1 explicitly,
// otherwise selection doesn't be changed
field->SetSelection(-1);
@ -1332,7 +1383,10 @@ boost::any& Choice::get_value()
}
else if (m_opt.gui_type == ConfigOptionDef::GUIType::f_enum_open || m_opt.gui_type == ConfigOptionDef::GUIType::i_enum_open) {
const int ret_enum = field->GetSelection();
if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings ||
if (m_list) {
ret_str = m_list->get_value(ret_enum);
get_value_by_opt_type(ret_str);
} else if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings ||
(ret_str != m_opt.enum_values[ret_enum] && ret_str != _(m_opt.enum_labels[ret_enum])))
// modifies ret_string!
get_value_by_opt_type(ret_str);
@ -1393,6 +1447,20 @@ void Choice::msw_rescale()
field->SetValue(selection) :
field->SetSelection(idx);
#else
if (!m_opt.enum_labels.empty()) {
boost::filesystem::path image_path(Slic3r::resources_dir());
image_path /= "images";
int i = 0;
auto temp = dynamic_cast<choice_ctrl *>(window);
for (auto el : m_opt.enum_values) {
auto icon_name = "param_" + m_opt.enum_values[i];
if (boost::filesystem::exists(image_path / (icon_name + ".svg"))) {
ScalableBitmap bm(window, icon_name, 24);
temp->SetItemBitmap(i, bm.bmp());
}
++i;
}
}
auto size = wxSize(def_width_wider() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0)
size.SetHeight(m_opt.height * m_em_unit);
@ -1444,14 +1512,21 @@ void ColourPicker::set_undef_value(wxColourPickerCtrl* field)
field->SetColour(wxTransparentColour);
wxButton* btn = dynamic_cast<wxButton*>(field->GetPickerCtrl());
wxBitmap bmp = btn->GetBitmap();
wxImage image(btn->GetBitmap().GetSize());
image.InitAlpha();
memset(image.GetAlpha(), 0, image.GetWidth() * image.GetHeight());
wxBitmap bmp(std::move(image));
wxMemoryDC dc(bmp);
if (!dc.IsOk()) return;
dc.SetTextForeground(*wxWHITE);
dc.SetFont(wxGetApp().normal_font());
#ifdef __WXMSW__
wxGCDC dc2(dc);
#else
wxDC &dc2(dc);
#endif
dc2.SetPen(wxPen("#F1754E", 1));
const wxRect rect = wxRect(0, 0, bmp.GetWidth(), bmp.GetHeight());
dc.DrawLabel("undef", rect, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL);
dc2.DrawLine(rect.GetLeftBottom(), rect.GetTopRight());
dc.SelectObject(wxNullBitmap);
btn->SetBitmapLabel(bmp);
@ -1529,8 +1604,8 @@ void PointCtrl::BUILD()
#ifdef _WIN32
style |= wxBORDER_SIMPLE;
#endif
x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, style);
y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, style);
x_textctrl = new ::TextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, style);
y_textctrl = new ::TextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, style);
if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double)x_textctrl->GetSize().GetHeight() / m_em_unit;
@ -1769,5 +1844,4 @@ boost::any& SliderCtrl::get_value()
}
} // GUI
} // Slic3r
}} // Slic3r

View file

@ -335,13 +335,36 @@ public:
wxWindow* getWindow() override { return window; }
};
class Choice;
class DynamicList
{
public:
virtual ~DynamicList() {}
virtual void apply_on(Choice * choice) = 0;
virtual wxString get_value(int index) = 0;
virtual int index_of(wxString value) = 0;
protected:
void update();
std::vector<Choice*> m_choices;
private:
friend class Choice;
void add_choice(Choice *choice);
void remove_choice(Choice *choice);
};
class Choice : public Field {
using Field::Field;
DynamicList * m_list = nullptr;
public:
Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~Choice() {}
~Choice();
static void register_dynamic_list(std::string const &optname, DynamicList *list);
wxWindow* window{ nullptr };
void BUILD() override;

File diff suppressed because it is too large Load diff

View file

@ -614,6 +614,7 @@ public:
Vec3f m_world_offset;
float m_z_offset{ 0.5f };
bool m_visible{ true };
bool m_is_dark = false;
public:
float m_scale = 1.0f;
@ -630,6 +631,7 @@ public:
//BBS: GUI refactor: add canvas size
void render(int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves, uint64_t curr_line_id) const;
void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; }
};
class GCodeWindow
@ -689,7 +691,7 @@ public:
float m_scale = 1.0;
//BBS: GUI refactor: add canvas size
void render(float legend_height, int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves) const;
void render(const bool has_render_path, float legend_height, int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves) const;
};
struct ETools
@ -771,11 +773,13 @@ private:
bool m_contained_in_bed{ true };
mutable bool m_no_render_path { false };
bool m_is_dark = false;
public:
GCodeViewer();
~GCodeViewer();
void on_change_color_mode(bool is_dark);
float m_scale = 1.0;
void set_scale(float scale = 1.0);
void init(ConfigOptionMode mode, Slic3r::PresetBundle* preset_bundle);

File diff suppressed because it is too large Load diff

View file

@ -188,6 +188,9 @@ wxDECLARE_EVENT(EVT_GLCANVAS_TOOLBAR_HIGHLIGHTER_TIMER, wxTimerEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_GIZMO_HIGHLIGHTER_TIMER, wxTimerEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE, SimpleEvent);
wxDECLARE_EVENT(EVT_CUSTOMEVT_TICKSCHANGED, wxCommandEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
class GLCanvas3D
{
@ -198,10 +201,116 @@ class GLCanvas3D
static float DEFAULT_BG_LIGHT_COLOR[3];
static float ERROR_BG_LIGHT_COLOR[3];
static float DEFAULT_BG_LIGHT_COLOR_LIGHT[3];
static float ERROR_BG_LIGHT_COLOR_LIGHT[3];
static float DEFAULT_BG_LIGHT_COLOR_DARK[3];
static float ERROR_BG_LIGHT_COLOR_DARK[3];
static void update_render_colors();
static void load_render_colors();
class LayersEditing
{
public:
enum EState : unsigned char
{
Unknown,
Editing,
Completed,
Num_States
};
static const float THICKNESS_BAR_WIDTH;
private:
bool m_enabled{ false };
unsigned int m_z_texture_id{ 0 };
// Not owned by LayersEditing.
const DynamicPrintConfig* m_config{ nullptr };
// ModelObject for the currently selected object (Model::objects[last_object_id]).
const ModelObject* m_model_object{ nullptr };
// Maximum z of the currently selected object (Model::objects[last_object_id]).
float m_object_max_z{ 0.0f };
// Owned by LayersEditing.
SlicingParameters* m_slicing_parameters{ nullptr };
std::vector<double> m_layer_height_profile;
mutable float m_adaptive_quality{ 0.5f };
mutable HeightProfileSmoothingParams m_smooth_params;
static float s_overlay_window_width;
struct LayersTexture
{
// Texture data
std::vector<char> data;
// Width of the texture, top level.
size_t width{ 0 };
// Height of the texture, top level.
size_t height{ 0 };
// For how many levels of detail is the data allocated?
size_t levels{ 0 };
// Number of texture cells allocated for the height texture.
size_t cells{ 0 };
// Does it need to be refreshed?
bool valid{ false };
};
LayersTexture m_layers_texture;
public:
EState state{ Unknown };
float band_width{ 2.0f };
float strength{ 0.005f };
int last_object_id{ -1 };
float last_z{ 0.0f };
LayerHeightEditActionType last_action{ LAYER_HEIGHT_EDIT_ACTION_INCREASE };
LayersEditing() = default;
~LayersEditing();
void init();
void set_config(const DynamicPrintConfig* config);
void select_object(const Model& model, int object_id);
bool is_allowed() const;
bool is_enabled() const;
void set_enabled(bool enabled);
void show_tooltip_information(const GLCanvas3D& canvas, std::map<wxString, wxString> captions_texts, float x, float y);
void render_variable_layer_height_dialog(const GLCanvas3D& canvas);
void render_overlay(const GLCanvas3D& canvas);
void render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes);
void adjust_layer_height_profile();
void accept_changes(GLCanvas3D& canvas);
void reset_layer_height_profile(GLCanvas3D& canvas);
void adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor);
void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params);
static float get_cursor_z_relative(const GLCanvas3D& canvas);
static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);
static Rect get_bar_rect_screen(const GLCanvas3D& canvas);
static Rect get_bar_rect_viewport(const GLCanvas3D& canvas);
static float get_overlay_window_width() { return LayersEditing::s_overlay_window_width; }
float object_max_z() const { return m_object_max_z; }
std::string get_tooltip(const GLCanvas3D& canvas) const;
private:
bool is_initialized() const;
void generate_layer_height_texture();
void render_background_texture(const GLCanvas3D& canvas, const Rect& bar_rect);
void render_curve(const Rect& bar_rect);
void update_slicing_parameters();
static float thickness_bar_width(const GLCanvas3D& canvas);
};
struct Mouse
{
struct Drag
@ -385,6 +494,7 @@ public:
};
private:
bool m_is_dark = false;
wxGLCanvas* m_canvas;
wxGLContext* m_context;
Bed3D &m_bed;
@ -394,6 +504,7 @@ private:
unsigned int m_last_w, m_last_h;
bool m_in_render;
wxTimer m_timer;
LayersEditing m_layers_editing;
Mouse m_mouse;
GLGizmosManager m_gizmos;
//BBS: GUI refactor: GLToolbar
@ -593,6 +704,8 @@ public:
bool init();
void post_event(wxEvent &&event);
void on_change_color_mode(bool is_dark, bool reinit = true);
const bool get_dark_mode_status() { return m_is_dark; }
void set_as_dirty();
void requires_check_outside_state() { m_requires_check_outside_state = true; }
@ -655,8 +768,16 @@ public:
BoundingBoxf3 scene_bounding_box() const;
BoundingBoxf3 plate_scene_bounding_box(int plate_idx) const;
bool is_layers_editing_enabled() const;
bool is_layers_editing_allowed() const;
void reset_layer_height_profile();
void adaptive_layer_height_profile(float quality_factor);
void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params);
bool is_reload_delayed() const;
void enable_layers_editing(bool enable);
void enable_legend_texture(bool enable);
void enable_picking(bool enable);
void enable_moving(bool enable);
@ -914,6 +1035,8 @@ public:
bool is_object_sinking(int object_idx) const;
void _perform_layer_editing_action(wxMouseEvent* evt = nullptr);
// Convert the screen space coordinate to an object space coordinate.
// If the Z screen space coordinate is not provided, a depth buffer value is substituted.
Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr);
@ -921,6 +1044,7 @@ public:
private:
bool _is_shown_on_screen() const;
void _switch_toolbars_icon_filename();
bool _init_toolbars();
bool _init_main_toolbar();
bool _init_select_plate_toolbar();
@ -1030,9 +1154,11 @@ private:
bool _deactivate_arrange_menu();
//BBS: add deactivate_orient_menu
bool _deactivate_orient_menu();
//BBS: add _deactivate_layersediting_menu
bool _deactivate_layersediting_menu();
// BBS FIXME
float get_overlay_window_width() { return 100.f; }
float get_overlay_window_width() { return 0; /*LayersEditing::get_overlay_window_width();*/ }
static std::vector<std::array<float, 4>> _parse_colors(const std::vector<std::string>& colors);
};

View file

@ -45,6 +45,7 @@ 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
//if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 0)) {
if (0) {
valid &= append_shader("gouraud", { "gouraud_130.vs", "gouraud_130.fs" }
#if ENABLE_ENVIRONMENT_MAP
@ -69,10 +70,18 @@ std::pair<bool, std::string> GLShadersManager::init()
// Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU.
// Since macOS 12 (Monterey), this issue with the opposite direction on Apple's Arm CPU seems to be fixed, and computed
// triangle normals inside fragment shader have the right direction.
if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12)
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});
else
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"});
if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12) {
//if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 0))
valid &= append_shader("mm_gouraud", {"mm_gouraud_130.vs", "mm_gouraud_130.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});
//else
// valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});
}
else {
//if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 0))
valid &= append_shader("mm_gouraud", {"mm_gouraud_wireframe.vs", "mm_gouraud_wireframe.fs"});
//else
// valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"});
}
//BBS: add shader for outline
valid &= append_shader("outline", { "outline.vs", "outline.fs" });

View file

@ -26,7 +26,8 @@
#include "nanosvg/nanosvgrast.h"
#include "libslic3r/Utils.hpp"
#include "GUI_App.hpp"
#include <wx/dcgraph.h>
namespace Slic3r {
namespace GUI {
@ -244,6 +245,8 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
if (filenames.empty() || states.empty() || sprite_size_px == 0)
return false;
bool dark_mode = wxGetApp().app_config->get("dark_color_mode") == "1";
// every tile needs to have a 1px border around it to avoid artifacts when linear sampling on its edges
unsigned int sprite_size_px_ex = sprite_size_px + 1;
@ -262,14 +265,23 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
std::vector<unsigned char> data(n_pixels * 4, 0);
std::vector<unsigned char> sprite_data(sprite_bytes, 0);
std::vector<unsigned char> sprite_white_only_data(sprite_bytes, 0);
std::vector<unsigned char> sprite_gray_only_data(sprite_bytes, 0);
std::vector<unsigned char> sprite_white_only_data(sprite_bytes, 0); // normal
std::vector<unsigned char> sprite_gray_only_data(sprite_bytes, 0); // disable
std::vector<unsigned char> output_data(sprite_bytes, 0);
//BBS
std::vector<unsigned char> pressed_data(sprite_bytes, 0);
std::vector<unsigned char> pressed_data(sprite_bytes, 0); // (gizmo) pressed
std::vector<unsigned char> disable_data(sprite_bytes, 0);
std::vector<unsigned char> hover_data(sprite_bytes, 0);
std::vector<unsigned char> hover_data(sprite_bytes, 0); // hover
const unsigned char pressed_color[3] = {255, 255, 255};
const unsigned char hover_color[3] = {255, 255, 255};
const unsigned char normal_color[3] = {43, 52, 54};
const unsigned char disable_color[3] = {200, 200, 200};
const unsigned char pressed_color_dark[3] = {60, 60, 65};
const unsigned char hover_color_dark[3] = {60, 60, 65};
const unsigned char normal_color_dark[3] = {182, 182, 182};
const unsigned char disable_color_dark[3] = {76, 76, 85};
NSVGrasterizer* rast = nsvgCreateRasterizer();
if (rast == nullptr) {
@ -299,12 +311,13 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
::memcpy((void*)pressed_data.data(), (const void*)sprite_data.data(), sprite_bytes);
for (int i = 0; i < sprite_n_pixels; ++i) {
int offset = i * 4;
if (pressed_data.data()[offset + 0] == 0 &&
if (pressed_data.data()[offset + 0] == 0 &&
pressed_data.data()[offset + 1] == 0 &&
pressed_data.data()[offset + 2] == 0) {
::memset((void*)&pressed_data.data()[offset], 238, 3);
pressed_data.data()[offset + 3] = (unsigned char) 225;
}
hover_data.data()[offset + 0] = dark_mode ? pressed_color_dark[0] : pressed_color[0];
hover_data.data()[offset + 0] = dark_mode ? pressed_color_dark[1] : pressed_color[1];
hover_data.data()[offset + 0] = dark_mode ? pressed_color_dark[2] : pressed_color[2];
}
}
::memcpy((void*)disable_data.data(), (const void*)sprite_data.data(), sprite_bytes);
@ -319,23 +332,23 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
int offset = i * 4;
if (hover_data.data()[offset + 0] == 0 &&
hover_data.data()[offset + 1] == 0 &&
hover_data.data()[offset + 2] == 0)
hover_data.data()[offset + 2] == 0)
{
::memset((void *) &hover_data.data()[offset], 238, 3);
hover_data.data()[offset + 3] = (unsigned char) 75;
hover_data.data()[offset + 0] = dark_mode ? hover_color_dark[0] : hover_color[0];
hover_data.data()[offset + 1] = dark_mode ? hover_color_dark[1] : hover_color[1];
hover_data.data()[offset + 2] = dark_mode ? hover_color_dark[2] : hover_color[2];
}
}
::memcpy((void*)sprite_white_only_data.data(), (const void*)sprite_data.data(), sprite_bytes);
for (int i = 0; i < sprite_n_pixels; ++i) {
int offset = i * 4;
if (sprite_white_only_data.data()[offset + 0] != 0 ||
sprite_white_only_data.data()[offset + 1] != 0 ||
sprite_white_only_data.data()[offset + 2] != 0){
sprite_white_only_data.data()[offset + 0] = (unsigned char) 43;
sprite_white_only_data.data()[offset + 1] = (unsigned char) 52;
sprite_white_only_data.data()[offset + 2] = (unsigned char) 54;
sprite_white_only_data.data()[offset + 1] != 0 ||
sprite_white_only_data.data()[offset + 2] != 0) {
sprite_white_only_data.data()[offset + 0] = dark_mode ? normal_color_dark[0] : normal_color[0];
sprite_white_only_data.data()[offset + 1] = dark_mode ? normal_color_dark[1] : normal_color[1];
sprite_white_only_data.data()[offset + 2] = dark_mode ? normal_color_dark[2] : normal_color[2];
}
}
@ -343,9 +356,11 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
for (int i = 0; i < sprite_n_pixels; ++i) {
int offset = i * 4;
if (sprite_gray_only_data.data()[offset + 0] != 0 ||
sprite_gray_only_data.data()[offset + 1] != 0 ||
sprite_gray_only_data.data()[offset + 2] != 0 ) {
::memset((void*)&sprite_gray_only_data.data()[offset], 200, 3);
sprite_gray_only_data.data()[offset + 1] != 0 ||
sprite_gray_only_data.data()[offset + 2] != 0) {
sprite_gray_only_data.data()[offset + 0] = dark_mode ? disable_color_dark[0] : disable_color[0];
sprite_gray_only_data.data()[offset + 1] = dark_mode ? disable_color_dark[1] : disable_color[1];
sprite_gray_only_data.data()[offset + 2] = dark_mode ? disable_color_dark[2] : disable_color[2];
}
}
@ -454,7 +469,13 @@ void GLTexture::reset()
m_original_width = m_original_height = 0;
}
bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &font, wxColor background, wxColor foreground)
bool GLTexture::generate_from_text_string(const std::string& text_str, wxFont &font, wxColor background, wxColor foreground)
{
int w,h,hl;
return generate_from_text(text_str, font, background, foreground);
}
bool GLTexture::generate_from_text(const std::string &text_str, wxFont &font, wxColor background, wxColor foreground)
{
if (text_str.empty())
{
@ -474,7 +495,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
m_original_width = (int)w;
m_original_height = (int)h;
m_width = (int)next_highest_power_of_2((uint32_t)w);
m_height = (int)next_highest_power_of_2((uint32_t)h);
m_height = (int)next_highest_power_of_2((uint32_t)h);
// generates bitmap
wxBitmap bitmap(m_width, m_height);
@ -485,7 +506,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
// draw message
memDC.SetTextForeground(*wxWHITE);
memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER);
memDC.DrawLabel(msg, wxRect(0, 0, m_original_width, m_original_height), wxALIGN_CENTER);
memDC.SelectObject(wxNullBitmap);
@ -494,7 +515,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
// prepare buffer
std::vector<unsigned char> data(4 * m_width * m_height, 0);
const unsigned char *src = image.GetData();
const unsigned char* src = image.GetData();
/* for debug use
std::ofstream fout;
fout.open(text_str+std::to_string(m_width)+"_"+std::to_string(m_height)+".rgb", std::ios::out);
@ -506,7 +527,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
*dst++ = foreground.Red();
*dst++ = foreground.Green();
*dst++ = foreground.Blue();
*dst++ = (unsigned char)std::min<int>(255, *src);
*dst++ = (unsigned char)std::min<int>(255, *src);
src += 3;
}
}
@ -516,9 +537,9 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
glsafe(::glGenTextures(1, &m_id));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
if (GLEW_EXT_texture_compression_s3tc)
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
else
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
@ -527,6 +548,111 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
return true;
}
bool GLTexture::generate_texture_from_text(const std::string& text_str, wxFont& font, int& ww, int& hh, int& hl, wxColor background, wxColor foreground)
{
if (text_str.empty())
{
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":no text string, should not happen\n";
return false;
}
wxString msg = _(text_str);
wxMemoryDC memDC;
memDC.SetFont(font);
// calculates texture size
wxCoord w, h, ll;
wxClientDC dc(wxGetApp().GetTopWindow());
dc.SetFont(font);
dc.GetMultiLineTextExtent(msg, &w, &h, &ll, &font);
m_original_width = (int)w;
m_original_height = (int)h;
m_width = (int)next_highest_power_of_2((uint32_t)w);
m_height = (int)next_highest_power_of_2((uint32_t)h);
ww = m_width;
hh = m_height;
hl = ll;
// generates bitmap
wxBitmap bitmap(m_width, m_height);
memDC.SelectObject(bitmap);
memDC.SetBackground(wxBrush(background));
memDC.Clear();
// draw message
memDC.SetTextForeground(*wxWHITE);
wxGCDC dc2(memDC);
dc2.SetFont(font);
dc2.SetBackground(wxBrush(background));
dc2.SetTextForeground(*wxWHITE);
dc2.DrawLabel(msg, wxRect(0, 0, m_width, m_height), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
memDC.SelectObject(wxNullBitmap);
// Convert the bitmap into a linear data ready to be loaded into the GPU.
wxImage image = bitmap.ConvertToImage();
// prepare buffer
std::vector<unsigned char> data(4 * m_width * m_height, 0);
const unsigned char* src = image.GetData();
/* for debug use
std::ofstream fout;
fout.open(text_str+std::to_string(m_width)+"_"+std::to_string(m_height)+".rgb", std::ios::out);
fout.write((const char*)src, 3 * m_width * m_height);
fout.close();*/
bool found = false;
for (int h = 0; h < m_height; ++h) {
unsigned char* dst = data.data() + 4 * h * m_width;
for (int w = 0; w < m_width; ++w) {
*dst++ = foreground.Red();
*dst++ = foreground.Green();
*dst++ = foreground.Blue();
*dst++ = (unsigned char)std::min<int>(255, *src);
if ((*src) != background.Red() && !found) {
found = true;
if (m_height - h < font.GetPointSize())
return false;
}
src += 3;
}
}
if (!found)
return false;
found = false;
src -= 3;
for (int h = m_height; h > 0; --h) {
for (int w = m_width; w > 0; --w) {
if ((*src) != background.Red() && !found) {
found = true;
if (h < font.GetPointSize())
return false;
}
src -= 3;
}
}
if (!found)
return false;
// sends buffer to gpu
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(::glGenTextures(1, &m_id));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
if (GLEW_EXT_texture_compression_s3tc)
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
else
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
return true;
}
void GLTexture::render_texture(unsigned int tex_id, float left, float right, float bottom, float top)
{
@ -776,7 +902,7 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, boo
int lod_w = m_width;
int lod_h = m_height;
GLint level = 0;
while (lod_w > 1 || lod_h > 1) {
while (lod_w >= 4 && lod_h >= 4) {
++level;
lod_w = std::max(lod_w / 2, 1);

View file

@ -106,7 +106,10 @@ namespace GUI {
//BBS: add generate logic for text strings
int m_original_width;
int m_original_height;
bool generate_from_text_string(const std::string &text_str, wxFont &font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
bool generate_texture_from_text(const std::string& text_str, wxFont& font, int& ww, int& hh, int &hl, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
bool generate_from_text(const std::string& text_str, wxFont& font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
bool generate_from_text_string(const std::string& text_str, wxFont& font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
unsigned int get_id() const { return m_id; }
int get_width() const { return m_width; }

View file

@ -27,8 +27,10 @@ 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_EXPORT_ALL_SLICED_FILE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_PRINT_SELECT, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER_ALL, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
@ -40,13 +42,13 @@ wxDEFINE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_CUT, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_LAYERSEDITING, SimpleEvent);
//BBS: add clone event
wxDEFINE_EVENT(EVT_GLTOOLBAR_CLONE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_VOLUMES, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_LAYERSEDITING, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_FILLCOLOR, IntEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_SELECT_SLICED_PLATE, wxCommandEvent);
@ -267,9 +269,6 @@ GLToolbar::~GLToolbar()
bool GLToolbar::init(const BackgroundTexture::Metadata& background_texture)
{
if (m_background_texture.texture.get_id() != 0)
return true;
std::string path = resources_dir() + "/images/";
bool res = false;

View file

@ -27,8 +27,10 @@ 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_EXPORT_ALL_SLICED_FILE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_PRINT_SELECT, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_SEND_TO_PRINTER_ALL, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
@ -40,6 +42,7 @@ wxDECLARE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_CUT, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_LAYERSEDITING, SimpleEvent);
//BBS: add clone event
wxDECLARE_EVENT(EVT_GLTOOLBAR_CLONE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
@ -183,6 +186,7 @@ public:
const std::string& get_name() const { return m_data.name; }
const std::string& get_icon_filename() const { return m_data.icon_filename; }
void set_icon_filename(const std::string& filename) { m_data.icon_filename = filename; }
const std::string& get_tooltip() const { return m_data.tooltip; }
const std::string& get_additional_tooltip() const { return m_data.additional_tooltip; }
void set_additional_tooltip(const std::string& text) { m_data.additional_tooltip = text; }
@ -354,6 +358,7 @@ public:
Layout::EType get_layout_type() const;
void set_layout_type(Layout::EType type);
void set_icon_dirty() { m_icons_texture_dirty = true; }
Layout::EHorizontalOrientation get_horizontal_orientation() const { return m_layout.horizontal_orientation; }
void set_horizontal_orientation(Layout::EHorizontalOrientation orientation) { m_layout.horizontal_orientation = orientation; }
Layout::EVerticalOrientation get_vertical_orientation() const { return m_layout.vertical_orientation; }

View file

@ -4,7 +4,9 @@
#include "I18N.hpp"
#include "libslic3r/LocalesUtils.hpp"
#ifdef __APPLE__
#include "slic3r/Utils/MacDarkMode.hpp"
#endif
#include <string>
#include <boost/algorithm/string.hpp>
@ -545,11 +547,9 @@ void desktop_open_any_folder( const std::string path )
#ifdef _WIN32
const wxString widepath = from_u8(path);
const wchar_t *argv[] = {L"explorer", widepath.GetData(), nullptr};
::wxExecute(const_cast<wchar_t **>(argv), wxEXEC_ASYNC, nullptr);
::wxExecute(L"explorer /select," + widepath, wxEXEC_ASYNC, nullptr);
#elif __APPLE__
const char *argv[] = {"open", path.data(), nullptr};
::wxExecute(const_cast<char **>(argv), wxEXEC_ASYNC, nullptr);
openFolderForFile(from_u8(path));
#else
const char *argv[] = {"xdg-open", path.data(), nullptr};

File diff suppressed because it is too large Load diff

View file

@ -26,9 +26,16 @@
#include <mutex>
#include <stack>
#define BBL_HAS_FIRST_PAGE 1
//#define BBL_HAS_FIRST_PAGE 1
#define STUDIO_INACTIVE_TIMEOUT 15*60*1000
#define LOG_FILES_MAX_NUM 30
#define TIMEOUT_CONNECT 15
#define TIMEOUT_RESPONSE 15
#define BE_UNACTED_ON 0x00200001
#ifndef _MSW_DARK_MODE
#define _MSW_DARK_MODE 1
#endif // _MSW_DARK_MODE
class wxMenuItem;
class wxMenuBar;
@ -65,6 +72,7 @@ class NotificationManager;
struct GUI_InitParams;
class ParamsDialog;
class HMSQuery;
class ModelMallDialog;
enum FileType
@ -219,14 +227,15 @@ private:
bool m_opengl_initialized{ false };
#endif
//#ifdef _WIN32
wxColour m_color_label_modified;
wxColour m_color_label_sys;
wxColour m_color_label_default;
wxColour m_color_window_default;
// BBS
//#ifdef _WIN32
wxColour m_color_highlight_label_default;
wxColour m_color_hovered_btn_label;
wxColour m_color_default_btn_label;
wxColour m_color_highlight_default;
wxColour m_color_selected_btn_bg;
bool m_force_colors_update { false };
@ -268,14 +277,15 @@ private:
std::shared_ptr<UpgradeNetworkJob> m_upgrade_network_job;
VersionInfo version_info;
static std::string version_display;
HMSQuery *hms_query { nullptr };
boost::thread m_sync_update_thread;
bool enable_sync = false;
bool m_is_dark_mode{ false };
bool m_adding_script_handler { false };
public:
std::string get_local_models_path();
bool OnInit() override;
bool initialized() const { return m_initialized; }
@ -315,8 +325,11 @@ public:
void update_label_colours();
// update color mode for window
void UpdateDarkUI(wxWindow *window, bool highlited = false, bool just_font = false);
void UpdateDarkUIWin(wxWindow* win);
void Update_dark_mode_flag();
// update color mode for whole dialog including all children
void UpdateDlgDarkUI(wxDialog* dlg, bool just_buttons_update = false);
void UpdateDlgDarkUI(wxDialog* dlg);
void UpdateFrameDarkUI(wxFrame* dlg);
// update color mode for DataViewControl
void UpdateDVCDarkUI(wxDataViewCtrl* dvc, bool highlited = false);
// update color mode for panel including all static texts controls
@ -362,6 +375,7 @@ public:
void import_model(wxWindow *parent, wxArrayString& input_files) const;
void load_gcode(wxWindow* parent, wxString& input_file) const;
wxString transition_tridid(int trid_id);
void ShowUserGuide();
void ShowDownNetPluginDlg();
void ShowUserLogin();
@ -377,7 +391,7 @@ public:
int request_user_unbind(std::string dev_id);
std::string handle_web_request(std::string cmd);
void handle_script_message(std::string msg);
void request_model_download(std::string import_json);
void request_model_download(std::string url, std::string filename);
void download_project(std::string project_id);
void request_project_download(std::string project_id);
void request_open_project(std::string project_id);
@ -386,6 +400,7 @@ public:
void handle_http_error(unsigned int status, std::string body);
void on_http_error(wxCommandEvent &evt);
void on_user_login(wxCommandEvent &evt);
void enable_user_preset_folder(bool enable);
// BBS
bool is_studio_active();
@ -399,6 +414,7 @@ public:
void enter_force_upgrade();
void set_skip_version(bool skip = true);
void no_new_version();
static std::string format_display_version();
void show_dialog(wxString msg);
void reload_settings();
void remove_user_presets();
@ -463,9 +479,15 @@ public:
ParamsDialog* params_dialog();
Model& model();
NotificationManager * notification_manager();
//BBS
ModelMallDialog* m_mall_home_dialog{ nullptr };
ModelMallDialog* m_mall_publish_dialog{ nullptr };
void load_url(wxString url);
void run_script(wxString js);
void open_mall_page_dialog();
void open_publish_page_dialog();
void remove_mall_system_dialog();
void run_script(wxString js);
bool is_adding_script_handler() { return m_adding_script_handler; }
void set_adding_script_handler(bool status) { m_adding_script_handler = status; }
@ -526,9 +548,9 @@ public:
void associate_files(std::wstring extend);
void disassociate_files(std::wstring extend);
#endif // __WXMSW__
std::string get_plugin_url(std::string country_code);
int download_plugin(InstallProgressFn pro_fn = nullptr, WasCancelledFn cancel_fn = nullptr);
int install_plugin(InstallProgressFn pro_fn = nullptr, WasCancelledFn cancel_fn = nullptr);
std::string get_plugin_url(std::string name, std::string country_code);
int download_plugin(std::string name, std::string package_name, InstallProgressFn pro_fn = nullptr, WasCancelledFn cancel_fn = nullptr);
int install_plugin(std::string name, std::string package_name, InstallProgressFn pro_fn = nullptr, WasCancelledFn cancel_fn = nullptr);
std::string get_http_url(std::string country_code);
bool is_compatibility_version();
bool check_networking_version();
@ -564,7 +586,7 @@ private:
};
DECLARE_APP(GUI_App)
wxDECLARE_EVENT(EVT_CONNECT_LAN_MODE_PRINT, wxCommandEvent);
} // GUI
} // Slic3r

View file

@ -50,15 +50,15 @@ static bool is_improper_category(const std::string& category, const int filament
static SettingsFactory::Bundle FREQ_SETTINGS_BUNDLE_FFF =
{
//BBS
{ L("Quality"), { "layer_height" , "adaptive_layer_height" } },
{ L("Quality"), { "layer_height" } },
{ L("Shell"), { "wall_loops", "top_shell_layers", "bottom_shell_layers"} },
{ L("Infill") , { "sparse_infill_density", "sparse_infill_pattern" } },
// BBS
{ L("Support") , { "enable_support", "support_type", "support_threshold_angle",
"support_base_pattern", "support_on_build_plate_only","support_critical_regions_only",
"support_base_pattern_spacing" } }
"support_base_pattern_spacing", "support_expansion"}},
//BBS
//{ L("Wipe options") , { "flush_into_infill", "flush_into_objects" } }
{ L("Flush options") , { "flush_into_infill", "flush_into_objects", "flush_into_support"} }
};
// pt_SLA
@ -72,14 +72,15 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::OBJECT_C
{
{ L("Quality"), {{"layer_height", "",1},
//{"initial_layer_print_height", "",2},
{"adaptive_layer_height", "",2},{"seam_position", "",3},
{"xy_hole_compensation", "",4}, {"xy_contour_compensation", "",5}, {"elefant_foot_compensation", "",6}
{"seam_position", "",2},
{"slice_closing_radius", "",3}, {"resolution", "",4},
{"xy_hole_compensation", "",5}, {"xy_contour_compensation", "",6}, {"elefant_foot_compensation", "",7}
}},
{ L("Support"), {{"brim_type", "",1},{"brim_width", "",2},{"brim_object_gap", "",3},
{"enable_support", "",4},{"support_type", "",5},{"support_threshold_angle", "",6},{"support_on_build_plate_only", "",7},
{"support_filament", "",8},{"support_interface_filament", "",9},
{"tree_support_branch_angle", "",10}, {"tree_support_wall_count", "",11},{"tree_support_with_infill", "",12},//tree support
{"support_top_z_distance", "",13},{"support_base_pattern", "",14},{"support_base_pattern_spacing", "",15},
{"support_filament", "",8},{"support_interface_filament", "",9},{"support_expansion", "",24},
{"tree_support_branch_angle", "",10}, {"tree_support_wall_count", "",11},//tree support
{"support_top_z_distance", "",13},{"support_bottom_z_distance", "",12},{"support_base_pattern", "",14},{"support_base_pattern_spacing", "",15},
{"support_interface_top_layers", "",16},{"support_interface_bottom_layers", "",17},{"support_interface_spacing", "",18},{"support_bottom_interface_spacing", "",19},
{"support_object_xy_distance", "",20}, {"bridge_no_support", "",21},{"max_bridge_length", "",22},{"support_critical_regions_only", "",23}
}},
@ -89,7 +90,7 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::OBJECT_C
std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::PART_CATEGORY_SETTINGS=
{
{ L("Quality"), {{"ironing_type", "",7},{"ironing_flow", "",8},{"ironing_spacing", "",9},{"bridge_flow", "",10}
{ L("Quality"), {{"ironing_type", "",8},{"ironing_flow", "",9},{"ironing_spacing", "",10},{"bridge_flow", "",11}
}},
{ L("Strength"), {{"wall_loops", "",1},{"top_shell_layers", L("Top Solid Layers"),1},{"top_shell_thickness", L("Top Minimum Shell Thickness"),1},
{"bottom_shell_layers", L("Bottom Solid Layers"),1}, {"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"),1},
@ -140,7 +141,7 @@ std::vector<SimpleSettingData> SettingsFactory::get_visible_options(const std::s
//Support
"enable_support", "support_type", "support_threshold_angle", "support_on_build_plate_only", "support_critical_regions_only", "enforce_support_layers",
//tree support
"tree_support_wall_count", "tree_support_with_infill",
"tree_support_wall_count",
//support
"support_top_z_distance", "support_base_pattern", "support_base_pattern_spacing", "support_interface_top_layers", "support_interface_bottom_layers", "support_interface_spacing", "support_bottom_interface_spacing", "support_object_xy_distance",
//adhesion
@ -438,7 +439,7 @@ void MenuFactory::append_menu_item_delete(wxMenu* menu)
[](wxCommandEvent&) { plater()->remove_selected(); }, "menu_delete", nullptr,
[]() { return plater()->can_delete(); }, m_parent);
#else
append_menu_item(menu, wxID_ANY, _L("Delete") + "\tDel", _L("Delete the selected object"),
append_menu_item(menu, wxID_ANY, _L("Delete") + "\tBackSpace", _L("Delete the selected object"),
[](wxCommandEvent&) { plater()->remove_selected(); }, "", nullptr,
[]() { return plater()->can_delete(); }, m_parent);
#endif
@ -723,6 +724,72 @@ void MenuFactory::append_menu_item_scale_selection_to_fit_print_volume(wxMenu* m
[](wxCommandEvent&) { plater()->scale_selection_to_fit_print_volume(); }, "", menu);
}
void MenuFactory::append_menu_items_flush_options(wxMenu* menu)
{
const wxString name = _L("Flush Options");
// Delete old menu item
const int item_id = menu->FindItem(name);
if (item_id != wxNOT_FOUND)
menu->Destroy(item_id);
bool show_flush_option_menu = false;
ObjectList* object_list = obj_list();
const Selection& selection = get_selection();
if (wxGetApp().plater()->get_partplate_list().get_curr_plate()->contains(selection.get_bounding_box())) {
auto plate_extruders = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_extruders();
for (auto extruder : plate_extruders) {
if (extruder != plate_extruders[0])
show_flush_option_menu = true;
}
}
if (!show_flush_option_menu)
return;
DynamicPrintConfig& global_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
ModelConfig& select_object_config = object_list->object(selection.get_object_idx())->config;
auto keys = select_object_config.keys();
for (auto key : FREQ_SETTINGS_BUNDLE_FFF["Flush options"]) {
if (find(keys.begin(), keys.end(), key) == keys.end()) {
const ConfigOption* option = global_config.option(key);
select_object_config.set_key_value(key, option->clone());
}
}
wxMenu* flush_options_menu = new wxMenu();
append_menu_check_item(flush_options_menu, wxID_ANY, _L("Flush into objects' infill"), "",
[&select_object_config](wxCommandEvent&) {
const ConfigOption* option = select_object_config.option(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][0]);
select_object_config.set_key_value(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][0], new ConfigOptionBool(!option->getBool()));
wxGetApp().obj_settings()->UpdateAndShow(true);
}, menu, []() {return true; }, [&select_object_config]() {const ConfigOption* option = select_object_config.option(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][0]); return option->getBool(); }, m_parent);
append_menu_check_item(flush_options_menu, wxID_ANY, _L("Flush into this object"), "",
[&select_object_config](wxCommandEvent&) {
const ConfigOption* option = select_object_config.option(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][1]);
select_object_config.set_key_value(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][1], new ConfigOptionBool(!option->getBool()));
wxGetApp().obj_settings()->UpdateAndShow(true);
}, menu, []() {return true; }, [&select_object_config]() {const ConfigOption* option = select_object_config.option(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][1]); return option->getBool(); }, m_parent);
append_menu_check_item(flush_options_menu, wxID_ANY, _L("Flush into objects' support"), "",
[&select_object_config](wxCommandEvent&) {
const ConfigOption* option = select_object_config.option(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][2]);
select_object_config.set_key_value(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][2], new ConfigOptionBool(!option->getBool()));
wxGetApp().obj_settings()->UpdateAndShow(true);
}, menu, []() {return true; }, [&select_object_config]() {const ConfigOption* option = select_object_config.option(FREQ_SETTINGS_BUNDLE_FFF["Flush options"][2]); return option->getBool(); }, m_parent);
size_t i = 0;
for (auto node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext())
{
i++;
wxMenuItem* item = node->GetData();
if (item->GetItemLabelText() == "Edit in Parameter Table")
break;
}
menu->Insert(i, wxID_ANY, _L("Flush Options"), flush_options_menu);
}
void MenuFactory::append_menu_items_convert_unit(wxMenu* menu)
{
std::vector<int> obj_idxs, vol_idxs;
@ -838,6 +905,12 @@ void MenuFactory::create_default_menu()
append_submenu(&m_default_menu, sub_menu, wxID_ANY, _L("Add Primitive"), "", "",
[]() {return true; }, m_parent);
#endif
m_default_menu.AppendSeparator();
append_menu_check_item(&m_default_menu, wxID_ANY, _L("Show Labels"), "",
[](wxCommandEvent&) { plater()->show_view3D_labels(!plater()->are_view3D_labels_shown()); plater()->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); }, &m_default_menu,
[]() { return plater()->is_view3D_shown(); }, [this]() { return plater()->are_view3D_labels_shown(); }, m_parent);
}
void MenuFactory::create_common_object_menu(wxMenu* menu)
@ -875,7 +948,7 @@ void MenuFactory::create_object_menu()
[]() { return plater()->can_split(false); }, m_parent);
append_submenu(&m_object_menu, split_menu, wxID_ANY, _L("Split"), _L("Split the selected object"), "",
[]() { return plater()->can_split(true); }, m_parent);
[]() { return plater()->can_split(true) || plater()->can_split(false); }, m_parent);
m_object_menu.AppendSeparator();
// BBS: remove Layers Editing
@ -920,6 +993,7 @@ void MenuFactory::create_bbl_object_menu()
// Set filament insert menu item here
// Set Printable
wxMenuItem* menu_item_printable = append_menu_item_printable(&m_object_menu);
append_menu_item_per_object_process(&m_object_menu);
// Enter per object parameters
append_menu_item_per_object_settings(&m_object_menu);
m_object_menu.AppendSeparator();
@ -1072,7 +1146,7 @@ void MenuFactory::create_plate_menu()
[](wxCommandEvent&) { plater()->delete_plate(); }, "menu_delete", nullptr,
[]() { return plater()->can_delete_plate(); }, m_parent);
#else
append_menu_item(menu, wxID_ANY, _L("Delete") + "\tDel", _L("Remove the selected plate"),
append_menu_item(menu, wxID_ANY, _L("Delete") + "\tBackSpace", _L("Remove the selected plate"),
[](wxCommandEvent&) { plater()->delete_plate(); }, "", nullptr,
[]() { return plater()->can_delete_plate(); }, m_parent);
#endif
@ -1131,6 +1205,7 @@ wxMenu* MenuFactory::object_menu()
{
append_menu_item_change_filament(&m_object_menu);
append_menu_items_convert_unit(&m_object_menu);
append_menu_items_flush_options(&m_object_menu);
return &m_object_menu;
}
@ -1194,6 +1269,7 @@ wxMenu* MenuFactory::multi_selection_menu()
append_menu_item_change_filament(menu);
append_menu_item_set_printable(menu);
append_menu_item_per_object_process(menu);
menu->AppendSeparator();
append_menu_items_convert_unit(menu);
menu->AppendSeparator();
@ -1303,6 +1379,24 @@ void MenuFactory::append_menu_item_center(wxMenu* menu)
}, m_parent);
}
void MenuFactory::append_menu_item_per_object_process(wxMenu* menu)
{
const std::vector<wxString> names = { _L("Edit Process Settings"), _L("Edit Process Settings") };
append_menu_item(menu, wxID_ANY, names[0], names[1],
[](wxCommandEvent&) {
wxGetApp().obj_list()->switch_to_object_process();
}, "", nullptr,
[]() {
Selection& selection = plater()->canvas3D()->get_selection();
return selection.is_single_full_object() ||
selection.is_multiple_full_object() ||
selection.is_single_full_instance() ||
selection.is_multiple_full_instance() ||
selection.is_single_volume() ||
selection.is_multiple_volume();
}, m_parent);
}
void MenuFactory::append_menu_item_per_object_settings(wxMenu* menu)
{
const std::vector<wxString> names = { _L("Edit in Parameter Table"), _L("Edit print parameters for a single object") };
@ -1342,6 +1436,12 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu)
if (sels.IsEmpty())
return;
if (sels.Count() == 1) {
const auto sel_vol = obj_list()->get_selected_model_volume();
if (sel_vol && sel_vol->type() != ModelVolumeType::MODEL_PART && sel_vol->type() != ModelVolumeType::PARAMETER_MODIFIER)
return;
}
std::vector<wxBitmap*> icons = get_extruder_color_icons(true);
if (icons.size() < filaments_cnt) {
BOOST_LOG_TRIVIAL(warning) << boost::format("Warning: icons size %1%, filaments_cnt=%2%")%icons.size()%filaments_cnt;
@ -1356,22 +1456,34 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu)
int initial_extruder = -1; // negative value for multiple object/part selection
if (sels.Count() == 1) {
const ModelConfig& config = obj_list()->get_item_config(sels[0]);
// BBS: set default extruder to 1
initial_extruder = config.has("extruder") ? config.extruder() : 1;
// BBS
const auto sel_vol = obj_list()->get_selected_model_volume();
if (sel_vol && sel_vol->type() == ModelVolumeType::PARAMETER_MODIFIER)
initial_extruder = config.has("extruder") ? config.extruder() : 0;
else
initial_extruder = config.has("extruder") ? config.extruder() : 1;
}
for (int i = 1; i <= filaments_cnt; i++)
// BBS
bool has_modifier = false;
for (auto sel : sels) {
if (obj_list()->GetModel()->GetVolumeType(sel) == ModelVolumeType::PARAMETER_MODIFIER) {
has_modifier = true;
break;
}
}
for (int i = has_modifier ? 0 : 1; i <= filaments_cnt; i++)
{
// BBS
//bool is_active_extruder = i == initial_extruder;
bool is_active_extruder = false;
int icon_idx = i == 0 ? 0 : i - 1;
const wxString& item_name = wxString::Format(_L("Filament %d"), i) +
const wxString& item_name = (i == 0 ? _L("Default") : wxString::Format(_L("Filament %d"), i)) +
(is_active_extruder ? " (" + _L("current") + ")" : "");
append_menu_item(extruder_selection_menu, wxID_ANY, item_name, "",
[i](wxCommandEvent&) { obj_list()->set_extruder_for_selected_items(i); }, *icons[icon_idx], menu,
[i](wxCommandEvent&) { obj_list()->set_extruder_for_selected_items(i); }, i == 0 ? wxNullBitmap : *icons[i - 1], menu,
[is_active_extruder]() { return !is_active_extruder; }, m_parent);
}
menu->Append(wxID_ANY, name, extruder_selection_menu, _L("Change Filament"));
@ -1441,9 +1553,11 @@ void MenuFactory::update_object_menu()
void MenuFactory::update_default_menu()
{
const auto menu_item_id = m_default_menu.FindItem(_("Add Primitive"));
if (menu_item_id != wxNOT_FOUND)
m_default_menu.Destroy(menu_item_id);
for (auto& name : { _L("Add Primitive") , _L("Show Labels") }) {
const auto menu_item_id = m_default_menu.FindItem(name);
if (menu_item_id != wxNOT_FOUND)
m_default_menu.Destroy(menu_item_id);
}
create_default_menu();
}

View file

@ -129,6 +129,7 @@ private:
void append_menu_item_delete(wxMenu* menu);
void append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu);
void append_menu_items_convert_unit(wxMenu* menu); // Add "Conver/Revert..." menu items (from/to inches/meters) after "Reload From Disk"
void append_menu_items_flush_options(wxMenu* menu);
void append_menu_item_merge_to_multipart_object(wxMenu *menu);
void append_menu_item_merge_to_single_object(wxMenu* menu);
void append_menu_item_merge_parts_to_single_part(wxMenu *menu);
@ -139,6 +140,7 @@ private:
void append_menu_item_clone(wxMenu* menu);
void append_menu_item_simplify(wxMenu* menu);
void append_menu_item_center(wxMenu* menu);
void append_menu_item_per_object_process(wxMenu* menu);
void append_menu_item_per_object_settings(wxMenu* menu);
void append_menu_item_change_filament(wxMenu* menu);
void append_menu_item_set_printable(wxMenu* menu);

View file

@ -80,7 +80,7 @@ ObjectList::ObjectList(wxWindow* parent) :
#ifdef __WXMSW__
GenericGetHeader()->SetFont(Label::sysFont(13));
#endif
// create control
create_objects_ctrl();
@ -234,9 +234,9 @@ ObjectList::ObjectList(wxWindow* parent) :
Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &ObjectList::OnContextMenu, this);
// BBS
//Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, &ObjectList::OnBeginDrag, this);
//Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, &ObjectList::OnDropPossible, this);
//Bind(wxEVT_DATAVIEW_ITEM_DROP, &ObjectList::OnDrop, this);
Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, &ObjectList::OnBeginDrag, this);
Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, &ObjectList::OnDropPossible, this);
Bind(wxEVT_DATAVIEW_ITEM_DROP, &ObjectList::OnDrop, this);
Bind(wxEVT_DATAVIEW_ITEM_EDITING_STARTED, &ObjectList::OnEditingStarted, this);
Bind(wxEVT_DATAVIEW_ITEM_EDITING_DONE, &ObjectList::OnEditingDone, this);
@ -354,6 +354,9 @@ void ObjectList::create_objects_ctrl()
bmp_choice_renderer->set_default_extruder_idx([this]() {
return m_objects_model->GetDefaultExtruderIdx(GetSelection());
});
bmp_choice_renderer->set_has_default_extruder([this]() {
return m_objects_model->GetVolumeType(GetSelection()) == ModelVolumeType::PARAMETER_MODIFIER;
});
AppendColumn(new wxDataViewColumn(_L("Fila."), bmp_choice_renderer,
colFilament, m_columns_width[colFilament] * em, wxALIGN_CENTER_HORIZONTAL, 0));
@ -604,6 +607,11 @@ void ObjectList::update_filament_values_for_items(const size_t filaments_count)
}
m_objects_model->SetExtruder(extruder, item);
static const char *keys[] = {"support_filament", "support_interface_filament"};
for (auto key : keys)
if (object->config.has(key) && object->config.opt_int(key) > filaments_count)
object->config.erase(key);
if (object->volumes.size() > 1) {
for (size_t id = 0; id < object->volumes.size(); id++) {
item = m_objects_model->GetItemByVolumeId(i, id);
@ -617,6 +625,10 @@ void ObjectList::update_filament_values_for_items(const size_t filaments_count)
}
m_objects_model->SetExtruder(extruder, item);
for (auto key : keys)
if (object->volumes[id]->config.has(key) && object->volumes[id]->config.opt_int(key) > filaments_count)
object->volumes[id]->config.erase(key);
}
}
}
@ -847,10 +859,14 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const
ModelObject* obj = object(obj_idx);
if (m_objects_model->GetItemType(item) & itObject) {
obj->name = m_objects_model->GetName(item).ToUTF8().data();
// if object has just one volume, rename this volume too
if (obj->volumes.size() == 1)
obj->volumes[0]->name = obj->name;
std::string name = m_objects_model->GetName(item).ToUTF8().data();
if (obj->name != name) {
obj->name = name;
// if object has just one volume, rename this volume too
if (obj->volumes.size() == 1)
obj->volumes[0]->name = obj->name;
Slic3r::save_object_mesh(*obj);
}
return;
}
@ -1363,7 +1379,7 @@ void ObjectList::key_event(wxKeyEvent& event)
//else if (event.GetUnicodeKey() == 'p')
// toggle_printable_state();
else if (filaments_count() > 1) {
std::vector<wxChar> numbers = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
std::vector<wxChar> numbers = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
wxChar key_char = event.GetUnicodeKey();
if (std::find(numbers.begin(), numbers.end(), key_char) != numbers.end()) {
long extruder_number;
@ -1381,17 +1397,28 @@ void ObjectList::key_event(wxKeyEvent& event)
void ObjectList::OnBeginDrag(wxDataViewEvent &event)
{
bool sequential_print = (wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
if (!sequential_print) {
//drag forbidden under bylayer mode
event.Veto();
return;
}
const wxDataViewItem item(event.GetItem());
const bool mult_sel = multiple_selection();
const ItemType& type = m_objects_model->GetItemType(item);
if (mult_sel || (type != itObject)) {
//drag only allowed for single object
event.Veto();
return;
}
#if 0
if ((mult_sel && !selected_instances_of_same_object()) ||
(!mult_sel && (GetSelection() != item)) ) {
event.Veto();
return;
}
const ItemType& type = m_objects_model->GetItemType(item);
if (!(type & (itVolume | itObject | itInstance))) {
event.Veto();
return;
@ -1413,7 +1440,9 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
type&itVolume ? m_objects_model->GetVolumeIdByItem(item) :
m_objects_model->GetInstanceIdByItem(item),
type);
#else
m_dragged_data.init(m_objects_model->GetIdByItem(item), type);
#endif
/* Under MSW or OSX, DnD moves an item to the place of another selected item
* But under GTK, DnD moves an item between another two items.
* And as a result - call EVT_CHANGE_SELECTION to unselect all items.
@ -1431,8 +1460,28 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
event.SetDragFlags(wxDrag_DefaultMove); // allows both copy and move;
}
bool ObjectList::can_drop(const wxDataViewItem& item) const
bool ObjectList::can_drop(const wxDataViewItem& item, int& src_obj_id, int& src_plate, int& dest_obj_id, int& dest_plate) const
{
#if 1
if (!item.IsOk() || (m_objects_model->GetItemType(item) != m_dragged_data.type()))
return false;
int from_obj_id = m_dragged_data.obj_idx();
int to_obj_id = m_objects_model->GetIdByItem(item);
PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list();
int from_plate = partplate_list.find_instance(from_obj_id, 0);
if (from_plate == -1)
return false;
int to_plate = partplate_list.find_instance(to_obj_id, 0);
if ((to_plate == -1) || (from_plate != to_plate))
return false;
src_obj_id = from_obj_id;
dest_obj_id = to_obj_id;
src_plate = from_plate;
dest_plate = to_plate;
#else
// move instance(s) or object on "empty place" of ObjectList
if ( (m_dragged_data.type() & (itInstance | itObject)) && !item.IsOk() )
return true;
@ -1481,7 +1530,7 @@ bool ObjectList::can_drop(const wxDataViewItem& item) const
return false;
}
#endif
return true;
}
@ -1489,7 +1538,8 @@ void ObjectList::OnDropPossible(wxDataViewEvent &event)
{
const wxDataViewItem& item = event.GetItem();
if (!can_drop(item)) {
int src_obj_id, src_plate, dest_obj_id, dest_plate;
if (!can_drop(item, src_obj_id, src_plate, dest_obj_id, dest_plate)) {
event.Veto();
m_prevent_list_events = false;
}
@ -1499,13 +1549,45 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
{
const wxDataViewItem& item = event.GetItem();
if (!can_drop(item))
int src_obj_id, src_plate, dest_obj_id, dest_plate;
if (!can_drop(item, src_obj_id, src_plate, dest_obj_id, dest_plate))
{
event.Veto();
m_dragged_data.clear();
return;
}
#if 1
take_snapshot("Object order changed");
int delta = dest_obj_id < src_obj_id ? -1 : 1;
PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list();
/*int cnt = 0, cur_id = src_obj_id, next_id, total = abs(src_obj_id - dest_obj_id);
//for (cur_id = src_obj_id; cnt < total; id += delta, cnt++)
next_id = src_obj_id + delta;
while (cnt < total)
{
int cur_plate = partplate_list.find_instance(next_id, 0);
if (cur_plate != src_plate) {
cnt ++;
next_id += delta;
continue;
}
std::swap((*m_objects)[cur_id], (*m_objects)[next_id]);
cur_id = next_id;
cnt ++;
next_id += delta;
}*/
int cnt = 0;
for (int id = src_obj_id; cnt < abs(src_obj_id - dest_obj_id); id += delta, cnt++)
std::swap((*m_objects)[id], (*m_objects)[id + delta]);
select_item(m_objects_model->ReorganizeObjects(src_obj_id, dest_obj_id));
partplate_list.reload_all_objects(false, src_plate);
changed_object(src_obj_id);
#else
if (m_dragged_data.type() == itInstance)
{
// BBS: remove snapshot name "Instances to Separated Objects"
@ -1546,6 +1628,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
}
changed_object(m_dragged_data.obj_idx());
#endif
m_dragged_data.clear();
@ -1839,10 +1922,17 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo
// Mesh will be centered when loading.
ModelVolume* new_volume = model_object.add_volume(std::move(mesh), type);
new_volume->name = boost::filesystem::path(input_file).filename().string();
// adjust the position according to the bounding box
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(v->get_instance_transformation(), mesh_bb));
auto offset = Vec3d(instance_bb.max.x(), instance_bb.min.y(), instance_bb.min.z()) + 0.5 * mesh_bb.size() - v->get_instance_offset();
new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset);
// set a default extruder value, since user can't add it manually
// BBS
int extruder_id = 0;
if (model_object.config.has("extruder"))
if (new_volume->type() == ModelVolumeType::MODEL_PART && model_object.config.has("extruder"))
extruder_id = model_object.config.opt_int("extruder");
new_volume->config.set_key_value("extruder", new ConfigOptionInt(extruder_id));
// update source data
@ -1945,10 +2035,11 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
const wxString name = _L("Generic") + "-" + _(type_name);
new_volume->name = into_u8(name);
// set a default extruder value, since user can't add it manually
// BBS
int extruder_id = 0;
if (model_object.config.has("extruder"))
if (new_volume->type() == ModelVolumeType::MODEL_PART && model_object.config.has("extruder"))
extruder_id = model_object.config.opt_int("extruder");
new_volume->config.set_key_value("extruder", new ConfigOptionInt(extruder_id));
new_volume->source.is_from_builtin_objects = true;
@ -1979,7 +2070,18 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
//Show Dialog
if (wxGetApp().app_config->get("do_not_show_modifer_tips").empty()) {
TipsDialog dlg(wxGetApp().mainframe, _L("Add Modifier"));
TipsDialog dlg(wxGetApp().mainframe, _L("Add Modifier"), _L("Switch to per-object setting mode to edit modifier settings."), "do_not_show_modifer_tips");
dlg.ShowModal();
}
}
void ObjectList::switch_to_object_process()
{
wxGetApp().params_panel()->switch_to_object(true);
// Show Dialog
if (wxGetApp().app_config->get("do_not_show_object_process_tips").empty()) {
TipsDialog dlg(wxGetApp().mainframe, _L("Edit Process Settings"), _L("Switch to per-object setting mode to edit process settings of selected objects."), "do_not_show_object_process_tips");
dlg.ShowModal();
}
}
@ -2029,6 +2131,9 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
new_object->invalidate_bounding_box();
new_object->translate(-bb.center());
// BBS: backup
Slic3r::save_object_mesh(*new_object);
// BBS: find an empty cell to put the copied object
auto start_point = wxGetApp().plater()->build_volume().bounding_volume2d().center();
auto empty_cell = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)});
@ -2076,7 +2181,7 @@ void ObjectList::load_mesh_part(const TriangleMesh& mesh, const wxString& name,
ModelVolume* mv = mo->add_volume(mesh);
Vec3d instance_bbox = mo->mesh().bounding_box().size();
Vec3d offset = mv->get_offset() + Vec3d(0, 0, instance_bbox[2] / 2);
Vec3d offset = Vec3d(0, 0, instance_bbox[2] / 2);
mv->set_offset(offset);
mv->name = name.ToStdString();
@ -2291,7 +2396,7 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
else if (type == itInstance) {
if (object->instances.size() == 1) {
// BBS: remove snapshot name "Last instance of an object cannot be deleted."
Slic3r::GUI::show_error(nullptr, _L(""));
Slic3r::GUI::show_error(nullptr, "");
return false;
}
@ -4036,11 +4141,18 @@ void ObjectList::select_items(const std::vector<ObjectVolumeID>& ov_ids)
void ObjectList::select_items(const wxDataViewItemArray& sels)
{
m_prevent_list_events = true;
m_last_selected_item = sels.empty() ? wxDataViewItem(nullptr) : sels.back();
UnselectAll();
SetSelections(sels);
if (!sels.empty()) {
SetSelections(sels);
}
else {
int curr_plate_idx = wxGetApp().plater()->get_partplate_list().get_curr_plate_index();
on_plate_selected(curr_plate_idx);
}
part_selection_changed();
m_prevent_list_events = false;
@ -4607,6 +4719,8 @@ void ObjectList::fix_through_netfabb()
update_item_error_icon(obj_idx, vol_idx);
update_info_items(obj_idx);
object(obj_idx)->ensure_on_bed();
return true;
};
@ -4805,6 +4919,16 @@ void ObjectList::set_extruder_for_selected_items(const int extruder)
ItemType sel_item_type = m_objects_model->GetItemType(sel_item);
wxDataViewItem item = (sel_item_type & itInstance) ? m_objects_model->GetObject(item) : sel_item;
ItemType type = m_objects_model->GetItemType(item);
if (type & itVolume) {
const int obj_idx = m_objects_model->GetObjectIdByItem(item);
const int vol_idx = m_objects_model->GetVolumeIdByItem(item);
if ((obj_idx < m_objects->size()) && (obj_idx < (*m_objects)[obj_idx]->volumes.size())) {
auto volume_type = (*m_objects)[obj_idx]->volumes[vol_idx]->type();
if (volume_type != ModelVolumeType::MODEL_PART && volume_type != ModelVolumeType::PARAMETER_MODIFIER)
continue;
}
}
ModelConfig& config = get_item_config(item);
if (config.has("extruder"))
@ -4812,11 +4936,11 @@ void ObjectList::set_extruder_for_selected_items(const int extruder)
else
config.set_key_value("extruder", new ConfigOptionInt(extruder));
// for object, clear all its volume's extruder config
// for object, clear all its part volume's extruder config
if (type & itObject) {
ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID();
for (ModelVolume* mv : node->m_model_object->volumes) {
if (mv->config.has("extruder"))
if (mv->type() == ModelVolumeType::MODEL_PART && mv->config.has("extruder"))
mv->config.erase("extruder");
}
}

View file

@ -282,6 +282,7 @@ public:
void load_shape_object(const std::string &type_name);
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true);
// BBS
void switch_to_object_process();
void load_mesh_part(const TriangleMesh& mesh, const wxString& name, bool center = true);
void del_object(const int obj_idx, bool refresh_immediately = true);
void del_subobject_item(wxDataViewItem& item);
@ -445,7 +446,7 @@ private:
void OnBeginDrag(wxDataViewEvent &event);
void OnDropPossible(wxDataViewEvent &event);
void OnDrop(wxDataViewEvent &event);
bool can_drop(const wxDataViewItem& item) const ;
bool can_drop(const wxDataViewItem& item, int& src_obj_id, int& src_plate, int& dest_obj_id, int& dest_plate) const ;
void ItemValueChanged(wxDataViewEvent &event);
// Workaround for entering the column editing mode on Windows. Simulate keyboard enter when another column of the active line is selected.

View file

@ -204,7 +204,7 @@ bool ObjectSettings::update_settings_list()
for (auto item : items) {
auto type = objects_model->GetItemType(item);
if (type != itObject && type != itVolume) {
return false;
continue;
}
const int obj_idx = objects_model->GetObjectIdByItem(item);
assert(obj_idx >= 0);

View file

@ -2674,7 +2674,7 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi
{
//m_bg_colour = wxColour(0xfa, 0xfa, 0xfa);
m_float_validator.SetRange(0, 100);
m_bg_colour = wxColour(0xff, 0xff, 0xff);
m_bg_colour = wxColour("#FFFFFF");
//m_hover_colour = wxColour(61, 70, 72);
SetBackgroundColour(m_bg_colour);
@ -2854,8 +2854,8 @@ void ObjectTablePanel::load_data()
m_object_grid->SetColLabelValue(ObjectGridTable::col_speed_perimeter, _L("Outer wall speed"));
m_object_grid->SetColLabelValue(ObjectGridTable::col_speed_perimeter_reset, "");
m_object_grid->SetLabelFont(Label::Head_13);
m_object_grid->SetLabelTextColour(wxColour(0x30,0x3a,0x3c));
m_object_grid->SetLabelBackgroundColour(wxColour(0xff, 0xff, 0xff));
m_object_grid->SetLabelTextColour(StateColor::darkModeColorFor(wxColour("#303A3C")));
m_object_grid->SetLabelBackgroundColour( wxColour("#FFFFFF"));
#else
m_object_grid->HideColLabels();
#endif
@ -2866,7 +2866,6 @@ void ObjectTablePanel::load_data()
m_object_grid->EnableDragGridSize(false);
m_object_grid->EnableDragRowSize(false);
/*set the first row as label*/
//format
wxGridCellAttr *attr;
@ -2894,7 +2893,7 @@ void ObjectTablePanel::load_data()
//m_object_grid->SetSelectionForeground(wxColour(0xDB,0xFD,0xE7));
//m_object_grid->SetSelectionBackground(*wxWHITE);
m_object_grid->SetDefaultCellBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
for (int col = 0; col < cols; col++)
{
ObjectGridTable::ObjectGridCol* grid_col = m_object_grid_table->get_grid_col(col);
@ -2907,7 +2906,8 @@ void ObjectTablePanel::load_data()
m_object_grid->SetCellAlignment(row, col, grid_col->horizontal_align, wxALIGN_CENTRE );
m_object_grid->SetCellOverflow(row, col, false);
//m_object_grid->SetCellBackgroundColour (row, col, *wxLIGHT_GREY);
m_object_grid->SetCellBackgroundColour (row, col, *wxWHITE);
m_object_grid->SetCellBackgroundColour (row, col, StateColor::darkModeColorFor(*wxWHITE));
m_object_grid->SetCellTextColour(row, col,StateColor::darkModeColorFor(wxColour(*wxBLACK)));
//set the render and editor
if (grid_col->b_icon) {
m_object_grid->SetCellRenderer(row, col, new GridCellIconRenderer());
@ -3094,6 +3094,7 @@ ObjectTablePanel::~ObjectTablePanel()
}*/
if (m_top_sizer)
m_top_sizer->Clear(true);
delete m_object_settings;
m_filaments_name.clear();
m_filaments_colors.clear();
@ -3306,6 +3307,7 @@ ObjectTableDialog::ObjectTableDialog(wxWindow* parent, Plater* platerObj, Model
SetSizer(m_main_sizer);
Fit();
Layout();
wxGetApp().UpdateDlgDarkUI(this);
}
ObjectTableDialog::~ObjectTableDialog()

View file

@ -168,7 +168,7 @@ bool ObjectTableSettings::update_settings_list(bool is_object, bool is_multiple_
btn->SetToolTip(_(L("Reset parameter")));
#ifdef __WINDOWS__
btn->SetBackgroundColour(*wxWHITE);
btn->SetBackgroundColour(parent->GetBackgroundColour());
#endif // DEBUG
@ -220,7 +220,8 @@ bool ObjectTableSettings::update_settings_list(bool is_object, bool is_multiple_
optgroup->sidetext_width = 5;
optgroup->set_config_category_and_type(GUI::from_u8(group_category), Preset::TYPE_PRINT);
optgroup->m_on_change = [this, optgroup, is_object, object, config, group_category](const t_config_option_key& opt_id, const boost::any& value) {
std::weak_ptr weak_optgroup(optgroup);
optgroup->m_on_change = [this, is_object, object, config, group_category](const t_config_option_key &opt_id, const boost::any &value) {
this->m_parent->Freeze();
this->update_config_values(is_object, object, config, group_category);
wxGetApp().obj_list()->changed_object();
@ -258,10 +259,10 @@ bool ObjectTableSettings::update_settings_list(bool is_object, bool is_multiple_
}
optgroup->activate();
for (auto& opt : cat.second)
optgroup->get_field(opt.name)->m_on_change = [optgroup](const std::string& opt_id, const boost::any& value) {
optgroup->get_field(opt.name)->m_on_change = [weak_optgroup](const std::string& opt_id, const boost::any& value) {
// first of all take a snapshot and then change value in configuration
wxGetApp().plater()->take_snapshot((boost::format("Change Option %s") % opt_id).str());
optgroup->on_change_OG(opt_id, value);
weak_optgroup.lock()->on_change_OG(opt_id, value);
};
optgroup->reload_config();

View file

@ -94,8 +94,9 @@ bool View3D::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig
void View3D::set_as_dirty()
{
if (m_canvas != nullptr)
if (m_canvas != nullptr) {
m_canvas->set_as_dirty();
}
}
void View3D::bed_shape_changed()
@ -160,6 +161,22 @@ void View3D::mirror_selection(Axis axis)
m_canvas->mirror_selection(axis);
}
bool View3D::is_layers_editing_enabled() const
{
return (m_canvas != nullptr) ? m_canvas->is_layers_editing_enabled() : false;
}
bool View3D::is_layers_editing_allowed() const
{
return (m_canvas != nullptr) ? m_canvas->is_layers_editing_allowed() : false;
}
void View3D::enable_layers_editing(bool enable)
{
if (m_canvas != nullptr)
m_canvas->enable_layers_editing(enable);
}
bool View3D::is_dragging() const
{
return (m_canvas != nullptr) ? m_canvas->is_dragging() : false;

View file

@ -66,6 +66,10 @@ public:
void center_selected();
void mirror_selection(Axis axis);
bool is_layers_editing_enabled() const;
bool is_layers_editing_allowed() const;
void enable_layers_editing(bool enable);
bool is_dragging() const;
bool is_reload_delayed() const;

View file

@ -259,15 +259,23 @@ bool check_dark_mode() {
void update_dark_ui(wxWindow* window)
{
#ifdef SUPPORT_DARK_MODE
bool is_dark = wxGetApp().app_config->get("dark_color_mode") == "1";// ? true : check_dark_mode();// #ysDarkMSW - Allow it when we deside to support the sustem colors for application
bool is_dark = wxGetApp().app_config->get("dark_color_mode") == "1";
#else
bool is_dark = false;
#endif
window->SetBackgroundColour(is_dark ? wxColour(43, 43, 43) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
window->SetForegroundColour(is_dark ? wxColour(250, 250, 250) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
//window->SetBackgroundColour(is_dark ? wxColour(43, 43, 43) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
//window->SetForegroundColour(is_dark ? wxColour(250, 250, 250) : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
}
#endif
void update_dark_config()
{
wxSystemAppearance app = wxSystemSettings::GetAppearance();
GUI::wxGetApp().app_config->set("dark_color_mode", app.IsDark() ? "1" : "0");
GUI::wxGetApp().app_config->save();
wxGetApp().Update_dark_mode_flag();
}
CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent)
: wxPanel(parent, wxID_ANY)

View file

@ -82,6 +82,7 @@ wxFont get_default_font_for_dpi(const wxWindow* window, int dpi);
inline wxFont get_default_font(const wxWindow* window) { return get_default_font_for_dpi(window, get_dpi_for_window(window)); }
bool check_dark_mode();
void update_dark_config();
#ifdef _WIN32
void update_dark_ui(wxWindow* window);
#endif
@ -188,8 +189,9 @@ public:
this->Bind(wxEVT_SYS_COLOUR_CHANGED, [this](wxSysColourChangedEvent& event)
{
event.Skip();
update_dark_config();
on_sys_color_changed();
event.Skip();
});
if (std::is_same<wxDialog, P>::value) {

View file

@ -166,6 +166,10 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u
m_cylinder.init_from(its_make_cylinder(1., 1., 2 * PI / 24.));
}
void GLGizmoBase::set_icon_filename(const std::string &filename) {
m_icon_filename = filename;
}
void GLGizmoBase::set_hover_id(int id)
{
if (m_grabbers.empty() || (id < (int)m_grabbers.size()))

View file

@ -126,6 +126,8 @@ protected:
GLModel m_cylinder;
GLModel m_sphere;
bool m_is_dark_mode = false;
public:
GLGizmoBase(GLCanvas3D& parent,
const std::string& icon_filename,
@ -149,20 +151,22 @@ public:
const std::string& get_icon_filename() const { return m_icon_filename; }
void set_icon_filename(const std::string& filename);
bool is_activable() const { return on_is_activable(); }
bool is_selectable() const { return on_is_selectable(); }
CommonGizmosDataID get_requirements() const { return on_get_requirements(); }
virtual bool wants_enter_leave_snapshots() const { return false; }
virtual std::string get_gizmo_entering_text() const { assert(false); return ""; }
virtual std::string get_gizmo_leaving_text() const { assert(false); return ""; }
virtual std::string get_action_snapshot_name() { return _u8L("Gizmo action"); }
virtual std::string get_action_snapshot_name() { return "Gizmo action"; }
void set_common_data_pool(CommonGizmosDataPool* ptr) { m_c = ptr; }
unsigned int get_sprite_id() const { return m_sprite_id; }
int get_hover_id() const { return m_hover_id; }
void set_hover_id(int id);
void set_highlight_color(const std::array<float, 4>& color);
void enable_grabber(unsigned int id);
@ -181,6 +185,7 @@ public:
void render() { m_tooltip.clear(); on_render(); }
void render_for_picking() { on_render_for_picking(); }
void render_input_window(float x, float y, float bottom_limit);
virtual void on_change_color_mode(bool is_dark) { m_is_dark_mode = is_dark; }
virtual std::string get_tooltip() const { return ""; }

View file

@ -81,6 +81,7 @@ bool GLGizmoFdmSupports::on_init()
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_caption"] = _L("Ctrl + Mouse wheel");
m_desc["cursor_size"] = _L("Pen size");
m_desc["enforce_caption"] = _L("Left mouse button");
@ -98,6 +99,7 @@ bool GLGizmoFdmSupports::on_init()
m_desc["tool_type"] = _L("Tool type");
m_desc["smart_fill_angle_caption"] = _L("Ctrl + Mouse wheel");
m_desc["smart_fill_angle"] = _L("Smart fill angle");
m_desc["on_overhangs_only"] = _L("On overhangs only");
memset(&m_print_instance, sizeof(m_print_instance), 0);
return true;
@ -216,6 +218,8 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.5f);
const float gap_fill_slider_left = m_imgui->calc_text_size(m_desc.at("gap_fill")).x + m_imgui->scaled(1.5f);
const float highlight_slider_left = m_imgui->calc_text_size(m_desc.at("highlight_by_angle")).x + m_imgui->scaled(1.5f);
const float reset_button_slider_left = m_imgui->calc_text_size(m_desc.at("reset_direction")).x + m_imgui->scaled(1.5f) + ImGui::GetStyle().FramePadding.x * 2;
const float on_overhangs_only_width = m_imgui->calc_text_size(m_desc["on_overhangs_only"]).x + m_imgui->scaled(1.5f);
const float remove_btn_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.5f);
const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform")).x + m_imgui->scaled(1.5f);
const float buttons_width = remove_btn_width + filter_btn_width + m_imgui->scaled(1.5f);
@ -233,7 +237,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
total_text_max += caption_max + m_imgui->scaled(1.f);
caption_max += m_imgui->scaled(1.f);
const float sliders_left_width = std::max(std::max(cursor_slider_left, clipping_slider_left), std::max(highlight_slider_left, gap_fill_slider_left));
const float sliders_left_width = std::max(reset_button_slider_left, std::max(std::max(cursor_slider_left, clipping_slider_left), std::max(highlight_slider_left, gap_fill_slider_left)));
const float slider_icon_width = m_imgui->get_slider_icon_size().x;
const float max_tooltip_width = ImGui::GetFontSize() * 20.0f;
@ -244,33 +248,39 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("tool_type"));
std::array<wchar_t, 4> tool_icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon };
std::array<wchar_t, 4> tool_ids = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon };
std::array<wchar_t, 4> icons;
if (m_is_dark_mode)
icons = { ImGui::CircleButtonDarkIcon, ImGui::SphereButtonDarkIcon, ImGui::FillButtonDarkIcon, ImGui::GapFillDarkIcon };
else
icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon };
std::array<wxString, 4> tool_tips = { _L("Circle"), _L("Sphere"), _L("Fill"), _L("Gap Fill") };
for (int i = 0; i < tool_icons.size(); i++) {
for (int i = 0; i < tool_ids.size(); i++) {
std::string str_label = std::string("##");
std::wstring btn_name = tool_icons[i] + boost::nowide::widen(str_label);
std::wstring btn_name = icons[i] + boost::nowide::widen(str_label);
if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.3f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0);
if (m_current_tool == tool_icons[i]) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
if (m_current_tool == tool_ids[i]) {
ImGui::PushStyleColor(ImGuiCol_Button, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.00f, 0.68f, 0.26f, 1.00f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0);
}
bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str());
if (m_current_tool == tool_icons[i])
if (m_current_tool == tool_ids[i])
{
ImGui::PopStyleColor(4);
ImGui::PopStyleVar(2);
}
ImGui::PopStyleVar(1);
if (btn_clicked && m_current_tool != tool_icons[i]) {
m_current_tool = tool_icons[i];
if (btn_clicked && m_current_tool != tool_ids[i]) {
m_current_tool = tool_ids[i];
for (auto& triangle_selector : m_triangle_selectors) {
triangle_selector->seed_fill_unselect_all_triangles();
triangle_selector->request_update_render_data();
@ -282,6 +292,11 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
}
}
m_imgui->bbl_checkbox(m_desc["on_overhangs_only"], m_paint_on_overhangs_only);
if (ImGui::IsItemHovered())
m_imgui->tooltip(format_wxstr(_L("Allows painting only on facets selected by: \"%1%\""), m_desc["highlight_by_angle"]), max_tooltip_width);
ImGui::Separator();
if (m_current_tool != old_tool)
this->tool_changed(old_tool, m_current_tool);
@ -379,11 +394,20 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
ImGui::SameLine(drag_left_width);
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##angle_threshold_deg_input", &m_highlight_by_angle_threshold_deg, 0.05f, 0.0f, 0.0f, "%.2f");
if (m_current_tool != ImGui::GapFillIcon) {
ImGui::Separator();
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
if (m_c->object_clipper()->get_position() == 0.f) {
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
}
else {
if (m_imgui->button(m_desc.at("reset_direction"))) {
wxGetApp().CallAfter([this]() {
m_c->object_clipper()->set_position(-1., false);
});
}
}
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(sliders_left_width);
@ -468,6 +492,7 @@ void GLGizmoFdmSupports::show_tooltip_information(float caption_max, float x, fl
float font_size = ImGui::GetFontSize();
ImVec2 button_size = ImVec2(font_size * 1.8, font_size * 1.3);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 0, ImGui::GetStyle().FramePadding.y });
ImGui::ImageButton3(normal_id, hover_id, button_size);
if (ImGui::IsItemHovered()) {
@ -499,7 +524,7 @@ void GLGizmoFdmSupports::show_tooltip_information(float caption_max, float x, fl
ImGui::EndTooltip();
}
ImGui::PopStyleVar(1);
ImGui::PopStyleVar(2);
}
// BBS
@ -796,7 +821,7 @@ void GLGizmoFdmSupports::update_support_volumes()
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "join thread returns "<<ret;
}
m_cancel = false;
m_thread = create_thread([this]{this->run_thread();});
m_thread = create_thread([this]{this->run_thread();});
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",created thread to generate support volumes";
return;
}

View file

@ -34,9 +34,9 @@ protected:
void show_tooltip_information(float caption_max, float x, float y);
wxString handle_snapshot_action_name(bool shift_down, Button button_down) const override;
std::string get_gizmo_entering_text() const override { return _u8L("Entering Paint-on supports"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Paint-on supports"); }
std::string get_action_snapshot_name() override { return _u8L("Paint-on supports editing"); }
std::string get_gizmo_entering_text() const override { return "Entering Paint-on supports"; }
std::string get_gizmo_leaving_text() const override { return "Leaving Paint-on supports"; }
std::string get_action_snapshot_name() override { return "Paint-on supports editing"; }
// BBS
wchar_t m_current_tool = 0;

View file

@ -13,7 +13,6 @@
namespace Slic3r {
namespace GUI {
static double g_normal_precise = 0.0015;
GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
@ -140,8 +139,8 @@ void GLGizmoFlatten::update_planes()
const Transform3d& inst_matrix = mo->instances.front()->get_matrix(true);
// Following constants are used for discarding too small polygons.
const float minimal_area = 4.f; // in square mm (world coordinates)
const float minimal_side = 2.f; // mm
const float minimal_area = 5.f; // in square mm (world coordinates)
const float minimal_side = 1.f; // mm
// Now we'll go through all the facets and append Points of facets sharing the same normal.
// This part is still performed in mesh coordinate system.
@ -169,7 +168,7 @@ void GLGizmoFlatten::update_planes()
while (facet_queue_cnt > 0) {
int facet_idx = facet_queue[-- facet_queue_cnt];
const stl_normal& this_normal = face_normals[facet_idx];
if (std::abs(this_normal(0) - (*normal_ptr)(0)) <= g_normal_precise && std::abs(this_normal(1) - (*normal_ptr)(1)) <= g_normal_precise && std::abs(this_normal(2) - (*normal_ptr)(2)) <= g_normal_precise) {
if (std::abs(this_normal(0) - (*normal_ptr)(0)) < 0.001 && std::abs(this_normal(1) - (*normal_ptr)(1)) < 0.001 && std::abs(this_normal(2) - (*normal_ptr)(2)) < 0.001) {
const Vec3i face = ch.its.indices[facet_idx];
for (int j=0; j<3; ++j)
m_planes.back().vertices.emplace_back(ch.its.vertices[face[j]].cast<double>());
@ -236,28 +235,18 @@ void GLGizmoFlatten::update_planes()
discard = true;
else {
// We also check the inner angles and discard polygons with angles smaller than the following threshold
const double angle_threshold = ::cos(9.0 * (double)PI / 180.0);
int count = 0, side_count = polygon.size();
const double angle_threshold = ::cos(10.0 * (double)PI / 180.0);
for (unsigned int i = 0; i < side_count; ++i) {
for (unsigned int i = 0; i < polygon.size(); ++i) {
const Vec3d& prec = polygon[(i == 0) ? polygon.size() - 1 : i - 1];
const Vec3d& curr = polygon[i];
const Vec3d& next = polygon[(i == polygon.size() - 1) ? 0 : i + 1];
double len = (next - curr).norm();
if (len >= minimal_side)
count ++;
if ((prec - curr).normalized().dot((next - curr).normalized()) > angle_threshold) {
discard = true;
break;
}
}
if (!discard
//&& ((side_count == 3) || (side_count == 5))
&& (side_count <= 5)
&& (count <= 2)) {
discard = true;
}
}
if (discard) {
@ -269,14 +258,14 @@ void GLGizmoFlatten::update_planes()
Vec3d centroid = std::accumulate(polygon.begin(), polygon.end(), Vec3d(0.0, 0.0, 0.0));
centroid /= (double)polygon.size();
for (auto& vertex : polygon)
vertex = 0.95f*vertex + 0.05f*centroid;
vertex = 0.9f*vertex + 0.1f*centroid;
// Polygon is now simple and convex, we'll round the corners to make them look nicer.
// The algorithm takes a vertex, calculates middles of respective sides and moves the vertex
// towards their average (controlled by 'aggressivity'). This is repeated k times.
// In next iterations, the neighbours are not always taken at the middle (to increase the
// rounding effect at the corners, where we need it most).
/*const unsigned int k = 10; // number of iterations
const unsigned int k = 10; // number of iterations
const float aggressivity = 0.2f; // agressivity
const unsigned int N = polygon.size();
std::vector<std::pair<unsigned int, unsigned int>> neighbours;
@ -308,7 +297,7 @@ void GLGizmoFlatten::update_planes()
}
}
polygon = points_out; // replace the coarse polygon with the smooth one that we just created
}*/
}
// Raise a bit above the object surface to avoid flickering:
@ -321,7 +310,7 @@ void GLGizmoFlatten::update_planes()
// We'll sort the planes by area and only keep the 254 largest ones (because of the picking pass limitations):
std::sort(m_planes.rbegin(), m_planes.rend(), [](const PlaneData& a, const PlaneData& b) { return a.area < b.area; });
m_planes.resize(std::min((int)m_planes.size(), 512));
m_planes.resize(std::min((int)m_planes.size(), 254));
// Planes are finished - let's save what we calculated it from:
m_volumes_matrices.clear();

View file

@ -99,6 +99,7 @@ bool GLGizmoMmuSegmentation::on_init()
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_caption"] = _L("Ctrl + Mouse wheel");
m_desc["cursor_size"] = _L("Pen size");
m_desc["cursor_type"] = _L("Pen shape");
@ -131,6 +132,10 @@ bool GLGizmoMmuSegmentation::on_init()
m_desc["height_range_caption"] = _L("Ctrl + Mouse wheel");
m_desc["height_range"] = _L("Height range");
//add toggle wire frame hint
m_desc["toggle_wireframe_caption"] = _L("Ctrl + Shift + Enter");
m_desc["toggle_wireframe"] = _L("Toggle Wireframe");
init_extruders_data();
return true;
@ -302,6 +307,7 @@ void GLGizmoMmuSegmentation::show_tooltip_information(float caption_max, float x
float font_size = ImGui::GetFontSize();
ImVec2 button_size = ImVec2(font_size * 1.8, font_size * 1.3);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 0, ImGui::GetStyle().FramePadding.y });
ImGui::ImageButton3(normal_id, hover_id, button_size);
if (ImGui::IsItemHovered()) {
@ -315,16 +321,16 @@ void GLGizmoMmuSegmentation::show_tooltip_information(float caption_max, float x
std::vector<std::string> tip_items;
switch (m_tool_type) {
case ToolType::BRUSH:
tip_items = {"paint", "erase", "cursor_size", "clipping_of_view"};
tip_items = {"paint", "erase", "cursor_size", "clipping_of_view", "toggle_wireframe"};
break;
case ToolType::BUCKET_FILL:
tip_items = {"paint", "erase", "smart_fill_angle", "clipping_of_view"};
tip_items = {"paint", "erase", "smart_fill_angle", "clipping_of_view", "toggle_wireframe"};
break;
case ToolType::SMART_FILL:
// TODO:
break;
case ToolType::GAP_FILL:
tip_items = {"gap_area"};
tip_items = {"gap_area", "toggle_wireframe"};
break;
default:
break;
@ -332,7 +338,7 @@ void GLGizmoMmuSegmentation::show_tooltip_information(float caption_max, float x
for (const auto &t : tip_items) draw_text_with_caption(m_desc.at(t + "_caption") + ": ", m_desc.at(t));
ImGui::EndTooltip();
}
ImGui::PopStyleVar(1);
ImGui::PopStyleVar(2);
}
void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bottom_limit)
@ -351,7 +357,8 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
// First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that:
const float space_size = m_imgui->get_style_scaling() * 8;
const float clipping_slider_left = m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x + m_imgui->scaled(1.5f);
const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x + m_imgui->scaled(1.5f),
m_imgui->calc_text_size(m_desc.at("reset_direction")).x + m_imgui->scaled(1.5f) + ImGui::GetStyle().FramePadding.x * 2);
const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.5f);
const float smart_fill_slider_left = m_imgui->calc_text_size(m_desc.at("smart_fill_angle")).x + m_imgui->scaled(1.5f);
const float edge_detect_slider_left = m_imgui->calc_text_size(m_desc.at("edge_detection")).x + m_imgui->scaled(1.f);
@ -411,7 +418,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
std::string color_label = std::string("##extruder color ") + std::to_string(extruder_idx);
std::string item_text = std::to_string(extruder_idx + 1);
const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true);
const ImVec2 button_size(max_label_size.x + m_imgui->scaled(0.5f),0.f);
float button_offset = start_pos_x;
@ -459,32 +466,38 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
m_imgui->text(m_desc.at("tool_type"));
std::array<wchar_t, 6> tool_icons = { ImGui::CircleButtonIcon,ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon };
std::array<wchar_t, 6> tool_ids;
tool_ids = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon };
std::array<wchar_t, 6> icons;
if (m_is_dark_mode)
icons = { ImGui::CircleButtonDarkIcon, ImGui::SphereButtonDarkIcon, ImGui::TriangleButtonDarkIcon, ImGui::HeightRangeDarkIcon, ImGui::FillButtonDarkIcon, ImGui::GapFillDarkIcon };
else
icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon };
std::array<wxString, 6> tool_tips = { _L("Circle"), _L("Sphere"), _L("Triangle"), _L("Height Range"), _L("Fill"), _L("Gap Fill") };
for (int i = 0; i < tool_icons.size(); i++) {
for (int i = 0; i < tool_ids.size(); i++) {
std::string str_label = std::string("");
std::wstring btn_name = tool_icons[i] + boost::nowide::widen(str_label);
std::wstring btn_name = icons[i] + boost::nowide::widen(str_label);
if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.5f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0);
if (m_current_tool == tool_icons[i]) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
if (m_current_tool == tool_ids[i]) {
ImGui::PushStyleColor(ImGuiCol_Button, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.00f, 0.68f, 0.26f, 1.00f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0);
}
bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str());
if (m_current_tool == tool_icons[i])
if (m_current_tool == tool_ids[i])
{
ImGui::PopStyleColor(4);
ImGui::PopStyleVar(2);
}
ImGui::PopStyleVar(1);
if (btn_clicked && m_current_tool != tool_icons[i]) {
m_current_tool = tool_icons[i];
if (btn_clicked && m_current_tool != tool_ids[i]) {
m_current_tool = tool_ids[i];
for (auto &triangle_selector : m_triangle_selectors) {
triangle_selector->seed_fill_unselect_all_triangles();
triangle_selector->request_update_render_data();
@ -518,9 +531,17 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
ImGui::BBLDragFloat("##cursor_radius_input", &m_cursor_radius, 0.05f, 0.0f, 0.0f, "%.2f");
ImGui::Separator();
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
if (m_c->object_clipper()->get_position() == 0.f) {
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
}
else {
if (m_imgui->button(m_desc.at("reset_direction"))) {
wxGetApp().CallAfter([this]() {
m_c->object_clipper()->set_position(-1., false);
});
}
}
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(circle_max_width);
@ -536,8 +557,17 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
m_cursor_type = TriangleSelector::CursorType::POINTER;
m_tool_type = ToolType::BRUSH;
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
if (m_c->object_clipper()->get_position() == 0.f) {
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
}
else {
if (m_imgui->button(m_desc.at("reset_direction"))) {
wxGetApp().CallAfter([this]() {
m_c->object_clipper()->set_position(-1., false);
});
}
}
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(clipping_slider_left);
@ -574,9 +604,17 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
m_smart_fill_angle = -1.f;
}
ImGui::Separator();
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
if (m_c->object_clipper()->get_position() == 0.f) {
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
}
else {
if (m_imgui->button(m_desc.at("reset_direction"))) {
wxGetApp().CallAfter([this]() {
m_c->object_clipper()->set_position(-1., false);
});
}
}
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(sliders_left_width);
@ -602,9 +640,17 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
ImGui::BBLDragFloat("##cursor_height_input", &m_cursor_height, 0.05f, 0.0f, 0.0f, "%.2f");
ImGui::Separator();
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
if (m_c->object_clipper()->get_position() == 0.f) {
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
}
else {
if (m_imgui->button(m_desc.at("reset_direction"))) {
wxGetApp().CallAfter([this]() {
m_c->object_clipper()->set_position(-1., false);
});
}
}
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(height_max_width);
@ -692,7 +738,9 @@ void GLGizmoMmuSegmentation::update_model_object()
if (updated) {
const ModelObjectPtrs &mos = wxGetApp().model().objects;
wxGetApp().obj_list()->update_info_items(std::find(mos.begin(), mos.end(), mo) - mos.begin());
size_t obj_idx = std::find(mos.begin(), mos.end(), mo) - mos.begin();
wxGetApp().obj_list()->update_info_items(obj_idx);
wxGetApp().plater()->get_partplate_list().notify_instance_update(obj_idx, 0);
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
}
}
@ -727,6 +775,7 @@ void GLGizmoMmuSegmentation::init_model_triangle_selectors()
EnforcerBlockerType max_ebt = (EnforcerBlockerType)std::min(m_extruders_colors.size(), (size_t)EnforcerBlockerType::ExtruderMax);
m_triangle_selectors.back()->deserialize(mv->mmu_segmentation_facets.get_data(), false, max_ebt);
m_triangle_selectors.back()->request_update_render_data();
m_triangle_selectors.back()->set_wireframe_needed(true);
m_volumes_extruder_idxs.push_back(mv->extruder_id());
}
}

View file

@ -100,9 +100,9 @@ protected:
wxString handle_snapshot_action_name(bool shift_down, Button button_down) const override;
std::string get_gizmo_entering_text() const override { return _u8L("Entering color painting"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving color painting"); }
std::string get_action_snapshot_name() override { return _u8L("Color painting editing"); }
std::string get_gizmo_entering_text() const override { return "Entering color painting"; }
std::string get_gizmo_leaving_text() const override { return "Leaving color painting"; }
std::string get_action_snapshot_name() override { return "Color painting editing"; }
// BBS
size_t m_selected_extruder_idx = 0;

View file

@ -877,12 +877,12 @@ void GLGizmoPainterBase::on_set_state()
on_opening();
const Selection& selection = m_parent.get_selection();
Camera& camera = wxGetApp().plater()->get_camera();
Vec3d rotate_target = selection.get_bounding_box().center();
rotate_target(2) = 0.f;
Vec3d position = camera.get_position();
//Camera& camera = wxGetApp().plater()->get_camera();
//Vec3d rotate_target = selection.get_bounding_box().center();
//rotate_target(2) = 0.f;
//Vec3d position = camera.get_position();
//camera.set_target(rotate_target);
camera.look_at(position, rotate_target, Vec3d::UnitZ());
//camera.look_at(position, rotate_target, Vec3d::UnitZ());
}
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
// we are actually shutting down
@ -1076,6 +1076,20 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui)
if (!shader)
return;
assert(shader->get_name() == "mm_gouraud");
GLint position_id = -1;
GLint barycentric_id = -1;
if (wxGetApp().plater()->is_wireframe_enabled()) {
position_id = shader->get_attrib_location("v_position");
barycentric_id = shader->get_attrib_location("v_barycentric");
if (m_need_wireframe && wxGetApp().plater()->is_show_wireframe()) {
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", show_wireframe on");
shader->set_uniform("show_wireframe", true);
}
else {
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", show_wireframe off");
shader->set_uniform("show_wireframe", false);
}
}
for (size_t buffer_idx = 0; buffer_idx < m_triangle_patches.size(); ++buffer_idx) {
if (this->has_VBOs(buffer_idx)) {
@ -1094,11 +1108,13 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui)
std::array<float, 4> new_color = adjust_color_for_rendering(color);
shader->set_uniform("uniform_color", new_color);
//shader->set_uniform("uniform_color", color);
this->render(buffer_idx);
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", buffer_idx %1%: new_color[%2%, %3%, %4%, %5%]")%buffer_idx%new_color[0]%new_color[1]%new_color[2]%new_color[3];
this->render(buffer_idx, (int)position_id, (int)barycentric_id);
}
}
if (m_paint_contour.has_VBO()) {
if (m_paint_contour.has_VBO())
{
ScopeGuard guard_mm_gouraud([shader]() { shader->start_using(); });
shader->stop_using();
@ -1117,6 +1133,7 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui)
void TriangleSelectorPatch::update_triangles_per_type()
{
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", enter");
m_triangle_patches.resize((int)EnforcerBlockerType::ExtruderMax + 1);
for (int i = 0; i < m_triangle_patches.size(); i++) {
auto& patch = m_triangle_patches[i];
@ -1124,14 +1141,44 @@ void TriangleSelectorPatch::update_triangles_per_type()
patch.triangle_indices.reserve(m_triangles.size() / 3);
}
bool using_wireframe = (wxGetApp().plater()->is_wireframe_enabled())?true:false;
for (auto& triangle : m_triangles) {
if (!triangle.valid() || triangle.is_split())
continue;
int state = (int)triangle.get_state();
auto& patch = m_triangle_patches[state];
patch.triangle_indices.insert(patch.triangle_indices.end(), triangle.verts_idxs.begin(), triangle.verts_idxs.end());
//patch.triangle_indices.insert(patch.triangle_indices.end(), triangle.verts_idxs.begin(), triangle.verts_idxs.end());
for (int i = 0; i < 3; ++i) {
int j = triangle.verts_idxs[i];
int index = using_wireframe?int(patch.patch_vertices.size()/6) : int(patch.patch_vertices.size()/3);
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: i=%2%, j=%3%, index=%4%, v[%5%,%6%,%7%]")%__LINE__%i%j%index%m_vertices[j].v(0)%m_vertices[j].v(1)%m_vertices[j].v(2);
patch.patch_vertices.emplace_back(m_vertices[j].v(0));
patch.patch_vertices.emplace_back(m_vertices[j].v(1));
patch.patch_vertices.emplace_back(m_vertices[j].v(2));
if (using_wireframe) {
if (i == 0) {
patch.patch_vertices.emplace_back(1.0);
patch.patch_vertices.emplace_back(0.0);
patch.patch_vertices.emplace_back(0.0);
}
else if (i == 1) {
patch.patch_vertices.emplace_back(0.0);
patch.patch_vertices.emplace_back(1.0);
patch.patch_vertices.emplace_back(0.0);
}
else {
patch.patch_vertices.emplace_back(0.0);
patch.patch_vertices.emplace_back(0.0);
patch.patch_vertices.emplace_back(1.0);
}
}
patch.triangle_indices.emplace_back( index);
}
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: state=%2%, vertice size=%3%, triangle size %4%")%__LINE__%state%patch.patch_vertices.size()%patch.triangle_indices.size();
}
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("exit");
}
void TriangleSelectorPatch::update_selector_triangles()
@ -1152,6 +1199,8 @@ void TriangleSelectorPatch::update_triangles_per_patch()
auto [neighbors, neighbors_propagated] = this->precompute_all_neighbors();
std::vector<bool> visited(m_triangles.size(), false);
bool using_wireframe = (wxGetApp().plater()->is_wireframe_enabled())?true:false;
auto get_all_touching_triangles = [this](int facet_idx, const Vec3i& neighbors, const Vec3i& neighbors_propagated) -> std::vector<int> {
assert(facet_idx != -1 && facet_idx < int(m_triangles.size()));
assert(this->verify_triangle_neighbors(m_triangles[facet_idx], neighbors));
@ -1202,7 +1251,32 @@ void TriangleSelectorPatch::update_triangles_per_patch()
if (!visited[current_facet]) {
Triangle& triangle = m_triangles[current_facet];
patch.triangle_indices.insert(patch.triangle_indices.end(), triangle.verts_idxs.begin(), triangle.verts_idxs.end());
for (int i = 0; i < 3; ++i) {
int j = triangle.verts_idxs[i];
int index = using_wireframe?int(patch.patch_vertices.size()/6) : int(patch.patch_vertices.size()/3);
patch.patch_vertices.emplace_back(m_vertices[j].v(0));
patch.patch_vertices.emplace_back(m_vertices[j].v(1));
patch.patch_vertices.emplace_back(m_vertices[j].v(2));
if (using_wireframe) {
if (i == 0) {
patch.patch_vertices.emplace_back(1.0);
patch.patch_vertices.emplace_back(0.0);
patch.patch_vertices.emplace_back(0.0);
}
else if (i == 1) {
patch.patch_vertices.emplace_back(0.0);
patch.patch_vertices.emplace_back(1.0);
patch.patch_vertices.emplace_back(0.0);
}
else {
patch.patch_vertices.emplace_back(0.0);
patch.patch_vertices.emplace_back(0.0);
patch.patch_vertices.emplace_back(1.0);
}
}
patch.triangle_indices.emplace_back( index);
}
//patch.triangle_indices.insert(patch.triangle_indices.end(), triangle.verts_idxs.begin(), triangle.verts_idxs.end());
patch.facet_indices.push_back(current_facet);
std::vector<int> touching_triangles = get_all_touching_triangles(current_facet, neighbors[current_facet], neighbors_propagated[current_facet]);
@ -1246,16 +1320,17 @@ void TriangleSelectorPatch::set_filter_state(bool is_filter_state)
void TriangleSelectorPatch::update_render_data()
{
if (m_paint_changed || m_vertices_VBO_id == 0) {
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", m_paint_changed=%1%, m_triangle_patches.size %2%")%m_paint_changed%m_triangle_patches.size();
if (m_paint_changed || (m_triangle_patches.size() == 0)) {
this->release_geometry();
m_patch_vertices.reserve(m_vertices.size() * 3);
/*m_patch_vertices.reserve(m_vertices.size() * 3);
for (const Vertex& vr : m_vertices) {
m_patch_vertices.emplace_back(vr.v.x());
m_patch_vertices.emplace_back(vr.v.y());
m_patch_vertices.emplace_back(vr.v.z());
}
this->finalize_vertices();
this->finalize_vertices();*/
if (m_filter_state)
update_triangles_per_patch();
@ -1266,6 +1341,8 @@ void TriangleSelectorPatch::update_render_data()
m_paint_changed = false;
}
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", before paint_contour");
m_paint_contour.release_geometry();
std::vector<Vec2i> contour_edges = this->get_seed_fill_contour();
m_paint_contour.contour_vertices.reserve(contour_edges.size() * 6);
@ -1284,17 +1361,37 @@ void TriangleSelectorPatch::update_render_data()
m_paint_contour.contour_indices_size = m_paint_contour.contour_indices.size();
m_paint_contour.finalize_geometry();
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", exit");
}
void TriangleSelectorPatch::render(int triangle_indices_idx)
void TriangleSelectorPatch::render(int triangle_indices_idx, int position_id, int barycentric_id)
{
assert(triangle_indices_idx < this->m_triangle_indices_VBO_ids.size());
assert(this->m_triangle_patches.size() == this->m_triangle_indices_VBO_ids.size());
assert(this->m_vertices_VBO_id != 0);
//assert(this->m_vertices_VBO_id != 0);
assert(this->m_triangle_patches.size() == this->m_vertices_VBO_ids.size());
assert(this->m_vertices_VBO_ids[triangle_indices_idx] != 0);
assert(this->m_triangle_indices_VBO_ids[triangle_indices_idx] != 0);
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_vertices_VBO_id));
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
//glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_vertices_VBO_id));
//glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
if (this->m_triangle_indices_sizes[triangle_indices_idx] > 0) {
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_vertices_VBO_ids[triangle_indices_idx]));
if (position_id != -1) {
glsafe(::glEnableVertexAttribArray((GLint)position_id));
glsafe(::glVertexAttribPointer((GLint)position_id, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), nullptr));
}
else {
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), nullptr));
}
if (barycentric_id != -1) {
glsafe(::glEnableVertexAttribArray((GLint)barycentric_id));
glsafe(::glVertexAttribPointer((GLint)barycentric_id, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (GLvoid*)(intptr_t)(3 * sizeof(float))));
}
//glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), nullptr));
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: triangle_indices_idx %2%, bind vertex vbo, buffer id %3%")%__LINE__%triangle_indices_idx%this->m_vertices_VBO_ids[triangle_indices_idx];
}
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
@ -1303,45 +1400,68 @@ void TriangleSelectorPatch::render(int triangle_indices_idx)
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->m_triangle_indices_VBO_ids[triangle_indices_idx]));
glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->m_triangle_indices_sizes[triangle_indices_idx]), GL_UNSIGNED_INT, nullptr));
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: triangle_indices_idx %2%, bind indices vbo, buffer id %3%")%__LINE__%triangle_indices_idx%this->m_triangle_indices_VBO_ids[triangle_indices_idx];
}
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
if ((this->m_triangle_indices_sizes[triangle_indices_idx] > 0)&&(position_id != -1))
glsafe(::glDisableVertexAttribArray(position_id));
if ((this->m_triangle_indices_sizes[triangle_indices_idx] > 0)&&(barycentric_id != -1))
glsafe(::glDisableVertexAttribArray((GLint)barycentric_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
if (this->m_triangle_indices_sizes[triangle_indices_idx] > 0)
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
void TriangleSelectorPatch::release_geometry()
{
if (m_vertices_VBO_id) {
/*if (m_vertices_VBO_id) {
glsafe(::glDeleteBuffers(1, &m_vertices_VBO_id));
m_vertices_VBO_id = 0;
}*/
for (auto& vertice_VBO_id : m_vertices_VBO_ids) {
glsafe(::glDeleteBuffers(1, &vertice_VBO_id));
vertice_VBO_id = 0;
}
for (auto& triangle_indices_VBO_id : m_triangle_indices_VBO_ids) {
glsafe(::glDeleteBuffers(1, &triangle_indices_VBO_id));
triangle_indices_VBO_id = 0;
}
this->clear();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: released geometry")%__LINE__;
}
void TriangleSelectorPatch::finalize_vertices()
{
assert(m_vertices_VBO_id == 0);
/*assert(m_vertices_VBO_id == 0);
if (!this->m_patch_vertices.empty()) {
glsafe(::glGenBuffers(1, &this->m_vertices_VBO_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_vertices_VBO_id));
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->m_patch_vertices.size() * sizeof(float), this->m_patch_vertices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
this->m_patch_vertices.clear();
}
}*/
}
void TriangleSelectorPatch::finalize_triangle_indices()
{
m_vertices_VBO_ids.resize(m_triangle_patches.size());
m_triangle_indices_VBO_ids.resize(m_triangle_patches.size());
m_triangle_indices_sizes.resize(m_triangle_patches.size());
assert(std::all_of(m_triangle_indices_VBO_ids.cbegin(), m_triangle_indices_VBO_ids.cend(), [](const auto& ti_VBO_id) { return ti_VBO_id == 0; }));
for (size_t buffer_idx = 0; buffer_idx < m_triangle_patches.size(); ++buffer_idx) {
std::vector<float>& patch_vertices = m_triangle_patches[buffer_idx].patch_vertices;
if (!patch_vertices.empty()) {
glsafe(::glGenBuffers(1, &m_vertices_VBO_ids[buffer_idx]));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices_VBO_ids[buffer_idx]));
glsafe(::glBufferData(GL_ARRAY_BUFFER, patch_vertices.size() * sizeof(float), patch_vertices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: buffer_idx %2%, vertices size %3%, buffer id %4%")%__LINE__%buffer_idx%patch_vertices.size()%m_vertices_VBO_ids[buffer_idx];
patch_vertices.clear();
}
std::vector<int>& triangle_indices = m_triangle_patches[buffer_idx].triangle_indices;
m_triangle_indices_sizes[buffer_idx] = triangle_indices.size();
if (!triangle_indices.empty()) {
@ -1349,6 +1469,7 @@ void TriangleSelectorPatch::finalize_triangle_indices()
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_triangle_indices_VBO_ids[buffer_idx]));
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangle_indices.size() * sizeof(int), triangle_indices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: buffer_idx %2%, vertices size %3%, buffer id %4%")%__LINE__%buffer_idx%triangle_indices.size()%m_triangle_indices_VBO_ids[buffer_idx];
triangle_indices.clear();
}
}

View file

@ -73,6 +73,8 @@ public:
// to be already set.
virtual void render(ImGuiWrapper *imgui);
void render() { this->render(nullptr); }
void set_wireframe_needed(bool need_wireframe) { m_need_wireframe = need_wireframe; }
bool get_wireframe_needed() { return m_need_wireframe; }
// BBS
void request_update_render_data(bool paint_changed = false)
@ -108,10 +110,12 @@ private:
protected:
GLPaintContour m_paint_contour;
bool m_need_wireframe {false};
};
// BBS
struct TrianglePatch {
std::vector<float> patch_vertices;
std::vector<int> triangle_indices;
std::vector<int> facet_indices;
EnforcerBlockerType type = EnforcerBlockerType::NONE;
@ -160,11 +164,15 @@ protected:
void clear()
{
// BBS
this->m_vertices_VBO_ids.clear();
this->m_triangle_indices_VBO_ids.clear();
this->m_triangle_indices_sizes.clear();
for (TrianglePatch& patch : this->m_triangle_patches)
{
patch.patch_vertices.clear();
patch.triangle_indices.clear();
}
this->m_triangle_patches.clear();
}
@ -174,7 +182,7 @@ protected:
return this->m_triangle_indices_VBO_ids[triangle_indices_idx] != 0;
}
std::vector<float> m_patch_vertices;
//std::vector<float> m_patch_vertices;
std::vector<TrianglePatch> m_triangle_patches;
// When the triangle indices are loaded into the graphics card as Vertex Buffer Objects,
@ -183,7 +191,8 @@ protected:
// IDs of the Vertex Array Objects, into which the geometry has been loaded.
// Zero if the VBOs are not sent to GPU yet.
unsigned int m_vertices_VBO_id{ 0 };
//unsigned int m_vertices_VBO_id{ 0 };
std::vector<unsigned int> m_vertices_VBO_ids;
std::vector<unsigned int> m_triangle_indices_VBO_ids;
std::vector<std::array<float, 4>> m_ebt_colors;
@ -192,7 +201,7 @@ protected:
private:
void update_render_data();
void render(int buffer_idx);
void render(int buffer_idx, int position_id = -1, int barycentric_id = -1);
};

View file

@ -132,6 +132,7 @@ void GLGizmoSeam::show_tooltip_information(float caption_max, float x, float y)
float font_size = ImGui::GetFontSize();
ImVec2 button_size = ImVec2(font_size * 1.8, font_size * 1.3);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 0, ImGui::GetStyle().FramePadding.y });
ImGui::ImageButton3(normal_id, hover_id, button_size);
if (ImGui::IsItemHovered()) {
@ -145,7 +146,7 @@ void GLGizmoSeam::show_tooltip_information(float caption_max, float x, float y)
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);
ImGui::PopStyleVar(2);
}
void GLGizmoSeam::tool_changed(wchar_t old_tool, wchar_t new_tool)
@ -184,7 +185,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
// First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that:
const float space_size = m_imgui->get_style_scaling() * 8;
const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x,
m_imgui->calc_text_size(m_desc.at("reset_direction")).x)
m_imgui->calc_text_size(m_desc.at("reset_direction")).x + ImGui::GetStyle().FramePadding.x * 2)
+ m_imgui->scaled(1.5f);
const float cursor_size_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f);
const float empty_button_width = m_imgui->calc_button_size("").x;
@ -206,31 +207,36 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("cursor_type"));
std::array<wchar_t, 2> tool_icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon};
std::array<wchar_t, 2> tool_ids = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon };
std::array<wchar_t, 2> icons;
if (m_is_dark_mode)
icons = { ImGui::CircleButtonDarkIcon, ImGui::SphereButtonDarkIcon};
else
icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon };
std::array<wxString, 2> tool_tips = { _L("Circle"), _L("Sphere")};
for (int i = 0; i < tool_icons.size(); i++) {
for (int i = 0; i < tool_ids.size(); i++) {
std::string str_label = std::string("##");
std::wstring btn_name = tool_icons[i] + boost::nowide::widen(str_label);
std::wstring btn_name = icons[i] + boost::nowide::widen(str_label);
if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.3f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0);
if (m_current_tool == tool_icons[i]) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
if (m_current_tool == tool_ids[i]) {
ImGui::PushStyleColor(ImGuiCol_Button, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, m_is_dark_mode ? ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f) : ImVec4(0.86f, 0.99f, 0.91f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.00f, 0.68f, 0.26f, 1.00f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0);
}
bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str());
if (m_current_tool == tool_icons[i])
if (m_current_tool == tool_ids[i])
{
ImGui::PopStyleColor(4);
ImGui::PopStyleVar(2);
}
ImGui::PopStyleVar(1);
if (btn_clicked && m_current_tool != tool_icons[i]) {
m_current_tool = tool_icons[i];
if (btn_clicked && m_current_tool != tool_ids[i]) {
m_current_tool = tool_ids[i];
for (auto& triangle_selector : m_triangle_selectors) {
triangle_selector->seed_fill_unselect_all_triangles();
triangle_selector->request_update_render_data();
@ -265,8 +271,18 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
ImGui::PushItemWidth(1.5 * slider_icon_width);
ImGui::BBLDragFloat("##cursor_radius_input", &m_cursor_radius, 0.05f, 0.0f, 0.0f, "%.2f");
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
ImGui::Separator();
if (m_c->object_clipper()->get_position() == 0.f) {
ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("clipping_of_view"));
}
else {
if (m_imgui->button(m_desc.at("reset_direction"))) {
wxGetApp().CallAfter([this]() {
m_c->object_clipper()->set_position(-1., false);
});
}
}
auto clp_dist = float(m_c->object_clipper()->get_position());
ImGui::SameLine(sliders_left_width);

View file

@ -29,9 +29,9 @@ protected:
wxString handle_snapshot_action_name(bool shift_down, Button button_down) const override;
std::string get_gizmo_entering_text() const override { return _u8L("Entering Seam painting"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving Seam painting"); }
std::string get_action_snapshot_name() override { return _u8L("Paint-on seam editing"); }
std::string get_gizmo_entering_text() const override { return "Entering Seam painting"; }
std::string get_gizmo_leaving_text() const override { return "Leaving Seam painting"; }
std::string get_action_snapshot_name() override { return "Paint-on seam editing"; }
private:
bool on_init() override;

View file

@ -236,7 +236,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
ImGuiWindowFlags_NoCollapse;
m_imgui->begin(on_get_name(), flag);
m_imgui->text_colored(ImVec4(0.15f, 0.18f, 0.19f, 1.00f), tr_mesh_name + ":");
m_imgui->text(tr_mesh_name + ":");
// BBS: somehow the calculated utf8 width is too narrow, have to add 35 here
ImGui::SameLine(text_left_width + space_size);
std::string name = m_volume->name;
@ -244,7 +244,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
name = name.substr(0, m_gui_cfg->max_char_in_name - 3) + "...";
m_imgui->text_colored(ImVec4(0.42f, 0.42f, 0.42f, 1.00f), name);
m_imgui->text_colored(ImVec4(0.15f, 0.18f, 0.19f, 1.00f), tr_triangles + ":");
m_imgui->text(tr_triangles + ":");
ImGui::SameLine(text_left_width + space_size);
size_t orig_triangle_count = m_volume->mesh().its.indices.size();
@ -361,22 +361,26 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.15f, 0.18f, 0.19f, 1.00f));
m_imgui->disabled_begin(is_worker_running || ! is_result_ready);
m_imgui->push_confirm_button_style();
if (m_imgui->bbl_button(_L("Apply"))) {
apply_simplify();
}
else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && is_worker_running) {
ImGui::SetTooltip("%s", _u8L("Can't apply when proccess preview.").c_str());
}
m_imgui->pop_confirm_button_style();
m_imgui->disabled_end(); // state !settings
ImGui::SameLine();
m_imgui->disabled_begin(is_cancelling);
m_imgui->push_cancel_button_style();
if (m_imgui->bbl_button(_L("Cancel"))) {
close();
}
else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && is_cancelling)
ImGui::SetTooltip("%s", _u8L("Operation already cancelling. Please wait few seconds.").c_str());
m_imgui->pop_cancel_button_style();
m_imgui->disabled_end(); // state cancelling
ImGui::PopStyleVar(3);

View file

@ -68,8 +68,8 @@ public:
void reslice_SLA_supports(bool postpone_error_messages = false) const;
bool wants_enter_leave_snapshots() const override { return true; }
std::string get_gizmo_entering_text() const override { return _u8L("Entering SLA support points"); }
std::string get_gizmo_leaving_text() const override { return _u8L("Leaving SLA support points"); }
std::string get_gizmo_entering_text() const override { return "Entering SLA support points"; }
std::string get_gizmo_leaving_text() const override { return "Leaving SLA support points"; }
private:
bool on_init() override;

View file

@ -23,20 +23,66 @@
namespace Slic3r {
namespace GUI {
static double g_normal_precise = 0.0015;
static const wxColour FONT_TEXTURE_BG = wxColour(0, 0, 0, 0);
static const wxColour FONT_TEXTURE_FG = *wxWHITE;
static const int FONT_SIZE = 12;
GLGizmoText::GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
{
}
GLGizmoText::~GLGizmoText()
{
for (int i = 0; i < m_textures.size(); i++) {
if (m_textures[i].texture != nullptr)
delete m_textures[i].texture;
}
}
bool GLGizmoText::on_init()
{
m_avail_font_names = init_occt_fonts();
update_font_texture();
m_scale = m_imgui->get_font_size();
m_shortcut_key = WXK_CONTROL_T;
return true;
}
void GLGizmoText::update_font_texture()
{
for (int i = 0; i < m_textures.size(); i++) {
if (m_textures[i].texture != nullptr)
delete m_textures[i].texture;
}
m_combo_width = 0.0f;
m_combo_height = 0.0f;
m_textures.clear();
m_textures.reserve(m_avail_font_names.size());
for (int i = 0; i < m_avail_font_names.size(); i++)
{
GLTexture* texture = new GLTexture();
auto face = wxString::FromUTF8(m_avail_font_names[i]);
auto retina_scale = m_parent.get_scale();
wxFont font { (int)round(retina_scale * FONT_SIZE), wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, face };
int w, h, hl;
if (texture->generate_texture_from_text(m_avail_font_names[i], font, w, h, hl, FONT_TEXTURE_BG, FONT_TEXTURE_FG)) {
//if (h < m_imgui->scaled(2.f)) {
TextureInfo info;
info.texture = texture;
info.w = w;
info.h = h;
info.hl = hl;
info.font_name = m_avail_font_names[i];
m_textures.push_back(info);
m_combo_width = std::max(m_combo_width, static_cast<float>(texture->m_original_width));
//}
}
}
m_combo_height = m_imgui->scaled(32.f / 15.f);
}
void GLGizmoText::on_set_state()
{
}
@ -68,28 +114,89 @@ void GLGizmoText::on_render_for_picking()
// TODO:
}
void GLGizmoText::push_combo_style(const float scale)
{
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale);
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_BorderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_Button, { 1.00f, 1.00f, 1.00f, 0.0f });
void GLGizmoText::push_button_style(bool pressed) {
if (m_is_dark_mode) {
if (pressed) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(43 / 255.f, 64 / 255.f, 54 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(43 / 255.f, 64 / 255.f, 54 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(43 / 255.f, 64 / 255.f, 54 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.f, 174 / 255.f, 66 / 255.f, 1.f));
}
else {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(45.f / 255.f, 45.f / 255.f, 49.f / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(45.f / 255.f, 45.f / 255.f, 49.f / 255.f, 1.f));
}
}
else {
if (pressed) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(219 / 255.f, 253 / 255.f, 231 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(219 / 255.f, 253 / 255.f, 231 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(219 / 255.f, 253 / 255.f, 231 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.f, 174 / 255.f, 66 / 255.f, 1.f));
}
else {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.f, 1.f, 1.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(238 / 255.f, 238 / 255.f, 238 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(238 / 255.f, 238 / 255.f, 238 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.f, 1.f, 1.f, 1.f));
}
}
}
void GLGizmoText::pop_button_style() {
ImGui::PopStyleColor(4);
}
void GLGizmoText::push_combo_style(const float scale) {
if (m_is_dark_mode) {
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale);
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG_DARK);
ImGui::PushStyleColor(ImGuiCol_BorderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImGuiWrapper::COL_WINDOW_BG_DARK);
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImGuiWrapper::COL_WINDOW_BG_DARK);
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImGuiWrapper::COL_WINDOW_BG_DARK);
ImGui::PushStyleColor(ImGuiCol_Button, { 1.00f, 1.00f, 1.00f, 0.0f });
}
else {
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale);
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_BorderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_Button, { 1.00f, 1.00f, 1.00f, 0.0f });
}
}
void GLGizmoText::pop_combo_style()
{
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(7);
ImGui::PopStyleColor(9);
}
// BBS
void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
{
if (m_imgui->get_font_size() != m_scale) {
m_scale = m_imgui->get_font_size();
update_font_texture();
}
if (m_textures.size() == 0) {
BOOST_LOG_TRIVIAL(info) << "GLGizmoText has no texture";
return;
}
const float win_h = ImGui::GetWindowHeight();
y = std::min(y, bottom_limit - win_h);
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
@ -114,12 +221,9 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
float input_size = input_text_size - button_size * 2 - ImGui::GetStyle().ItemSpacing.x * 4;
ImTextureID normal_B = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_B);
ImTextureID press_B_hover = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_B_HOVER);
ImTextureID press_B_press = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_B_PRESS);
ImTextureID normal_T = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_T);
ImTextureID press_T_hover = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_T_HOVER);
ImTextureID press_T_press = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_T_PRESS);
ImTextureID normal_B_dark = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_B_DARK);
ImTextureID normal_T_dark = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_T_DARK);
// adjust window position to avoid overlap the view toolbar
if (last_h != win_h || last_y != y) {
@ -133,28 +237,29 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
ImGui::AlignTextToFramePadding();
const char** cstr_font_names = (const char**)calloc(m_avail_font_names.size(), sizeof(const char*));
for (int i = 0; i < m_avail_font_names.size(); i++)
cstr_font_names[i] = m_avail_font_names[i].c_str();
m_imgui->text(_L("Font"));
ImGui::SameLine(caption_size);
ImGui::PushItemWidth(input_text_size + ImGui::GetFrameHeight() * 2);
push_combo_style(currt_scale);
if (ImGui::BBLBeginCombo("##Font", cstr_font_names[m_curr_font_idx], 0)) {
int font_index = m_curr_font_idx;
if (ImGui::BBLBeginCombo("##Font", m_textures[m_curr_font_idx].font_name.c_str(), 0)) {
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(4.0f, 0.0f) * currt_scale);
for (int i = 0; i < m_avail_font_names.size(); i++) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8, 4));
for (int i = 0; i < m_textures.size(); i++) {
const bool is_selected = (m_curr_font_idx == i);
if (ImGui::BBLSelectable(cstr_font_names[i], is_selected)) {
ImTextureID icon_id = (ImTextureID)(intptr_t)(m_textures[i].texture->get_id());
ImVec4 tint_color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
ImVec2 selectable_size(std::max((input_text_size + ImGui::GetFrameHeight() * 2), m_combo_width), m_combo_height);
if (ImGui::BBLImageSelectable(icon_id, selectable_size, { (float)m_textures[i].w, (float)m_textures[i].h }, m_textures[i].hl, tint_color, { 0, 0 }, {1, 1}, is_selected)) {
m_curr_font_idx = i;
m_font_name = cstr_font_names[m_curr_font_idx];
m_font_name = m_textures[m_curr_font_idx].font_name;
}
if (is_selected) {
ImGui::SetItemDefaultFocus();
}
}
ImGui::PopStyleVar(2);
ImGui::PopStyleVar(3);
ImGui::EndCombo();
}
@ -167,12 +272,19 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
if (m_font_size < 3.0f)m_font_size = 3.0f;
ImGui::SameLine();
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0.0,0.0});
ImGui::BBLImageButton(normal_B,press_B_hover,press_B_press,{button_size,button_size},m_bold);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * currt_scale);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {1.0f * currt_scale, 1.0f * currt_scale });
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f * currt_scale);
push_button_style(m_bold);
if (ImGui::ImageButton(m_is_dark_mode ? normal_B_dark : normal_B, { button_size - 2 * ImGui::GetStyle().FramePadding.x, button_size - 2 * ImGui::GetStyle().FramePadding.y }))
m_bold = !m_bold;
pop_button_style();
ImGui::SameLine();
ImGui::BBLImageButton(normal_T,press_T_hover,press_T_press,{button_size,button_size},m_italic);
ImGui::PopStyleVar(2);
push_button_style(m_italic);
if (ImGui::ImageButton(m_is_dark_mode ? normal_T_dark : normal_T, { button_size - 2 * ImGui::GetStyle().FramePadding.x, button_size - 2 * ImGui::GetStyle().FramePadding.y }))
m_italic = !m_italic;
pop_button_style();
ImGui::PopStyleVar(3);
ImGui::AlignTextToFramePadding();
m_imgui->text(_L("Thickness"));
@ -185,6 +297,7 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
m_imgui->text(_L("Input text"));
ImGui::SameLine(caption_size);
ImGui::PushItemWidth(input_text_size);
ImGui::InputText("", m_text, sizeof(m_text));
ImGui::Separator();
@ -194,13 +307,29 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
ImGui::SameLine(offset);
bool add_clicked = m_imgui->button(_L("Add"));
if (add_clicked) {
m_imgui->disabled_end();
GizmoImguiEnd();
ImGui::PopStyleVar();
ImGuiWrapper::pop_toolbar_style();
TriangleMesh mesh;
load_text_shape(m_text, m_font_name.c_str(), m_font_size, m_thickness, m_bold, m_italic, mesh);
ObjectList* obj_list = wxGetApp().obj_list();
obj_list->load_mesh_part(mesh, "text_shape");
return;
}
m_imgui->disabled_end();
#if 0
ImGuiIO& io = ImGui::GetIO();
ImFontAtlas* atlas = io.Fonts;
ImVec4 tint_col = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
ImVec4 border_col = ImVec4(0.0f, 0.0f, 0.0f, 0.8f);
m_imgui->text(wxString("") << atlas->TexWidth << " * " << atlas->TexHeight);
ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), tint_col, border_col);
#endif
GizmoImguiEnd();
ImGui::PopStyleVar();
ImGuiWrapper::pop_toolbar_style();

View file

@ -3,7 +3,7 @@
#include "GLGizmoBase.hpp"
#include "slic3r/GUI/3DScene.hpp"
#include "../GLTexture.hpp"
namespace Slic3r {
@ -15,16 +15,34 @@ class GLGizmoText : public GLGizmoBase
{
private:
std::vector<std::string> m_avail_font_names;
char m_text[256] = { 0 };
char m_text[1024] = { 0 };
std::string m_font_name;
float m_font_size = 16.f;
int m_curr_font_idx = 0;
bool m_bold = true;
bool m_italic = false;
float m_thickness = 2.f;
float m_combo_height = 0.0f;
float m_combo_width = 0.0f;
float m_scale;
class TextureInfo {
public:
GLTexture* texture { nullptr };
int h;
int w;
int hl;
std::string font_name;
};
std::vector<TextureInfo> m_textures;
public:
GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
~GLGizmoText();
void update_font_texture();
protected:
virtual bool on_init() override;
@ -34,6 +52,8 @@ protected:
virtual void on_render_for_picking() override;
void push_combo_style(const float scale);
void pop_combo_style();
void push_button_style(bool pressed);
void pop_button_style();
virtual void on_set_state() override;
virtual CommonGizmosDataID on_get_requirements() const override;
virtual void on_render_input_window(float x, float y, float bottom_limit);

View file

@ -433,11 +433,11 @@ void ObjectClipper::set_position(double pos, bool keep_normal)
int active_inst = get_pool()->selection_info()->get_active_instance();
double z_shift = get_pool()->selection_info()->get_sla_shift();
Vec3d camera_dir = wxGetApp().plater()->get_camera().get_dir_forward();
if (abs(camera_dir(0)) > EPSILON || abs(camera_dir(1)) > EPSILON)
camera_dir(2) = 0;
//Vec3d camera_dir = wxGetApp().plater()->get_camera().get_dir_forward();
//if (abs(camera_dir(0)) > EPSILON || abs(camera_dir(1)) > EPSILON)
// camera_dir(2) = 0;
Vec3d normal = (keep_normal && m_clp) ? m_clp->get_normal() : -camera_dir;
Vec3d normal = (keep_normal && m_clp) ? m_clp->get_normal() : /*-camera_dir;*/ -wxGetApp().plater()->get_camera().get_dir_forward();
const Vec3d& center = mo->instances[active_inst]->get_offset() + Vec3d(0., 0., z_shift);
float dist = normal.dot(center);
@ -697,8 +697,7 @@ void ModelObjectsClipper::render_cut() const
void ModelObjectsClipper::set_position(double pos, bool keep_normal)
{
Vec3d camera_dir = wxGetApp().plater()->get_camera().get_dir_forward();
Vec3d normal = -camera_dir;
Vec3d normal = (keep_normal && m_clp) ? m_clp->get_normal() : -wxGetApp().plater()->get_camera().get_dir_forward();
const Vec3d& center = get_pool()->get_canvas()->volumes_bounding_box().center();
float dist = normal.dot(center);
@ -708,6 +707,7 @@ void ModelObjectsClipper::set_position(double pos, bool keep_normal)
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();
}

View file

@ -120,12 +120,57 @@ size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const
return Undefined;
}
void GLGizmosManager::switch_gizmos_icon_filename()
{
m_background_texture.metadata.filename = m_is_dark ? "toolbar_background_dark.png" : "toolbar_background.png";
m_background_texture.metadata.left = 16;
m_background_texture.metadata.top = 16;
m_background_texture.metadata.right = 16;
m_background_texture.metadata.bottom = 16;
if (!m_background_texture.metadata.filename.empty())
m_background_texture.texture.load_from_file(resources_dir() + "/images/" + m_background_texture.metadata.filename, false, GLTexture::SingleThreaded, false);
for (auto& gizmo : m_gizmos) {
gizmo->on_change_color_mode(m_is_dark);
switch (gizmo->get_sprite_id())
{
case(EType::Move):
gizmo->set_icon_filename(m_is_dark ? "toolbar_move_dark.svg" : "toolbar_move.svg");
break;
case(EType::Rotate):
gizmo->set_icon_filename(m_is_dark ? "toolbar_rotate_dark.svg" : "toolbar_rotate.svg");
break;
case(EType::Scale):
gizmo->set_icon_filename(m_is_dark ? "toolbar_scale_dark.svg" : "toolbar_scale.svg");
break;
case(EType::Flatten):
gizmo->set_icon_filename(m_is_dark ? "toolbar_flatten_dark.svg" : "toolbar_flatten.svg");
break;
case(EType::Cut):
gizmo->set_icon_filename(m_is_dark ? "toolbar_cut_dark.svg" : "toolbar_cut.svg");
break;
case(EType::FdmSupports):
gizmo->set_icon_filename(m_is_dark ? "toolbar_support_dark.svg" : "toolbar_support.svg");
break;
case(EType::Seam):
gizmo->set_icon_filename(m_is_dark ? "toolbar_seam_dark.svg" : "toolbar_seam.svg");
break;
case(EType::Text):
gizmo->set_icon_filename(m_is_dark ? "toolbar_text_dark.svg" : "toolbar_text.svg");
break;
case(EType::MmuSegmentation):
gizmo->set_icon_filename(m_is_dark ? "mmu_segmentation_dark.svg" : "mmu_segmentation.svg");
break;
}
}
}
bool GLGizmosManager::init()
{
bool result = init_icon_textures();
if (!result) return result;
m_background_texture.metadata.filename = "toolbar_background.png";
m_background_texture.metadata.filename = m_is_dark ? "toolbar_background_dark.png" : "toolbar_background.png";
m_background_texture.metadata.left = 16;
m_background_texture.metadata.top = 16;
m_background_texture.metadata.right = 16;
@ -139,23 +184,25 @@ bool GLGizmosManager::init()
// Order of gizmos in the vector must match order in EType!
//BBS: GUI refactor: add obj manipulation
m_gizmos.clear();
unsigned int sprite_id = 0;
m_gizmos.emplace_back(new GLGizmoMove3D(m_parent, "toolbar_move.svg", EType::Move, &m_object_manipulation));
m_gizmos.emplace_back(new GLGizmoRotate3D(m_parent, "toolbar_rotate.svg", EType::Rotate, &m_object_manipulation));
m_gizmos.emplace_back(new GLGizmoScale3D(m_parent, "toolbar_scale.svg", EType::Scale, &m_object_manipulation));
m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, "toolbar_flatten.svg", EType::Flatten));
m_gizmos.emplace_back(new GLGizmoAdvancedCut(m_parent, "toolbar_cut.svg", EType::Cut));
m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "toolbar_support.svg", EType::FdmSupports));
m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "toolbar_seam.svg", EType::Seam));
m_gizmos.emplace_back(new GLGizmoText(m_parent, "toolbar_text.svg", EType::Text));
m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, "mmu_segmentation.svg", EType::MmuSegmentation));
m_gizmos.emplace_back(new GLGizmoMove3D(m_parent, m_is_dark ? "toolbar_move_dark.svg" : "toolbar_move.svg", EType::Move, &m_object_manipulation));
m_gizmos.emplace_back(new GLGizmoRotate3D(m_parent, m_is_dark ? "toolbar_rotate_dark.svg" : "toolbar_rotate.svg", EType::Rotate, &m_object_manipulation));
m_gizmos.emplace_back(new GLGizmoScale3D(m_parent, m_is_dark ? "toolbar_scale_dark.svg" : "toolbar_scale.svg", EType::Scale, &m_object_manipulation));
m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, m_is_dark ? "toolbar_flatten_dark.svg" : "toolbar_flatten.svg", EType::Flatten));
m_gizmos.emplace_back(new GLGizmoAdvancedCut(m_parent, m_is_dark ? "toolbar_cut_dark.svg" : "toolbar_cut.svg", EType::Cut));
m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, m_is_dark ? "toolbar_support_dark.svg" : "toolbar_support.svg", EType::FdmSupports));
m_gizmos.emplace_back(new GLGizmoSeam(m_parent, m_is_dark ? "toolbar_seam_dark.svg" : "toolbar_seam.svg", EType::Seam));
m_gizmos.emplace_back(new GLGizmoText(m_parent, m_is_dark ? "toolbar_text_dark.svg" : "toolbar_text.svg", EType::Text));
m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, m_is_dark ? "mmu_segmentation_dark.svg" : "mmu_segmentation.svg", EType::MmuSegmentation));
m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify));
//m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++));
//m_gizmos.emplace_back(new GLGizmoFaceDetector(m_parent, "face recognition.svg", sprite_id++));
//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));
if(!m_assemble_view_data)
m_assemble_view_data.reset(new AssembleViewDataPool(&m_parent));
for (auto& gizmo : m_gizmos) {
if (! gizmo->init()) {
@ -163,6 +210,7 @@ bool GLGizmosManager::init()
return false;
}
gizmo->set_common_data_pool(m_common_gizmos_data.get());
gizmo->on_change_color_mode(m_is_dark);
}
m_current = Undefined;
@ -203,30 +251,20 @@ bool GLGizmosManager::init_icon_textures()
else
return false;
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_B_hover.svg", 20, 20, texture_id))
icon_list.insert(std::make_pair((int)IC_TEXT_B_HOVER, texture_id));
else
return false;
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_B_press.svg", 20, 20, texture_id))
icon_list.insert(std::make_pair((int)IC_TEXT_B_PRESS, texture_id));
else
return false;
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_B_dark.svg", 20, 20, texture_id))
icon_list.insert(std::make_pair((int)IC_TEXT_B_DARK, texture_id));
else
return false;
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_T.svg", 20, 20, texture_id))
icon_list.insert(std::make_pair((int)IC_TEXT_T, texture_id));
else
return false;
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_T_hover.svg", 20, 20, texture_id))
icon_list.insert(std::make_pair((int)IC_TEXT_T_HOVER, texture_id));
else
return false;
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_T_press.svg", 20, 20, texture_id))
icon_list.insert(std::make_pair((int)IC_TEXT_T_PRESS, texture_id));
else
return false;
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_T_dark.svg", 20, 20, texture_id))
icon_list.insert(std::make_pair((int)IC_TEXT_T_DARK, texture_id));
else
return false;
return true;
}
@ -617,6 +655,10 @@ bool GLGizmosManager::wants_reslice_supports_on_undo() const
&& dynamic_cast<const GLGizmoSlaSupports*>(m_gizmos.at(SlaSupports).get())->has_backend_supports());
}
void GLGizmosManager::on_change_color_mode(bool is_dark) {
m_is_dark = is_dark;
}
void GLGizmosManager::render_current_gizmo() const
{
if (!m_enabled || m_current == Undefined)
@ -640,7 +682,7 @@ void GLGizmosManager::render_painter_gizmo() const
void GLGizmosManager::render_painter_assemble_view() const
{
if (m_assemble_view_data)
if (m_assemble_view_data && m_assemble_view_data->model_objects_clipper())
m_assemble_view_data->model_objects_clipper()->render_cut();
}
@ -653,7 +695,7 @@ void GLGizmosManager::render_current_gizmo_for_picking_pass() const
m_gizmos[m_current]->render_for_picking();
}
void GLGizmosManager::render_overlay() const
void GLGizmosManager::render_overlay()
{
if (!m_enabled)
return;
@ -1037,6 +1079,14 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt)
//break;
//}
// BBS: Skip all keys when in gizmo. This is necessary for 3D text tool.
default:
{
if (is_running() && m_current == EType::Text) {
processed = true;
}
break;
}
}
}
@ -1484,6 +1534,9 @@ bool GLGizmosManager::activate_gizmo(EType type)
GLGizmoBase* new_gizmo = type == Undefined ? nullptr : m_gizmos[type].get();
if (old_gizmo) {
//if (m_current == Text) {
// wxGetApp().imgui()->destroy_fonts_texture();
//}
old_gizmo->set_state(GLGizmoBase::Off);
if (old_gizmo->get_state() != GLGizmoBase::Off)
return false; // gizmo refused to be turned off, do nothing.
@ -1503,8 +1556,12 @@ bool GLGizmosManager::activate_gizmo(EType type)
m_current = type;
if (new_gizmo)
if (new_gizmo) {
//if (m_current == Text) {
// wxGetApp().imgui()->load_fonts_texture();
//}
new_gizmo->set_state(GLGizmoBase::On);
}
return true;
}

View file

@ -144,6 +144,8 @@ private:
// key MENU_ICON_NAME, value = ImtextureID
std::map<int, void*> icon_list;
bool m_is_dark = false;
public:
std::unique_ptr<AssembleViewDataPool> m_assemble_view_data;
@ -153,16 +155,16 @@ public:
IC_TOOLBAR_TOOLTIP,
IC_TOOLBAR_TOOLTIP_HOVER,
IC_TEXT_B,
IC_TEXT_B_HOVER,
IC_TEXT_B_PRESS,
IC_TEXT_B_DARK,
IC_TEXT_T,
IC_TEXT_T_HOVER,
IC_TEXT_T_PRESS,
IC_TEXT_T_DARK,
IC_NAME_COUNT,
};
explicit GLGizmosManager(GLCanvas3D& parent);
void switch_gizmos_icon_filename();
bool init();
bool init_icon_textures();
@ -209,6 +211,7 @@ public:
bool is_enabled() const { return m_enabled; }
void set_enabled(bool enable) { m_enabled = enable; }
void set_icon_dirty() { m_icons_texture_dirty = true; }
void set_overlay_icon_size(float size);
void set_overlay_scale(float scale);
@ -256,6 +259,12 @@ public:
else
return nullptr;
}
void* get_icon_texture_id(MENU_ICON_NAME icon) const{
if (icon_list.find((int)icon) != icon_list.end())
return icon_list.at(icon);
else
return nullptr;
}
Vec3d get_flattening_normal() const;
@ -273,12 +282,13 @@ public:
bool is_in_editing_mode(bool error_notification = false) const;
bool is_hiding_instances() const;
void on_change_color_mode(bool is_dark);
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;
void render_overlay();
void render_arrow(const GLCanvas3D& parent, EType highlighted_type) const;

View file

@ -44,9 +44,11 @@ int HMSQuery::download_hms_info()
if (!config) return -1;
std::string hms_host = wxGetApp().app_config->get_hms_host();
std::string lang_code = wxGetApp().app_config->get_language_code();
std::string lang_code = HMSQuery::hms_language_code();
std::string url = (boost::format("https://%1%/query.php?lang=%2%") % hms_host % lang_code).str();
BOOST_LOG_TRIVIAL(info) << "hms: download url = " << url;
Slic3r::Http http = Slic3r::Http::get(url);
http.on_complete([this](std::string body, unsigned status) {
@ -102,6 +104,7 @@ int HMSQuery::load_from_local(std::string &version_info)
}
} catch(...) {
version_info = "";
BOOST_LOG_TRIVIAL(error) << "HMS: load_from_local failed";
return -1;
}
version_info = "";
@ -125,27 +128,42 @@ int HMSQuery::save_to_local()
json_file.close();
return 0;
}
BOOST_LOG_TRIVIAL(error) << "HMS: save_to_local failed";
return -1;
}
std::string HMSQuery::hms_language_code()
{
AppConfig* config = wxGetApp().app_config;
if (!config)
// set language code to en by default
return "en";
std::string lang_code = wxGetApp().app_config->get_language_code();
if (lang_code.empty()) {
// set language code to en by default
return "en";
}
return lang_code;
}
std::string HMSQuery::get_hms_file()
{
AppConfig* config = wxGetApp().app_config;
if (!config)
return HMS_INFO_FILE;
std::string lang_code = wxGetApp().app_config->get_language_code();
std::string lang_code = HMSQuery::hms_language_code();
return (boost::format("hms_%1%.json") % lang_code).str();
}
wxString HMSQuery::query_hms_msg(std::string long_error_code)
{
if (long_error_code.empty())
return wxEmptyString;
AppConfig* config = wxGetApp().app_config;
if (!config) return wxEmptyString;
std::string lang_code = HMSQuery::hms_language_code();
return _query_hms_msg(long_error_code, lang_code);
}
std::string hms_host = wxGetApp().app_config->get_hms_host();
std::string lang_code = wxGetApp().app_config->get_language_code();
wxString HMSQuery::_query_hms_msg(std::string long_error_code, std::string lang_code)
{
if (long_error_code.empty())
return wxEmptyString;
if (m_hms_json.contains("device_hms")) {
if (m_hms_json["device_hms"].contains(lang_code)) {
@ -160,34 +178,61 @@ wxString HMSQuery::query_hms_msg(std::string long_error_code)
}
}
BOOST_LOG_TRIVIAL(info) << "hms: query_hms_msg, not found error_code = " << long_error_code;
} else {
BOOST_LOG_TRIVIAL(error) << "hms: query_hms_msg, do not contains lang_code = " << lang_code;
// return first language
if (!m_hms_json["device_hms"].empty()) {
for (auto lang : m_hms_json["device_hms"]) {
for (auto item = lang.begin(); item != lang.end(); item++) {
if (item->contains("ecode")) {
std::string temp_string = (*item)["ecode"].get<std::string>();
if (boost::to_upper_copy(temp_string) == long_error_code) {
if (item->contains("intro")) {
return wxString::FromUTF8((*item)["intro"].get<std::string>());
}
}
}
}
}
}
}
} else {
BOOST_LOG_TRIVIAL(info) << "device_hms is not exists";
return wxEmptyString;
}
return wxEmptyString;
}
wxString HMSQuery::query_error_msg(std::string error_code)
wxString HMSQuery::_query_error_msg(std::string error_code, std::string lang_code)
{
AppConfig* config = wxGetApp().app_config;
if (!config) return wxEmptyString;
std::string hms_host = wxGetApp().app_config->get_hms_host();
std::string lang_code = wxGetApp().app_config->get_language_code();
if (m_hms_json.contains("device_error")) {
if (m_hms_json["device_error"].contains(lang_code)) {
for (auto item = m_hms_json["device_error"][lang_code].begin(); item != m_hms_json["device_error"][lang_code].end(); item++) {
if (item->contains("ecode") && (*item)["ecode"].get<std::string>() == error_code) {
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == error_code) {
if (item->contains("intro")) {
return wxString::FromUTF8((*item)["intro"].get<std::string>());
}
}
}
BOOST_LOG_TRIVIAL(info) << "hms: query_error_msg, not found error_code = " << error_code;
} else {
BOOST_LOG_TRIVIAL(error) << "hms: query_error_msg, do not contains lang_code = " << lang_code;
// return first language
if (!m_hms_json["device_error"].empty()) {
for (auto lang : m_hms_json["device_error"]) {
for (auto item = lang.begin(); item != lang.end(); item++) {
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == error_code) {
if (item->contains("intro")) {
return wxString::FromUTF8((*item)["intro"].get<std::string>());
}
}
}
}
}
}
}
else {
BOOST_LOG_TRIVIAL(info) << "device_error is not exists";
return wxEmptyString;
}
return wxEmptyString;
@ -197,7 +242,8 @@ wxString HMSQuery::query_print_error_msg(int print_error)
{
char buf[32];
::sprintf(buf, "%08X", print_error);
return query_error_msg(std::string(buf));
std::string lang_code = HMSQuery::hms_language_code();
return _query_error_msg(std::string(buf), lang_code);
}
int HMSQuery::check_hms_info()
@ -230,7 +276,7 @@ std::string get_hms_wiki_url(std::string error_code)
if (!config) return "";
std::string hms_host = wxGetApp().app_config->get_hms_host();
std::string lang_code = wxGetApp().app_config->get_language_code();
std::string lang_code = HMSQuery::hms_language_code();
std::string url = (boost::format("https://%1%/index.php?e=%2%&s=device_hms&lang=%3%")
% hms_host
% error_code

View file

@ -24,12 +24,14 @@ protected:
int load_from_local(std::string& version_info);
int save_to_local();
std::string get_hms_file();
wxString _query_hms_msg(std::string long_error_code, std::string lang_code = "en");
wxString _query_error_msg(std::string long_error_code, std::string lang_code = "en");
public:
HMSQuery() {}
int check_hms_info();
wxString query_hms_msg(std::string long_error_code);
wxString query_error_msg(std::string error_code);
wxString query_print_error_msg(int print_error);
static std::string hms_language_code();
};
int get_hms_info_version(std::string &version);

View file

@ -62,7 +62,8 @@ HMSNotifyItem::HMSNotifyItem(wxWindow *parent, HMSItem& item)
this->SetSizer(main_sizer);
this->Layout();
m_hms_content->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent &e) {
#ifdef __linux__
m_panel_hms->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& e) {
e.Skip();
if (!m_url.empty()) {
auto font = m_hms_content->GetFont();
@ -72,7 +73,7 @@ HMSNotifyItem::HMSNotifyItem(wxWindow *parent, HMSItem& item)
SetCursor(wxCURSOR_HAND);
}
});
m_hms_content->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &e) {
m_panel_hms->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) {
e.Skip();
if (!m_url.empty()) {
auto font = m_hms_content->GetFont();
@ -82,9 +83,37 @@ HMSNotifyItem::HMSNotifyItem(wxWindow *parent, HMSItem& item)
SetCursor(wxCURSOR_ARROW);
}
});
m_hms_content->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &e) {
m_panel_hms->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_url.empty()) wxLaunchDefaultBrowser(m_url);
});
});
m_hms_content->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_url.empty()) wxLaunchDefaultBrowser(m_url);
});
#else
m_hms_content->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& e) {
e.Skip();
if (!m_url.empty()) {
auto font = m_hms_content->GetFont();
font.SetUnderlined(true);
m_hms_content->SetFont(font);
Layout();
SetCursor(wxCURSOR_HAND);
}
});
m_hms_content->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) {
e.Skip();
if (!m_url.empty()) {
auto font = m_hms_content->GetFont();
font.SetUnderlined(false);
m_hms_content->SetFont(font);
Layout();
SetCursor(wxCURSOR_ARROW);
}
});
m_hms_content->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_url.empty()) wxLaunchDefaultBrowser(m_url);
});
#endif
}
HMSNotifyItem ::~HMSNotifyItem() {
;
@ -153,7 +182,8 @@ void HMSPanel::append_hms_panel(HMSItem& item) {
m_top_sizer->Add(m_notify_item, 0, wxALIGN_CENTER_HORIZONTAL);
else {
// debug for hms display error info
m_top_sizer->Add(m_notify_item, 0, wxALIGN_CENTER_HORIZONTAL);
// m_top_sizer->Add(m_notify_item, 0, wxALIGN_CENTER_HORIZONTAL);
BOOST_LOG_TRIVIAL(info) << "hms: do not display empty_item";
}
}
@ -180,6 +210,21 @@ void HMSPanel::update(MachineObject *obj)
}
}
void HMSPanel::show_status(int status)
{
if (last_status == status) return;
last_status = status;
if (((status & (int)MonitorStatus::MONITOR_DISCONNECTED) != 0)
|| ((status & (int)MonitorStatus::MONITOR_DISCONNECTED_SERVER) != 0)
|| ((status & (int)MonitorStatus::MONITOR_CONNECTING) != 0)
|| ((status & (int)MonitorStatus::MONITOR_NO_PRINTER) != 0)
) {
delete_hms_panels();
Layout();
}
}
bool HMSPanel::Show(bool show)
{
return wxPanel::Show(show);

View file

@ -6,6 +6,7 @@
#include <slic3r/GUI/Widgets/Button.hpp>
#include <slic3r/GUI/DeviceManager.hpp>
#include <slic3r/GUI/Widgets/ScrolledWindow.hpp>
#include <slic3r/GUI/StatusPanel.hpp>
#include <wx/html/htmlwin.h>
namespace Slic3r {
@ -44,6 +45,7 @@ protected:
wxScrolledWindow *m_scrolledWindow;
wxBoxSizer * m_top_sizer;
HMSNotifyItem * m_notify_item;
int last_status;
void append_hms_panel(HMSItem &item);
void delete_hms_panels();
@ -58,6 +60,8 @@ public:
void update(MachineObject *obj_);
void show_status(int status);
MachineObject *obj { nullptr };
};

View file

@ -839,7 +839,7 @@ void NotificationManager::HintNotification::render_text(ImGuiWrapper& imgui, con
float x_offset = m_left_indentation;
int last_end = 0;
float starting_y = (m_lines_count < 4 ? m_line_height / 2 * (4 - m_lines_count + 1) : m_line_height / 2);
float starting_y = (/*m_lines_count < 4 ? m_line_height / 2 * (4 - m_lines_count + 1) :*/ m_line_height / 2);
float shift_y = m_line_height;
std::string line;
@ -929,44 +929,32 @@ void NotificationManager::HintNotification::render_close_button(ImGuiWrapper& im
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(.0f, .0f, .0f, .0f));
std::string button_text;
button_text = ImGui::CloseNotifButton;
std::wstring button_text;
button_text = m_is_dark ? ImGui::CloseNotifDarkButton : ImGui::CloseNotifButton;
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - win_size.x / 10.f, win_pos.y),
ImVec2(win_pos.x, win_pos.y + win_size.y - 2 * m_line_height),
true))
{
button_text = ImGui::CloseNotifHoverButton;
}
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
ImVec2 button_pic_size = ImGui::CalcTextSize(into_u8(button_text).c_str());
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
m_close_b_w = button_size.y;
if (m_lines_count <= 3) {
m_close_b_y = win_size.y / 2 - button_size.y * 1.25f;
ImGui::SetCursorPosX(win_size.x - m_line_height * 2.75f);
ImGui::SetCursorPosY(m_close_b_y);
}
else {
ImGui::SetCursorPosX(win_size.x - m_line_height * 2.75f);
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y);
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - win_size.x / 10.f, win_pos.y + win_size.y / 2 - button_pic_size.y),
ImVec2(win_pos.x, win_pos.y + win_size.y / 2 + button_pic_size.y),
true))
{
button_text = m_is_dark ? ImGui::CloseNotifHoverDarkButton : ImGui::CloseNotifHoverButton;
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
close();
}
ImGui::SetCursorPosX(win_size.x - m_line_height * 2.75f);
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y);
if (imgui.button(button_text.c_str(), button_size.x, button_size.y))
{
close();
}
//invisible large button
ImGui::SetCursorPosX(win_size.x - m_line_height * 2.35f);
ImGui::SetCursorPosY(0);
if (imgui.button(" ", m_line_height * 2.125, win_size.y - 2 * m_line_height))
{
close();
}
ImGui::PopStyleColor(5);
//render_right_arrow_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
render_right_arrow_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
//render_logo(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
render_preferences_button(imgui, win_pos_x, win_pos_y);
if (!m_documentation_link.empty() && wxGetApp().app_config->get("suppress_hyperlinks") != "1")
@ -978,47 +966,38 @@ void NotificationManager::HintNotification::render_close_button(ImGuiWrapper& im
void NotificationManager::HintNotification::render_preferences_button(ImGuiWrapper& imgui, const float win_pos_x, const float win_pos_y)
{
auto scale = wxGetApp().plater()->get_current_canvas3D()->get_scale();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.0f, .0f, .0f, .0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(.0f, .0f, .0f, .0f));
push_style_color(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg), m_state == EState::FadingOut, m_current_fade_opacity);
push_style_color(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
push_style_color(ImGuiCol_TextSelectedBg, ImVec4(0, .75f, .75f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
std::string button_text;
button_text = ImGui::PreferencesButton;
std::wstring button_text;
button_text = m_is_dark ? ImGui::PreferencesDarkButton : ImGui::PreferencesButton;
//hover
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos_x - m_window_width / 15.f, win_pos_y + m_window_height - 1.75f * m_line_height),
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos_x - m_window_width / 15.f, win_pos_y + m_window_height - 1.5f * m_line_height),
ImVec2(win_pos_x, win_pos_y + m_window_height),
true)) {
button_text = ImGui::PreferencesHoverButton;
button_text = m_is_dark ? ImGui::PreferencesHoverDarkButton : ImGui::PreferencesHoverButton;
// tooltip
long time_now = wxGetLocalTime();
if (m_prefe_hover_time > 0 && m_prefe_hover_time < time_now) {
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
ImGui::BeginTooltip();
imgui.text(_u8L("Open Preferences."));
ImGui::EndTooltip();
ImGui::PopStyleColor();
}
if (m_prefe_hover_time == 0)
m_prefe_hover_time = time_now;
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
ImGui::PushStyleColor(ImGuiCol_Border, { 0,0,0,0 });
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 8 * scale, 1 * scale });
ImGui::BeginTooltip();
imgui.text(_u8L("Open Preferences."));
ImGui::EndTooltip();
ImGui::PopStyleColor(2);
ImGui::PopStyleVar();
}
else
m_prefe_hover_time = 0;
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
ImVec2 button_pic_size = ImGui::CalcTextSize(into_u8(button_text).c_str());
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
ImGui::SetCursorPosX(m_window_width - m_line_height * 1.75f);
if (m_lines_count <= 3) {
ImGui::SetCursorPosY(m_close_b_y + m_close_b_w / 4.f * 7.f);
}
else {
ImGui::SetCursorPosY(m_window_height - button_size.y - m_close_b_w / 4.f);
}
ImGui::SetCursorPosY(m_window_height - button_size.y - m_close_b_w / 4.f);
if (imgui.button(button_text.c_str(), button_size.x, button_size.y))
{
wxGetApp().open_preferences(1, "GUI");// 1 is to modify
wxGetApp().open_preferences();
}
ImGui::PopStyleColor(5);
@ -1028,7 +1007,7 @@ void NotificationManager::HintNotification::render_preferences_button(ImGuiWrapp
void NotificationManager::HintNotification::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)
{
// Used for debuging
auto scale = wxGetApp().plater()->get_current_canvas3D()->get_scale();
ImVec2 win_size(win_size_x, win_size_y);
ImVec2 win_pos(win_pos_x, win_pos_y);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.0f, .0f, .0f, .0f));
@ -1037,17 +1016,28 @@ void NotificationManager::HintNotification::render_right_arrow_button(ImGuiWrapp
push_style_color(ImGuiCol_TextSelectedBg, ImVec4(0, .75f, .75f, 1.f), m_state == EState::FadingOut, m_current_fade_opacity);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(.0f, .0f, .0f, .0f));
std::string button_text;
button_text = ImGui::RightArrowButton;
std::wstring button_text;
button_text = m_is_dark ? ImGui::RightArrowDarkButton : ImGui::RightArrowButton;
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
ImVec2 button_pic_size = ImGui::CalcTextSize(into_u8(button_text).c_str());
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos_x - m_window_width / 7.5f, win_pos_y + m_window_height - 1.5f * m_line_height),
ImVec2(win_pos_x - m_window_width / 15.f, win_pos_y + m_window_height),
true))
{
button_text = m_is_dark ? ImGui::RightArrowHoverDarkButton : ImGui::RightArrowHoverButton;
// tooltip
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
ImGui::PushStyleColor(ImGuiCol_Border, { 0,0,0,0 });
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 8 * scale, 1 * scale });
ImGui::BeginTooltip();
imgui.text(_u8L("Open next tip."));
ImGui::EndTooltip();
ImGui::PopStyleColor(2);
ImGui::PopStyleVar();
}
ImGui::SetCursorPosX(m_window_width - m_line_height * 3.f);
if (m_lines_count <= 3)
ImGui::SetCursorPosY(m_close_b_y + m_close_b_w / 4.f * 7.f);
else
ImGui::SetCursorPosY(m_window_height - button_size.y - m_close_b_w / 4.f);
ImGui::SetCursorPosY(m_window_height - button_size.y - m_close_b_w / 4.f);
if (imgui.button(button_text.c_str(), button_size.x * 0.8f, button_size.y * 1.f))
{
retrieve_data();
@ -1068,6 +1058,7 @@ void NotificationManager::HintNotification::render_logo(ImGuiWrapper& imgui, con
}
void NotificationManager::HintNotification::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)
{
auto scale = wxGetApp().plater()->get_current_canvas3D()->get_scale();
ImVec2 win_size(win_size_x, win_size_y);
ImVec2 win_pos(win_pos_x, win_pos_y);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.0f, .0f, .0f, .0f));
@ -1077,32 +1068,29 @@ void NotificationManager::HintNotification::render_documentation_button(ImGuiWra
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(.0f, .0f, .0f, .0f));
std::wstring button_text;
button_text = ImGui::DocumentationButton;
button_text = m_is_dark ? ImGui::DocumentationDarkButton : ImGui::DocumentationButton;
std::string placeholder_text;
placeholder_text = ImGui::EjectButton;
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - m_line_height * 5.f, win_pos.y),
ImVec2(win_pos.x - m_line_height * 2.5f, win_pos.y + win_size.y - 2 * m_line_height),
true))
{
button_text = ImGui::DocumentationHoverButton;
// tooltip
long time_now = wxGetLocalTime();
if (m_docu_hover_time > 0 && m_docu_hover_time < time_now) {
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
ImGui::BeginTooltip();
imgui.text(_u8L("Open Documentation in web browser."));
ImGui::EndTooltip();
ImGui::PopStyleColor();
}
if (m_docu_hover_time == 0)
m_docu_hover_time = time_now;
}
else
m_docu_hover_time = 0;
ImVec2 button_pic_size = ImGui::CalcTextSize(placeholder_text.c_str());
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos.x - m_line_height * 5.f, win_pos.y + win_size.y / 2 - button_pic_size.y),
ImVec2(win_pos.x - m_line_height * 2.5f, win_pos.y + win_size.y / 2 + button_pic_size.y),
true))
{
button_text = m_is_dark ? ImGui::DocumentationHoverDarkButton : ImGui::DocumentationHoverButton;
// tooltip
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
ImGui::PushStyleColor(ImGuiCol_Border, { 0,0,0,0 });
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 8 * scale, 1 * scale });
ImGui::BeginTooltip();
imgui.text(_u8L("Open Documentation in web browser."));
ImGui::EndTooltip();
ImGui::PopStyleColor(2);
ImGui::PopStyleVar();
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
open_documentation();
}
ImGui::SetCursorPosX(win_size.x - m_line_height * 5.0f);
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y);
if (imgui.button(button_text.c_str(), button_size.x, button_size.y))
@ -1110,14 +1098,6 @@ void NotificationManager::HintNotification::render_documentation_button(ImGuiWra
open_documentation();
}
//invisible large button
ImGui::SetCursorPosX(win_size.x - m_line_height * 4.625f);
ImGui::SetCursorPosY(0);
if (imgui.button(" ", m_line_height * 2.f, win_size.y - 2 * m_line_height))
{
open_documentation();
}
ImGui::PopStyleColor(5);
}

View file

@ -88,6 +88,7 @@ protected:
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,

View file

@ -12,16 +12,6 @@
#include "Tab.hpp"
#include "GUI_ObjectList.hpp"
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/sizer.h>
#include <wx/slider.h>
#include <wx/menu.h>
#include <wx/bmpcbox.h>
#include <wx/statline.h>
#include <wx/dcclient.h>
#include <wx/colordlg.h>
#include <cmath>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
@ -49,6 +39,7 @@ constexpr double miscalculation = scale_(scale_(1)); // equal to 1 mm2
static const float LEFT_MARGIN = 13.0f + 100.0f; // avoid thumbnail toolbar
static const float SLIDER_LENGTH = 680.0f;
static const float TEXT_WIDTH_DUMMY = 63.0f;
static const float ONE_LAYER_MARGIN = 10.0f;
static const ImVec2 ONE_LAYER_OFFSET = ImVec2(41.0f, 44.0f);
static const ImVec2 HORIZONTAL_SLIDER_SIZE = ImVec2(764.0f, 90.0f);//764 = 680 + handle_dummy_width * 2 + text_right_dummy
static const ImVec2 VERTICAL_SLIDER_SIZE = ImVec2(105.0f, 748.0f);//748 = 680 + text_dummy_height * 2
@ -440,7 +431,7 @@ IMSlider::IMSlider(int lowerValue, int higherValue, int minValue, int maxValue,
m_style = style == wxSL_HORIZONTAL || style == wxSL_VERTICAL ? style : wxSL_HORIZONTAL;
// BBS set to none style by default
m_extra_style = style == wxSL_VERTICAL ? 0 : 0;
m_selection = ssUndef;
m_selection = ssHigher;
m_is_need_post_tick_changed_event = false;
m_tick_change_event_type = Type::Unknown;
@ -452,13 +443,14 @@ bool IMSlider::init_texture()
bool result = true;
if (!is_horizontal()) {
// BBS init image texture id
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/reset_normal.svg", 20, 20, m_reset_normal_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/reset_hover.svg", 20, 20, m_reset_hover_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_on.svg", 24, 24, m_one_layer_on_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_on_hover.svg", 28, 28, m_one_layer_on_hover_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_off.svg", 28, 28, m_one_layer_off_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_off_hover.svg", 28, 28, m_one_layer_off_hover_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_arrow.svg", 28, 28, m_one_layer_arrow_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_on_dark.svg", 24, 24, m_one_layer_on_dark_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_on_hover_dark.svg", 28, 28, m_one_layer_on_hover_dark_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_off_dark.svg", 28, 28, m_one_layer_off_dark_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/one_layer_off_hover_dark.svg", 28, 28, m_one_layer_off_hover_dark_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/im_gcode_pause.svg", 14, 14, m_pause_icon_id);
result &= IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/im_slider_delete.svg", 14, 14, m_delete_icon_id);
}
@ -722,8 +714,8 @@ bool IMSlider::switch_one_layer_mode()
}
void IMSlider::draw_background(const ImRect& groove) {
const ImU32 bg_rect_col = IM_COL32(255, 255, 255, 255);
const ImU32 groove_col = IM_COL32(206, 206, 206, 255);
const ImU32 bg_rect_col = m_is_dark ? IM_COL32(65, 65, 71, 255) : IM_COL32(255, 255, 255, 255);
const ImU32 groove_col = m_is_dark ? IM_COL32(45, 45, 49, 255) : IM_COL32(206, 206, 206, 255);
if (is_horizontal() || m_ticks.empty()) {
ImVec2 groove_padding = ImVec2(2.0f, 2.0f) * m_scale;
@ -772,9 +764,9 @@ bool IMSlider::horizontal_slider(const char* str_id, int* value, int v_min, int
float triangle_offsets[3] = {-3.5f * m_scale, 3.5f * m_scale, -6.06f * m_scale};
const ImU32 white_bg = IM_COL32(255, 255, 255, 255);
const ImU32 white_bg = m_is_dark ? IM_COL32(65, 65, 71, 255) : IM_COL32(255, 255, 255, 255);
const ImU32 handle_clr = IM_COL32(0, 174, 66, 255);
const ImU32 handle_border_clr = IM_COL32(248, 248, 248, 255);
const ImU32 handle_border_clr = m_is_dark ? IM_COL32(65, 65, 71, 255) : IM_COL32(248, 248, 248, 255);
// calc groove size
ImVec2 groove_start = ImVec2(pos.x + handle_dummy_width, pos.y + size.y - groove_y - bottom_dummy);
@ -835,7 +827,7 @@ void IMSlider::draw_colored_band(const ImRect& groove, const ImRect& slideable_r
if (m_ticks.empty())
return;
const ImU32 blank_col = IM_COL32(255, 255, 255, 255);
const ImU32 blank_col = m_is_dark ? IM_COL32(65, 65, 71, 255) : IM_COL32(255, 255, 255, 255);
ImVec2 blank_padding = ImVec2(6.0f, 5.0f) * m_scale;
float blank_width = 1.0f * m_scale;
@ -908,8 +900,7 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) {
ImVec2 icon_size = ImVec2(14.0f, 14.0f) * m_scale;
const ImU32 tick_clr = IM_COL32(144, 144, 144, 255);
const ImU32 tick_hover_box_clr = IM_COL32(219, 253, 231, 255);
const ImU32 delete_btn_clr = IM_COL32(144, 144, 144, 255);
const ImU32 tick_hover_box_clr = m_is_dark ? IM_COL32(65, 65, 71, 255) : IM_COL32(219, 253, 231, 255);
auto get_tick_pos = [this, slideable_region](int tick)
{
@ -1010,10 +1001,9 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
ImVec2 text_content_size;
ImVec2 text_size;
const ImU32 white_bg = IM_COL32(255, 255, 255, 255);
const ImU32 white_bg = m_is_dark ? IM_COL32(65, 65, 71, 255) : IM_COL32(255, 255, 255, 255);
const ImU32 handle_clr = IM_COL32(0, 174, 66, 255);
const ImU32 handle_border_clr = IM_COL32(248, 248, 248, 255);
const ImU32 delete_btn_clr = IM_COL32(144, 144, 144, 255);
const ImU32 handle_border_clr = m_is_dark ? IM_COL32(65, 65, 71, 255) : IM_COL32(248, 248, 248, 255);
// calc slider groove size
ImVec2 groove_start = ImVec2(pos.x + size.x - groove_x - right_dummy, pos.y + text_dummy_height);
@ -1055,7 +1045,7 @@ bool IMSlider::vertical_slider(const char* str_id, int* higher_value, int* lower
if (!one_layer_flag)
{
// select higher handle by default
static bool h_selected = true;
bool h_selected = (selection == ssHigher);
if (ImGui::ItemHoverable(higher_handle, id) && context.IO.MouseClicked[0]) {
selection = ssHigher;
h_selected = true;
@ -1223,6 +1213,8 @@ bool IMSlider::render(int canvas_width, int canvas_height)
render_input_custom_gcode();
render_go_to_layer_dialog();
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);
@ -1236,9 +1228,9 @@ bool IMSlider::render(int canvas_width, int canvas_height)
}
imgui.end();
} else {
float pos_x = canvas_width - (VERTICAL_SLIDER_SIZE.x + TEXT_WIDTH_DUMMY * scale - TEXT_WIDTH_DUMMY) * m_scale;
float pos_x = canvas_width - (VERTICAL_SLIDER_SIZE.x + TEXT_WIDTH_DUMMY * scale - TEXT_WIDTH_DUMMY + ONE_LAYER_MARGIN) * m_scale;
float pos_y = std::max(ONE_LAYER_OFFSET.y, 0.15f * canvas_height - (VERTICAL_SLIDER_SIZE.y - SLIDER_LENGTH) * scale);
ImVec2 size = ImVec2((VERTICAL_SLIDER_SIZE.x + TEXT_WIDTH_DUMMY * scale - TEXT_WIDTH_DUMMY) * m_scale, canvas_height - 2 * pos_y);
ImVec2 size = ImVec2((VERTICAL_SLIDER_SIZE.x + TEXT_WIDTH_DUMMY * scale - TEXT_WIDTH_DUMMY + ONE_LAYER_MARGIN) * m_scale, canvas_height - 2 * pos_y);
imgui.set_next_window_pos(pos_x, pos_y, ImGuiCond_Always);
imgui.begin(std::string("laysers_slider"), windows_flag);
@ -1261,8 +1253,12 @@ bool IMSlider::render(int canvas_width, int canvas_height)
ImGui::Spacing();
ImGui::SameLine((VERTICAL_SLIDER_SIZE.x - ONE_LAYER_OFFSET.x) * scale * m_scale);
ImTextureID normal_id = is_one_layer() ? m_one_layer_on_id : m_one_layer_off_id;
ImTextureID hover_id = is_one_layer() ? m_one_layer_on_hover_id : m_one_layer_off_hover_id;
ImTextureID normal_id = m_is_dark ?
is_one_layer() ? m_one_layer_on_dark_id : m_one_layer_off_dark_id :
is_one_layer() ? m_one_layer_on_id : m_one_layer_off_id;
ImTextureID hover_id = m_is_dark ?
is_one_layer() ? m_one_layer_on_hover_dark_id : m_one_layer_off_hover_dark_id :
is_one_layer() ? m_one_layer_on_hover_id : m_one_layer_off_hover_id;
if (ImGui::ImageButton3(normal_id, hover_id, ImVec2(28 * m_scale, 28 * m_scale))) {
switch_one_layer_mode();
}
@ -1282,11 +1278,12 @@ void IMSlider::render_input_custom_gcode()
return;
ImGuiWrapper& imgui = *wxGetApp().imgui();
static bool move_to_center = true;
static bool set_focus = 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);
move_to_center = false;
}
imgui.push_common_window_style(m_scale);
@ -1301,6 +1298,12 @@ void IMSlider::render_input_custom_gcode()
| ImGuiWindowFlags_NoScrollWithMouse;
imgui.begin(_u8L("Custom G-code"), windows_flag);
imgui.text(_u8L("Enter Custom G-code used on current layer:"));
if (ImGui::IsMouseClicked(0)) {
set_focus = false;
}
if (set_focus && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0)) {
ImGui::SetKeyboardFocusHere(0);
}
int text_height = 6;
ImGui::InputTextMultiline("##text", m_custom_gcode, sizeof(m_custom_gcode), ImVec2(-1, ImGui::GetTextLineHeight() * text_height));
//text_height = 5;
@ -1311,29 +1314,104 @@ void IMSlider::render_input_custom_gcode()
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"))) {
imgui.push_confirm_button_style();
if (imgui.bbl_button(_L("OK")) || ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Enter))) {
m_show_custom_gcode_window = false;
add_custom_gcode(m_custom_gcode);
move_to_center = true;
set_focus = true;
}
ImGui::PopStyleColor(5);
imgui.pop_confirm_button_style();
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"))) {
imgui.push_cancel_button_style();
if (imgui.bbl_button(_L("Cancel")) || ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) {
m_show_custom_gcode_window = false;
move_to_center = true;
set_focus = true;
}
ImGui::PopStyleColor(5);
imgui.pop_cancel_button_style();
imgui.end();
ImGui::PopStyleVar(3);
imgui.pop_common_window_style();
}
void IMSlider::do_go_to_layer(size_t layer_number) {
clamp((int)layer_number, m_min_value, m_max_value);
GetSelection() == ssLower ? SetLowerValue(layer_number) : SetHigherValue(layer_number);
}
void IMSlider::render_go_to_layer_dialog(){
if (!m_show_go_to_layer_dialog)
return;
ImGuiWrapper& imgui = *wxGetApp().imgui();
static bool move_to_center = true;
static bool set_focus = true;
if (move_to_center) {
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);
move_to_center = false;
}
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("Jump to layer"), windows_flag);
imgui.text(_u8L("Please enter the layer number") + " (" + std::to_string(m_min_value + 1) + " - " + std::to_string(m_max_value + 1) + "):");
if (ImGui::IsMouseClicked(0)) {
set_focus = false;
}
if (set_focus && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0)) {
ImGui::SetKeyboardFocusHere(0);
}
ImGui::InputText("##input_layer_number", m_layer_number, sizeof(m_layer_number));
ImGui::NewLine();
ImGui::SameLine(GImGui->Style.WindowPadding.x * 8);
imgui.push_confirm_button_style();
bool disable_button = false;
if (strlen(m_layer_number) == 0)
disable_button = true;
else {
for (size_t i = 0; i< strlen(m_layer_number); i++)
if (!isdigit(m_layer_number[i]))
disable_button = true;
if (!disable_button && (m_min_value > atoi(m_layer_number) - 1 || atoi(m_layer_number) - 1 > m_max_value))
disable_button = true;
}
if (disable_button) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
imgui.push_button_disable_style();
}
if (imgui.bbl_button(_L("OK")) || (!disable_button && ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Enter)))) {
do_go_to_layer(atoi(m_layer_number) - 1);
m_show_go_to_layer_dialog = false;
move_to_center = true;
set_focus = true;
}
if (disable_button) {
ImGui::PopItemFlag();
imgui.pop_button_disable_style();
}
imgui.pop_confirm_button_style();
ImGui::SameLine();
imgui.push_cancel_button_style();
if (imgui.bbl_button(_L("Cancel")) || ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) {
m_show_go_to_layer_dialog = false;
move_to_center = true;
set_focus = true;
}
imgui.pop_cancel_button_style();
imgui.end();
ImGui::PopStyleVar(3);
@ -1354,8 +1432,11 @@ void IMSlider::render_menu()
if (ImGui::BeginPopup("slider_menu_popup")) {
if ((m_selection == ssLower && GetLowerValueD() == m_zero_layer_height) || (m_selection == ssHigher && GetHigherValueD() == m_zero_layer_height))
{
menu_item_with_icon(_u8L("Add Pause").c_str(), "", ImVec2(0, 0), 0, false, false);
}else
if (menu_item_with_icon(_u8L("Jump to Layer").c_str(), "")) {
m_show_go_to_layer_dialog = true;
}
}
else
{
if (menu_item_with_icon(_u8L("Add Pause").c_str(), "")) {
add_code_as_tick(PausePrint);
@ -1368,6 +1449,9 @@ void IMSlider::render_menu()
add_code_as_tick(Template);
}
}
if (menu_item_with_icon(_u8L("Jump to Layer").c_str(), "")) {
m_show_go_to_layer_dialog = true;
}
}
//BBS render this menu item only when extruder_num > 1
@ -1391,11 +1475,67 @@ void IMSlider::render_menu()
ImGuiWrapper::pop_menu_style();
}
void IMSlider::on_change_color_mode(bool is_dark) {
m_is_dark = is_dark;
}
void IMSlider::set_scale(float scale)
{
if(m_scale != scale) m_scale = scale;
}
void IMSlider::on_mouse_wheel(wxMouseEvent& evt) {
auto moves_slider_window = ImGui::FindWindowByName("moves_slider");
auto layers_slider_window = ImGui::FindWindowByName("laysers_slider");
if (!moves_slider_window || !layers_slider_window) {
BOOST_LOG_TRIVIAL(info) << "Couldn't find slider window";
return;
}
float wheel = 0.0f;
wheel = evt.GetWheelRotation() > 0 ? 1.0f : -1.0f;
if (wheel == 0.0f)
return;
#ifdef __WXOSX__
if (wxGetKeyState(WXK_SHIFT)) {
wheel *= -5;
}
else if (wxGetKeyState(WXK_RAW_CONTROL)) {
wheel *= 5;
}
#else
if (wxGetKeyState(WXK_COMMAND) || wxGetKeyState(WXK_SHIFT))
wheel *= 5;
#endif
if (is_horizontal()) {
if( evt.GetPosition().x > moves_slider_window->Pos.x &&
evt.GetPosition().x < moves_slider_window->Pos.x + moves_slider_window->Size.x &&
evt.GetPosition().y > moves_slider_window->Pos.y &&
evt.GetPosition().y < moves_slider_window->Pos.y + moves_slider_window->Size.y){
const int new_pos = GetHigherValue() + wheel;
SetHigherValue(new_pos);
set_as_dirty();
}
}
else {
if (evt.GetPosition().x > layers_slider_window->Pos.x &&
evt.GetPosition().x < layers_slider_window->Pos.x + layers_slider_window->Size.x &&
evt.GetPosition().y > layers_slider_window->Pos.y &&
evt.GetPosition().y < layers_slider_window->Pos.y + layers_slider_window->Size.y) {
if (is_one_layer()) {
const int new_pos = GetHigherValue() + wheel;
SetHigherValue(new_pos);
}
else {
const int new_pos = m_selection == ssLower ? GetLowerValue() + wheel : GetHigherValue() + wheel;
m_selection == ssLower ? SetLowerValue(new_pos) : SetHigherValue(new_pos);
}
set_as_dirty();
}
}
}
void IMSlider::correct_lower_value()
{
if (m_lower_value < m_min_value)

View file

@ -261,18 +261,14 @@ 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 on_mouse_wheel(wxMouseEvent& evt);
void post_ticks_changed_event(Type type = Custom);
bool check_ticks_changed_event(Type type);
bool switch_one_layer_mode();
void show_go_to_layer(bool show) { m_show_go_to_layer_dialog = show; }
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; }
@ -286,10 +282,18 @@ public:
ExtrudersSequence m_extruders_sequence;
float m_scale = 1.0;
void set_scale(float scale = 1.0);
void on_change_color_mode(bool is_dark);
protected:
void add_custom_gcode(std::string custom_gcode);
void add_code_as_tick(Type type, int selected_extruder = -1);
void do_go_to_layer(size_t layer_number);
void correct_lower_value();
void correct_higher_value();
bool horizontal_slider(const char* str_id, int* v, int v_min, int v_max, const ImVec2& pos, const ImVec2& size, float scale = 1.0);
void render_go_to_layer_dialog();
void render_input_custom_gcode();
void render_menu();
void draw_background(const ImRect& groove);
void draw_colored_band(const ImRect& groove, const ImRect& slideable_region);
void draw_ticks(const ImRect& slideable_region);
@ -305,8 +309,6 @@ private:
int get_tick_from_value(double value, bool force_lower_bound = false);
float get_pos_from_value(int v_min, int v_max, int value, const ImRect& rect);
std::string get_color_for_tool_change_tick(std::set<TickCode>::const_iterator it) const;
// Get active extruders for tick.
// Means one current extruder for not existing tick OR
@ -315,6 +317,8 @@ private:
std::array<int, 2> get_active_extruders_for_tick(int tick) const;
// Use those values to disable selection of active extruders
bool m_is_dark = false;
bool is_osx{false};
int m_min_value;
int m_max_value;
@ -331,6 +335,7 @@ private:
bool m_is_focused = false;
bool m_show_menu = false;
bool m_show_custom_gcode_window = false;
bool m_show_go_to_layer_dialog = false;
bool m_force_mode_apply = true;
bool m_enable_action_icon = true;
bool m_enable_cog_icon = false;
@ -340,13 +345,18 @@ private:
int m_selected_tick_value = -1;
/* BBS slider images */
void *m_reset_normal_id;
void *m_reset_hover_id;
void *m_one_layer_on_id;
void *m_one_layer_on_hover_id;
void *m_one_layer_arrow_id;
void *m_one_layer_off_id;
void *m_one_layer_off_hover_id;
void* m_one_layer_on_light_id;
void* m_one_layer_on_hover_light_id;
void* m_one_layer_off_light_id;
void* m_one_layer_off_hover_light_id;
void* m_one_layer_on_dark_id;
void* m_one_layer_on_hover_dark_id;
void* m_one_layer_off_dark_id;
void* m_one_layer_off_hover_dark_id;
void *m_pause_icon_id;
void *m_delete_icon_id;
@ -373,6 +383,7 @@ private:
std::vector<double> m_alternate_values;
char m_custom_gcode[1024] = { 0 };
char m_layer_number[64] = { 0 };
};
}

View file

@ -27,6 +27,7 @@
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
#include "libslic3r/Shape/TextShape.hpp"
#include "3DScene.hpp"
#include "GUI.hpp"
#include "I18N.hpp"
@ -37,6 +38,7 @@
#include "nanosvg/nanosvg.h"
#include "nanosvg/nanosvgrast.h"
#include "OpenGLManager.hpp"
#include "GUI_App.hpp"
namespace Slic3r {
namespace GUI {
@ -65,6 +67,20 @@ static const std::map<const wchar_t, std::string> font_icons = {
{ImGui::FoldButtonIcon , "im_fold" },
{ImGui::UnfoldButtonIcon , "im_unfold" },
{ImGui::SphereButtonIcon , "toolbar_modifier_sphere" },
// dark mode icon
{ImGui::MinimalizeDarkButton , "notification_minimalize_dark" },
{ImGui::MinimalizeHoverDarkButton , "notification_minimalize_hover_dark" },
{ImGui::RightArrowDarkButton , "notification_right_dark" },
{ImGui::RightArrowHoverDarkButton , "notification_right_hover_dark" },
{ImGui::PreferencesDarkButton , "notification_preferences_dark" },
{ImGui::PreferencesHoverDarkButton , "notification_preferences_hover_dark"},
{ImGui::CircleButtonDarkIcon , "circle_paint_dark" },
{ImGui::TriangleButtonDarkIcon , "triangle_paint_dark" },
{ImGui::FillButtonDarkIcon , "fill_paint_dark" },
{ImGui::HeightRangeDarkIcon , "height_range_dark" },
{ImGui::GapFillDarkIcon , "gap_fill_dark" },
{ImGui::SphereButtonDarkIcon , "toolbar_modifier_sphere_dark" },
};
static const std::map<const wchar_t, std::string> font_icons_large = {
@ -86,6 +102,11 @@ static const std::map<const wchar_t, std::string> font_icons_large = {
{ImGui::DocumentationButton , "notification_documentation" },
{ImGui::DocumentationHoverButton, "notification_documentation_hover"},
//{ImGui::InfoMarker , "notification_info" },
// dark mode icon
{ImGui::CloseNotifDarkButton , "notification_close_dark" },
{ImGui::CloseNotifHoverDarkButton , "notification_close_hover_dark" },
{ImGui::DocumentationDarkButton , "notification_documentation_dark" },
{ImGui::DocumentationHoverDarkButton, "notification_documentation_hover_dark"},
};
static const std::map<const wchar_t, std::string> font_icons_extra_large = {
@ -108,9 +129,11 @@ const ImVec4 ImGuiWrapper::COL_BLUE_LIGHT = ImVec4(0.122f, 0.557f, 0.918f
const ImVec4 ImGuiWrapper::COL_GREEN_LIGHT = ImVec4(0.86f, 0.99f, 0.91f, 1.0f);
const ImVec4 ImGuiWrapper::COL_HOVER = { 0.933f, 0.933f, 0.933f, 1.0f };
const ImVec4 ImGuiWrapper::COL_ACTIVE = { 0.675f, 0.675f, 0.675f, 1.0f };
const ImVec4 ImGuiWrapper::COL_SEPARATOR = { 0.93f, 0.93f, 0.93f,1.0f };
const ImVec4 ImGuiWrapper::COL_SEPARATOR = { 0.93f, 0.93f, 0.93f, 1.0f };
const ImVec4 ImGuiWrapper::COL_SEPARATOR_DARK = { 0.24f, 0.24f, 0.27f, 1.0f };
const ImVec4 ImGuiWrapper::COL_TITLE_BG = { 0.745f, 0.745f, 0.745f, 1.0f };
const ImVec4 ImGuiWrapper::COL_WINDOW_BG = { 1.000f, 1.000f, 1.000f, 0.95f };
const ImVec4 ImGuiWrapper::COL_WINDOW_BG = { 1.000f, 1.000f, 1.000f, 1.0f };
const ImVec4 ImGuiWrapper::COL_WINDOW_BG_DARK = { 45 / 255.f, 45 / 255.f, 49 / 255.f, 1.f };
int ImGuiWrapper::TOOLBAR_WINDOW_FLAGS = ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_NoMove
@ -118,7 +141,6 @@ int ImGuiWrapper::TOOLBAR_WINDOW_FLAGS = ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoTitleBar;
static float accer = 1.f;
bool get_data_from_svg(const std::string &filename, unsigned int max_size_px, ThumbnailData &thumbnail_data)
{
@ -189,15 +211,7 @@ bool slider_behavior(ImGuiID id, const ImRect& region, const ImS32 v_min, const
// Process interacting with the slider
ImS32 v_new = *out_value;
bool value_changed = false;
// wheel behavior
ImRect mouse_wheel_responsive_region;
if (axis == ImGuiAxis_X)
mouse_wheel_responsive_region = ImRect(region.Min - ImVec2(handle_sz.x / 2, 0), region.Max + ImVec2(handle_sz.x / 2, 0));
if (axis == ImGuiAxis_Y)
mouse_wheel_responsive_region = ImRect(region.Min - ImVec2(0, handle_sz.y), region.Max + ImVec2(0, handle_sz.y));
if (ImGui::ItemHoverable(mouse_wheel_responsive_region, id)) {
v_new = ImClamp(*out_value + (ImS32)(context.IO.MouseWheel * accer), v_min, v_max);
}
// drag behavior
if (context.ActiveId == id)
{
@ -290,6 +304,7 @@ ImGuiWrapper::ImGuiWrapper()
ImGuiWrapper::~ImGuiWrapper()
{
//destroy_fonts_texture();
destroy_font();
ImGui::DestroyContext();
}
@ -353,18 +368,25 @@ void ImGuiWrapper::set_language(const std::string &language)
ImGui::GetIO().Fonts->GetGlyphRangesChineseFull() :
// Simplified Chinese
// Default + Half-Width + Japanese Hiragana/Katakana + set of 2500 CJK Unified Ideographs for common simplified Chinese
ImGui::GetIO().Fonts->GetGlyphRangesChineseFull();
ImGui::GetIO().Fonts->GetGlyphRangesChineseSimplifiedCommon();
m_font_cjk = true;
} else if (lang == "th") {
ranges = ImGui::GetIO().Fonts->GetGlyphRangesThai(); // Default + Thai characters
} else {
ranges = ImGui::GetIO().Fonts->GetGlyphRangesDefault(); // Basic Latin, Extended Latin
}
else if (lang == "en") {
ranges = ImGui::GetIO().Fonts->GetGlyphRangesEnglish(); // Basic Latin
}
else{
ranges = ImGui::GetIO().Fonts->GetGlyphRangesOthers();
}
if (ranges != m_glyph_ranges) {
m_glyph_ranges = ranges;
//destroy_fonts_texture();
destroy_font();
}
m_glyph_basic_ranges = ImGui::GetIO().Fonts->GetGlyphRangesBasic();
}
void ImGuiWrapper::set_display_size(float w, float h)
@ -388,6 +410,7 @@ void ImGuiWrapper::set_scaling(float font_size, float scale_style, float scale_b
ImGui::GetStyle().ScaleAllSizes(scale_style / m_style_scaling);
m_style_scaling = scale_style;
//destroy_fonts_texture();
destroy_font();
}
@ -422,19 +445,6 @@ bool ImGuiWrapper::update_key_data(wxKeyEvent &evt)
ImGuiIO& io = ImGui::GetIO();
if (evt.CmdDown()) {
accer = 5.f;
}
else if (evt.ShiftDown()) {
#ifdef __APPLE__
accer = -5.f;
#else
accer = 5.f;
#endif
}
else
accer = 1.f;
if (evt.GetEventType() == wxEVT_CHAR) {
// Char event
const auto key = evt.GetUnicodeKey();
@ -1537,6 +1547,31 @@ void ImGuiWrapper::bold_text(const std::string& str)
}
}
bool ImGuiWrapper::push_font_by_name(std::string font_name)
{
auto sys_font = im_fonts_map.find(font_name);
if (sys_font != im_fonts_map.end()) {
ImFont* font = sys_font->second;
if (font && font->ContainerAtlas && font->Glyphs.Size > 4)
ImGui::PushFont(font);
else {
ImGui::PushFont(default_font);
}
return true;
}
return false;
}
bool ImGuiWrapper::pop_font_by_name(std::string font_name)
{
auto sys_font = im_fonts_map.find(font_name);
if (sys_font != im_fonts_map.end()) {
ImGui::PopFont();
return true;
}
return false;
}
void ImGuiWrapper::title(const std::string& str)
{
if (bold_font){
@ -1635,50 +1670,95 @@ std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name
return data;
}
//BBS
static bool m_is_dark_mode = false;
void ImGuiWrapper::on_change_color_mode(bool is_dark)
{
m_is_dark_mode = is_dark;
}
void ImGuiWrapper::push_toolbar_style(const float scale)
{
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f) * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f) * scale);
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, ImGuiWrapper::COL_HOVER); // 7
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.00f)); // 8
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(238/255.0f, 238/255.0f, 238/255.0f, 1.00f)); // 9
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(238/255.0f, 238/255.0f, 238/255.0f, 0.00f)); // 10
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, COL_GREEN_LIGHT); // 11
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.00f, 1.00f, 1.00f, 1.00f));//12
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, ImVec4(0.42f, 0.42f, 0.42f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImVec4(0.93f, 0.93f, 0.93f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImVec4(0.93f, 0.93f, 0.93f, 1.00f));
if (m_is_dark_mode) {
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f) * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f) * scale);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 0.88f)); // 1
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGuiWrapper::COL_WINDOW_BG_DARK); // 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_DARK); // 5
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(62 / 255.0f, 62 / 255.0f, 69 / 255.0f, 1.00f)); // 6
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(73 / 255.0f, 73 / 255.0f, 78 / 255.0f, 1.00f)); // 7
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(73 / 255.0f, 73 / 255.0f, 78 / 255.0f, 1.00f)); // 8
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(84 / 255.0f, 84 / 255.0f, 90 / 255.0f, 1.00f)); // 9
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(62 / 255.0f, 62 / 255.0f, 69 / 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_TextSelectedBg, ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f)); // 12
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.00f, 1.00f, 1.00f, 1.00f)); // 13
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, ImVec4(0.42f, 0.42f, 0.42f, 1.00f)); // 14
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImVec4(0.93f, 0.93f, 0.93f, 1.00f)); // 15
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImVec4(0.93f, 0.93f, 0.93f, 1.00f)); // 16
}
else {
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f) * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f) * scale);
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, ImGuiWrapper::COL_HOVER); // 7
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.00f)); // 8
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(172 / 255.0f, 172 / 255.0f, 172 / 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_TextSelectedBg, COL_GREEN_LIGHT); // 12
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.00f, 1.00f, 1.00f, 1.00f));//13
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, ImVec4(0.42f, 0.42f, 0.42f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImVec4(0.93f, 0.93f, 0.93f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImVec4(0.93f, 0.93f, 0.93f, 1.00f));
}
}
void ImGuiWrapper::pop_toolbar_style()
{
// size in push toolbar style
ImGui::PopStyleColor(15);
ImGui::PopStyleColor(16);
ImGui::PopStyleVar(6);
}
void ImGuiWrapper::push_menu_style(const float scale)
{
ImGuiWrapper::push_toolbar_style(scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 10.0f) * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 0.0f);
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
if (m_is_dark_mode) {
ImGuiWrapper::push_toolbar_style(scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 10.0f) * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 0.0f);
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG_DARK);
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
}
else {
ImGuiWrapper::push_toolbar_style(scale);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 10.0f) * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 0.0f);
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG);
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
}
}
void ImGuiWrapper::pop_menu_style()
{
@ -1688,25 +1768,48 @@ void ImGuiWrapper::pop_menu_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
if (m_is_dark_mode) {
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(1.0f, 1.0f, 1.0f, 0.88f)); // 1
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGuiWrapper::COL_WINDOW_BG_DARK); // 2
ImGui::PushStyleColor(ImGuiCol_TitleBg, ImVec4(54 / 255.0f, 54 / 255.0f, 60 / 255.0f, 1.00f)); // 3
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImVec4(54 / 255.0f, 54 / 255.0f, 60 / 255.0f, 1.00f)); // 4
ImGui::PushStyleColor(ImGuiCol_Separator, ImGuiWrapper::COL_SEPARATOR_DARK); // 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(84 / 255.0f, 84 / 255.0f, 90 / 255.0f, 1.00f)); // 9
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(62 / 255.0f, 62 / 255.0f, 69 / 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, ImVec4(43 / 255.0f, 64 / 255.0f, 54 / 255.0f, 1.00f)); // 13
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); // 14
}
else {
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, ImVec4(1.00f, 1.00f, 1.00f, 1.00f)); // 2
ImGui::PushStyleColor(ImGuiCol_TitleBg, ImVec4(245 / 255.0f, 245 / 255.0f, 245 / 255.0f, 1.00f)); // 3
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImVec4(245 / 255.0f, 245 / 255.0f, 245 / 255.0f, 1.00f)); // 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() {
@ -1714,6 +1817,69 @@ void ImGuiWrapper::pop_common_window_style() {
ImGui::PopStyleVar(5);
}
void ImGuiWrapper::push_confirm_button_style() {
if (m_is_dark_mode) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f / 255.f, 174.f / 255.f, 66.f / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, 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, 0.88f));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 0.88f));
}
else {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f / 255.f, 174.f / 255.f, 66.f / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, 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));
}
}
void ImGuiWrapper::pop_confirm_button_style() {
ImGui::PopStyleColor(6);
}
void ImGuiWrapper::push_cancel_button_style() {
if (m_is_dark_mode) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.f, 1.f, 1.f, 0.64f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(73 / 255.f, 73 / 255.f, 78 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(129 / 255.f, 129 / 255.f, 131 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.f, 1.f, 1.f, 0.64f));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 0.64f));
}
else {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.f, 1.f, 1.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(38 / 255.f, 46 / 255.f, 48 / 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));
}
}
void ImGuiWrapper::pop_cancel_button_style() {
ImGui::PopStyleColor(6);
}
void ImGuiWrapper::push_button_disable_style() {
if (m_is_dark_mode) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(54 / 255.f, 54 / 255.f, 60 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(54 / 255.f, 54 / 255.f, 60 / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 0.4f));
}
else {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(206.f / 255.f, 206.f / 255.f, 206.f / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(206.f / 255.f, 206.f / 255.f, 206.f / 255.f, 1.f));
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 1.f, 1.f, 1.f));
}
}
void ImGuiWrapper::pop_button_disable_style() {
ImGui::PopStyleColor(3);
}
void ImGuiWrapper::init_font(bool compress)
{
destroy_font();
@ -1723,6 +1889,7 @@ void ImGuiWrapper::init_font(bool compress)
// Create ranges of characters from m_glyph_ranges, possibly adding some OS specific special characters.
ImVector<ImWchar> ranges;
ImVector<ImWchar> basic_ranges;
ImFontAtlas::GlyphRangesBuilder builder;
builder.AddRanges(m_glyph_ranges);
#ifdef __APPLE__
@ -1737,15 +1904,15 @@ void ImGuiWrapper::init_font(bool compress)
cfg.OversampleH = cfg.OversampleV = 1;
//FIXME replace with io.Fonts->AddFontFromMemoryTTF(buf_decompressed_data, (int)buf_decompressed_size, m_font_size, nullptr, ranges.Data);
//https://github.com/ocornut/imgui/issues/220
ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/" + "HarmonyOS_Sans_SC_Regular.ttf").c_str(), m_font_size, &cfg, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
if (font == nullptr) {
font = io.Fonts->AddFontDefault();
if (font == nullptr) {
default_font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/" + "HarmonyOS_Sans_SC_Regular.ttf").c_str(), m_font_size, &cfg, ImGui::GetIO().Fonts->GetGlyphRangesChineseFull());
if (default_font == nullptr) {
default_font = io.Fonts->AddFontDefault();
if (default_font == nullptr) {
throw Slic3r::RuntimeError("ImGui: Could not load deafult font");
}
}
bold_font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/" + "HarmonyOS_Sans_SC_Bold.ttf").c_str(), m_font_size, &cfg, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
bold_font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/" + "HarmonyOS_Sans_SC_Bold.ttf").c_str(), m_font_size, &cfg, ranges.Data);
if (bold_font == nullptr) {
bold_font = io.Fonts->AddFontDefault();
if (bold_font == nullptr) { throw Slic3r::RuntimeError("ImGui: Could not load deafult font"); }
@ -1767,16 +1934,17 @@ void ImGuiWrapper::init_font(bool compress)
int rect_id = io.Fonts->CustomRects.Size; // id of the rectangle added next
// add rectangles for the icons to the font atlas
for (auto& icon : font_icons)
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz, icon_sz, 3.0 * font_scale + icon_sz);
io.Fonts->AddCustomRectFontGlyph(default_font, icon.first, icon_sz, icon_sz, 3.0 * font_scale + icon_sz);
for (auto& icon : font_icons_large)
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 2, icon_sz * 2, 3.0 * font_scale + icon_sz * 2);
io.Fonts->AddCustomRectFontGlyph(default_font, icon.first, icon_sz * 2, icon_sz * 2, 3.0 * font_scale + icon_sz * 2);
for (auto& icon : font_icons_extra_large)
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 4, icon_sz * 4, 3.0 * font_scale + icon_sz * 4);
io.Fonts->AddCustomRectFontGlyph(default_font, icon.first, icon_sz * 4, icon_sz * 4, 3.0 * font_scale + icon_sz * 4);
// Build texture atlas
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
BOOST_LOG_TRIVIAL(trace) << "Build default font texture done. width: " << width << ", height: " << height;
// Fill rectangles from the SVG-icons
for (auto icon : font_icons) {
@ -1846,6 +2014,66 @@ void ImGuiWrapper::init_font(bool compress)
glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));
}
void ImGuiWrapper::load_fonts_texture()
{
//if (m_font_another_texture == 0) {
// ImGuiIO& io = ImGui::GetIO();
// io.Fonts->Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;
// ImFontConfig cfg = ImFontConfig();
// cfg.OversampleH = cfg.OversampleV = 1;
// std::map<std::string, std::string> sys_fonts_map = get_occt_fonts_maps(); // map<font name, font path>
// im_fonts_map.clear(); // map<font name, ImFont*>
// BOOST_LOG_TRIVIAL(info) << "init_im_font start";
// for (auto sys_font : sys_fonts_map) {
// boost::filesystem::path font_path(sys_font.second);
// if (!boost::filesystem::exists(font_path)) {
// BOOST_LOG_TRIVIAL(trace) << "load font = " << sys_font.first << ", path = " << font_path << " is not exists";
// continue;
// }
// ImFont* im_font = io.Fonts->AddFontFromFileTTF(sys_font.second.c_str(), m_font_size, &cfg, ImGui::GetIO().Fonts->GetGlyphRangesBasic());
// if (im_font == nullptr) {
// BOOST_LOG_TRIVIAL(trace) << "load font = " << sys_font.first << " failed, path = " << font_path << " is not exists";
// continue;
// }
// im_fonts_map.insert({ sys_font.first, im_font });
// }
// BOOST_LOG_TRIVIAL(info) << "init_im_font end";
// unsigned char* pixels;
// int width, height;
// io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
// BOOST_LOG_TRIVIAL(trace) << "Build system fonts texture done. width: " << width << ", height: " << height;
// if (m_fonts_names.size() == 0) {
// std::vector<std::string> to_delete_fonts;
// for (auto im_font : im_fonts_map) {
// if (im_font.second->Glyphs.Size < 4) { to_delete_fonts.push_back(im_font.first); }
// }
// for (auto to_delete_font : to_delete_fonts) {
// sys_fonts_map.erase(to_delete_font);
// im_fonts_map.erase(to_delete_font);
// }
// for (auto im_font : im_fonts_map) m_fonts_names.push_back(im_font.first);
// }
// GLint last_texture;
// glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
// glsafe(::glGenTextures(1, &(m_font_another_texture)));
// glsafe(::glBindTexture(GL_TEXTURE_2D, m_font_another_texture));
// glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
// glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
// glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
// glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
// // Store our identifier
// io.Fonts->TexID = (ImTextureID)(intptr_t)m_font_another_texture;
// // Restore state
// glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));
//}
}
void ImGuiWrapper::init_input()
{
ImGuiIO& io = ImGui::GetIO();
@ -2052,6 +2280,20 @@ void ImGuiWrapper::destroy_font()
}
}
void ImGuiWrapper::destroy_fonts_texture() {
//if (m_font_another_texture != 0) {
// if (m_new_frame_open) {
// render();
// }
// init_font(true);
// glsafe(::glDeleteTextures(1, &m_font_another_texture));
// m_font_another_texture = 0;
// if (!m_new_frame_open) {
// new_frame();
// }
//}
}
const char* ImGuiWrapper::clipboard_get(void* user_data)
{
ImGuiWrapper *self = reinterpret_cast<ImGuiWrapper*>(user_data);

View file

@ -45,10 +45,12 @@ bool menu_item_with_icon(const char *label, const char *shortcut, ImVec2 icon_si
class ImGuiWrapper
{
const ImWchar* m_glyph_ranges{ nullptr };
const ImWchar* m_glyph_basic_ranges { nullptr };
// Chinese, Japanese, Korean
bool m_font_cjk{ false };
float m_font_size{ 18.0 };
unsigned m_font_texture{ 0 };
unsigned m_font_another_texture{ 0 };
float m_style_scaling{ 1.0 };
unsigned m_mouse_buttons{ 0 };
bool m_disabled{ false };
@ -155,6 +157,13 @@ public:
void bold_text(const std::string &str);
void title(const std::string& str);
// set font
const std::vector<std::string> get_fonts_names() const { return m_fonts_names; }
bool push_font_by_name(std::string font_name);
bool pop_font_by_name(std::string font_name);
void load_fonts_texture();
void destroy_fonts_texture();
void disabled_begin(bool disabled);
void disabled_end();
@ -185,15 +194,24 @@ public:
static const ImVec4 COL_ACTIVE;
static const ImVec4 COL_TITLE_BG;
static const ImVec4 COL_WINDOW_BG;
static const ImVec4 COL_WINDOW_BG_DARK;
static const ImVec4 COL_SEPARATOR;
static const ImVec4 COL_SEPARATOR_DARK;
//BBS
static void on_change_color_mode(bool is_dark);
static void push_toolbar_style(const float scale);
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();
static void push_confirm_button_style();
static void pop_confirm_button_style();
static void push_cancel_button_style();
static void pop_cancel_button_style();
static void push_button_disable_style();
static void pop_button_disable_style();
//BBS
static int TOOLBAR_WINDOW_FLAGS;
@ -211,7 +229,10 @@ private:
static void clipboard_set(void* user_data, const char* text);
LastSliderStatus m_last_slider_status;
ImFont* default_font = nullptr;
ImFont* bold_font = nullptr;
std::map<std::string, ImFont*> im_fonts_map;
std::vector<std::string> m_fonts_names;
};
class IMTexture

Some files were not shown because too many files have changed in this diff Show more