diff --git a/resources/shaders/customs.vs b/resources/shaders/customs.vs index 45fa543f45..3b78a59700 100644 --- a/resources/shaders/customs.vs +++ b/resources/shaders/customs.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 10.0; + gl_PointSize = 15.0; } diff --git a/resources/shaders/pauses.vs b/resources/shaders/pauses.vs index 45fa543f45..3b78a59700 100644 --- a/resources/shaders/pauses.vs +++ b/resources/shaders/pauses.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 10.0; + gl_PointSize = 15.0; } diff --git a/resources/shaders/retractions.vs b/resources/shaders/retractions.vs index 2cf5ca2dd0..3b78a59700 100644 --- a/resources/shaders/retractions.vs +++ b/resources/shaders/retractions.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 5.0; + gl_PointSize = 15.0; } diff --git a/resources/shaders/toolchanges.vs b/resources/shaders/toolchanges.vs index 2cf5ca2dd0..3b78a59700 100644 --- a/resources/shaders/toolchanges.vs +++ b/resources/shaders/toolchanges.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 5.0; + gl_PointSize = 15.0; } diff --git a/resources/shaders/unretractions.vs b/resources/shaders/unretractions.vs index 2cf5ca2dd0..3b78a59700 100644 --- a/resources/shaders/unretractions.vs +++ b/resources/shaders/unretractions.vs @@ -13,5 +13,5 @@ void main() // world_normal_z = gl_Normal.z; gl_Position = ftransform(); - gl_PointSize = 5.0; + gl_PointSize = 15.0; } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index e60676ca31..63cacdd457 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -341,6 +341,7 @@ BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box(const Transform3d & } +#if !ENABLE_GCODE_VIEWER void GLVolume::set_range(double min_z, double max_z) { this->qverts_range.first = 0; @@ -375,6 +376,7 @@ void GLVolume::set_range(double min_z, double max_z) } } } +#endif // !ENABLE_GCODE_VIEWER void GLVolume::render() const { diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 70d6fb016a..28295a35f7 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -442,7 +442,9 @@ public: bool empty() const { return this->indexed_vertex_array.empty(); } +#if !ENABLE_GCODE_VIEWER void set_range(double low, double high); +#endif // !ENABLE_GCODE_VIEWER void render() const; #if !ENABLE_SLOPE_RENDERING @@ -560,7 +562,9 @@ public: void clear() { for (auto *v : volumes) delete v; volumes.clear(); } bool empty() const { return volumes.empty(); } +#if !ENABLE_GCODE_VIEWER void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); } +#endif // !ENABLE_GCODE_VIEWER void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) { m_print_box_min[0] = min_x; m_print_box_min[1] = min_y; m_print_box_min[2] = min_z; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index e6ddba8d11..268b998fa4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -10,7 +10,6 @@ #if ENABLE_GCODE_VIEWER #include "GUI_Utils.hpp" #include "DoubleSlider.hpp" -#include "GLToolbar.hpp" #include "GLCanvas3D.hpp" #include "libslic3r/Model.hpp" #endif // ENABLE_GCODE_VIEWER @@ -33,8 +32,7 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); } -std::vector> decode_colors(const std::vector& colors) -{ +std::vector> decode_colors(const std::vector& colors) { static const float INV_255 = 1.0f / 255.0f; std::vector> output(colors.size(), {0.0f, 0.0f, 0.0f} ); @@ -94,7 +92,8 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); + double z = static_cast(move.position[2]); + paths.push_back({ move.type, move.extrusion_role, id, id, z, z, move.delta_extruder, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id, move.cp_color_id }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -174,13 +173,16 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { + auto start_time = std::chrono::high_resolution_clock::now(); + if (m_vertices.vertices_count == 0) return; + // update tool colors m_tool_colors = decode_colors(str_tool_colors); + // update ranges for coloring / legend m_extrusions.reset_ranges(); - for (size_t i = 0; i < m_vertices.vertices_count; ++i) { // skip first vertex @@ -201,14 +203,17 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std: } case GCodeProcessor::EMoveType::Travel: { - if (m_buffers[buffer_id(curr.type)].visible) { + if (m_buffers[buffer_id(curr.type)].visible) m_extrusions.ranges.feedrate.update_from(curr.feedrate); - } + break; } default: { break; } } } + + auto end_time = std::chrono::high_resolution_clock::now(); + std::cout << "refresh: " << std::chrono::duration_cast(end_time - start_time).count() << "ms \n"; } void GCodeViewer::reset() @@ -226,6 +231,7 @@ void GCodeViewer::reset() m_extrusions.reset_ranges(); m_shells.volumes.clear(); m_layers_zs = std::vector(); + m_layers_z_range = { 0.0, 0.0 }; m_roles = std::vector(); } @@ -391,7 +397,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) // layers zs / roles / extruder ids / cp color ids -> extract from result for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) { if (move.type == GCodeProcessor::EMoveType::Extrude) - m_layers_zs.emplace_back(move.position[2]); + m_layers_zs.emplace_back(static_cast(move.position[2])); m_roles.emplace_back(move.extrusion_role); m_extruder_ids.emplace_back(move.extruder_id); @@ -411,6 +417,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (k < n) m_layers_zs.erase(m_layers_zs.begin() + k, m_layers_zs.end()); + // set layers z range + m_layers_z_range = { m_layers_zs.front(), m_layers_zs.back() }; + // roles -> remove duplicates std::sort(m_roles.begin(), m_roles.end()); m_roles.erase(std::unique(m_roles.begin(), m_roles.end()), m_roles.end()); @@ -508,10 +517,6 @@ void GCodeViewer::render_toolpaths() const BOOST_LOG_TRIVIAL(error) << "Unable to find uniform_color uniform"; }; - auto is_path_visible = [](unsigned int flags, const Path& path) { - return Extrusions::is_role_visible(flags, path.role); - }; - glsafe(::glCullFace(GL_BACK)); glsafe(::glLineWidth(3.0f)); @@ -546,60 +551,90 @@ void GCodeViewer::render_toolpaths() const { std::array color = { 1.0f, 1.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!is_in_z_range(path)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Color_change: { std::array color = { 1.0f, 0.0f, 0.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!is_in_z_range(path)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Pause_Print: { std::array color = { 0.0f, 1.0f, 0.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!is_in_z_range(path)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Custom_GCode: { std::array color = { 0.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!is_in_z_range(path)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Retract: { std::array color = { 1.0f, 0.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!is_in_z_range(path)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Unretract: { std::array color = { 0.0f, 1.0f, 1.0f }; set_color(current_program_id, color); - glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); - glsafe(::glDrawElements(GL_POINTS, (GLsizei)buffer.data_size, GL_UNSIGNED_INT, nullptr)); - glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + for (const Path& path : buffer.paths) { + if (!is_in_z_range(path)) + continue; + + glsafe(::glEnable(GL_PROGRAM_POINT_SIZE)); + glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); + glsafe(::glDisable(GL_PROGRAM_POINT_SIZE)); + } break; } case GCodeProcessor::EMoveType::Extrude: { for (const Path& path : buffer.paths) { - if (!is_path_visible(m_extrusions.role_visibility_flags, path)) + if (!is_visible(path) || !is_in_z_range(path)) continue; set_color(current_program_id, extrusion_color(path)); @@ -610,6 +645,9 @@ void GCodeViewer::render_toolpaths() const case GCodeProcessor::EMoveType::Travel: { for (const Path& path : buffer.paths) { + if (!is_in_z_range(path)) + continue; + set_color(current_program_id, (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path)); glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint)))); } @@ -643,9 +681,7 @@ void GCodeViewer::render_shells() const void GCodeViewer::render_overlay() const { static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - static const float ICON_BORDER_SIZE = 25.0f; static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); - static const float GAP_ICON_TEXT = 7.5f; if (!m_legend_enabled || m_roles.empty()) return; @@ -656,17 +692,22 @@ void GCodeViewer::render_overlay() const ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + if (ImGui::IsWindowAppearing()) + // force an extra farme + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label) { - // draw icon - ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); - draw_list->AddRect({ pos.x, pos.y }, { pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE }, ICON_BORDER_COLOR, 0.0f, 0); - draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, - { pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f }, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + float icon_size = ImGui::GetTextLineHeight(); + ImVec2 pos = ImGui::GetCursorPos(); + draw_list->AddRect({ pos.x, pos.y }, { pos.x + icon_size, pos.y + icon_size }, ICON_BORDER_COLOR, 0.0f, 0); + draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + // draw text - ImGui::SetCursorPos({ pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT, pos.y + 0.5f * (ICON_BORDER_SIZE - ImGui::GetTextLineHeight()) }); + ImGui::Dummy({ icon_size, icon_size }); + ImGui::SameLine(); imgui.text(label); }; @@ -689,6 +730,7 @@ void GCodeViewer::render_overlay() const } }; + // extrusion paths -> title ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); switch (m_view_type) { @@ -703,15 +745,21 @@ void GCodeViewer::render_overlay() const default: { break; } } ImGui::PopStyleColor(); - ImGui::Separator(); + // extrusion paths -> items switch (m_view_type) { case EViewType::FeatureType: { for (ExtrusionRole role : m_roles) { + bool visible = is_visible(role); + if (!visible) + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); + add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role))); + if (!visible) + ImGui::PopStyleVar(); } break; } @@ -810,6 +858,37 @@ void GCodeViewer::render_overlay() const default: { break; } } + // travel paths + if (m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)].visible) + { + switch (m_view_type) + { + case EViewType::Feedrate: + case EViewType::Tool: + case EViewType::ColorPrint: + { + break; + } + default: + { + // title + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + imgui.text(I18N::translate_utf8(L("Travel"))); + ImGui::PopStyleColor(); + ImGui::Separator(); + + // items + add_item(Travel_Colors[0], I18N::translate_utf8(L("Movement"))); + add_item(Travel_Colors[1], I18N::translate_utf8(L("Extrusion"))); + add_item(Travel_Colors[2], I18N::translate_utf8(L("Retraction"))); + + break; + } + } + } + imgui.end(); ImGui::PopStyleVar(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index bfd61e8d4c..d2eb103f65 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -40,6 +40,8 @@ class GCodeViewer ExtrusionRole role{ erNone }; unsigned int first{ 0 }; unsigned int last{ 0 }; + double first_z{ 0.0f }; + double last_z{ 0.0f }; float delta_extruder{ 0.0f }; float height{ 0.0f }; float width{ 0.0f }; @@ -129,10 +131,6 @@ class GCodeViewer } void reset_ranges() { ranges.reset(); } - - static bool is_role_visible(unsigned int flags, ExtrusionRole role) { - return role < erCount && (flags & (1 << role)) != 0; - } }; public: @@ -156,6 +154,7 @@ private: BoundingBoxf3 m_bounding_box; std::vector> m_tool_colors; std::vector m_layers_zs; + std::array m_layers_z_range; std::vector m_roles; std::vector m_extruder_ids; Extrusions m_extrusions; @@ -195,6 +194,7 @@ public: void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } void set_options_visibility_from_flags(unsigned int flags); + void set_layers_z_range(const std::array& layers_z_range) { m_layers_z_range = layers_z_range; } bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } @@ -206,6 +206,17 @@ private: void render_toolpaths() const; void render_shells() const; void render_overlay() const; + bool is_visible(ExtrusionRole role) const { + return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0; + } + bool is_visible(const Path& path) const { return is_visible(path.role); } + bool is_in_z_range(const Path& path) const { + auto in_z_range = [this](double z) { + return z > m_layers_z_range[0] - EPSILON && z < m_layers_z_range[1] + EPSILON; + }; + + return in_z_range(path.first_z) || in_z_range(path.last_z); + } }; } // namespace GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ab2dee6938..fa38aca470 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2346,17 +2346,22 @@ void GLCanvas3D::set_toolpath_view_type(GCodeViewer::EViewType type) { m_gcode_viewer.set_view_type(type); } + +void GLCanvas3D::set_toolpaths_z_range(const std::array& range) +{ + m_gcode_viewer.set_layers_z_range(range); +} #else std::vector GLCanvas3D::get_current_print_zs(bool active_only) const { return m_volumes.get_current_print_zs(active_only); } -#endif // ENABLE_GCODE_VIEWER void GLCanvas3D::set_toolpaths_range(double low, double high) { m_volumes.set_range(low, high); } +#endif // ENABLE_GCODE_VIEWER std::vector GLCanvas3D::load_object(const ModelObject& model_object, int obj_idx, std::vector instance_idxs) { @@ -2853,6 +2858,8 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) void GLCanvas3D::refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { m_gcode_viewer.refresh(gcode_result, str_tool_colors); + set_as_dirty(); + request_extra_frame(); } #endif // ENABLE_GCODE_VIEWER @@ -3202,6 +3209,17 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #else case 'k': { m_camera.select_next_type(); m_dirty = true; break; } #endif // ENABLE_NON_STATIC_CANVAS_MANAGER +#if ENABLE_GCODE_VIEWER + case 'L': + case 'l': { + if (!m_main_toolbar.is_enabled()) + { + m_gcode_viewer.enable_legend(!m_gcode_viewer.is_legend_enabled()); + m_dirty = true; + } + break; + } +#endif // ENABLE_GCODE_VIEWER case 'O': case 'o': { _update_camera_zoom(-1.0); break; } #if ENABLE_RENDER_PICKING_PASS diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 7a295b900d..152658b13a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -650,8 +650,10 @@ public: void set_gcode_options_visibility_from_flags(unsigned int flags); void set_toolpath_role_visibility_flags(unsigned int flags); void set_toolpath_view_type(GCodeViewer::EViewType type); + void set_toolpaths_z_range(const std::array& range); #else std::vector get_current_print_zs(bool active_only) const; + void set_toolpaths_range(double low, double high); #endif // ENABLE_GCODE_VIEWER void set_toolpaths_range(double low, double high); diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index dd9ddcab8f..a66396b277 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -271,9 +271,12 @@ void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, cons // On the other side, with this line the combo box popup cannot be closed by clicking on the combo button on Windows 10. comboCtrl->UseAltPopupWindow(); + int max_width = 0; + comboCtrl->EnablePopupAnimation(false); comboCtrl->SetPopupControl(popup); wxString title = from_u8(text); + max_width = std::max(max_width, 60 + comboCtrl->GetTextExtent(title).x); popup->SetStringValue(title); popup->Bind(wxEVT_CHECKLISTBOX, [popup](wxCommandEvent& evt) { popup->OnCheckListBox(evt); }); popup->Bind(wxEVT_LISTBOX, [popup](wxCommandEvent& evt) { popup->OnListBoxSelection(evt); }); @@ -289,9 +292,12 @@ void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, cons for (size_t i = 0; i < items_str.size(); i += 2) { wxString label = from_u8(items_str[i]); + max_width = std::max(max_width, 60 + popup->GetTextExtent(label).x); popup->Append(label); popup->Check(i / 2, items_str[i + 1] == "1"); } + + comboCtrl->SetMinClientSize(wxSize(max_width, -1)); } } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 876d212fb4..3e0d5cd5a4 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -332,7 +332,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view #if ENABLE_GCODE_VIEWER m_combochecklist_options = new wxComboCtrl(); - m_combochecklist_options->Create(this, wxID_ANY, _(L("Options")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); + m_combochecklist_options->Create(this, wxID_ANY, _(L("Others")), wxDefaultPosition, wxSize(15 * wxGetApp().em_unit(), -1), wxCB_READONLY); std::string options_items = GUI::into_u8( _(L("Travel")) + "|0|" + _(L("Retractions")) + "|0|" + @@ -344,7 +344,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view _(L("Shells")) + "|0|" + _(L("Legend")) + "|1" ); - Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_(L("Options"))), options_items); + Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_(L("Others"))), options_items); #else m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _(L("Travel"))); m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _(L("Retractions"))); @@ -1113,9 +1113,14 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) PrinterTechnology tech = m_process->current_printer_technology(); if (tech == ptFFF) { +#if ENABLE_GCODE_VIEWER + m_canvas->set_toolpaths_z_range({ m_slider->GetLowerValueD(), m_slider->GetHigherValueD() }); + m_canvas->set_as_dirty(); +#else m_canvas->set_toolpaths_range(m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6); m_canvas->render(); m_canvas->set_use_clipping_planes(false); +#endif // ENABLE_GCODE_VIEWER } else if (tech == ptSLA) { diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index b3f2791961..3e55f6ae30 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -197,8 +197,8 @@ wxString wxCheckListBoxComboPopup::GetStringValue() const wxSize wxCheckListBoxComboPopup::GetAdjustedSize(int minWidth, int prefHeight, int maxHeight) { - // matches owner wxComboCtrl's width - // and sets height dinamically in dependence of contained items count + // set width dinamically in dependence of items text + // and set height dinamically in dependence of items count wxComboCtrl* cmb = GetComboCtrl(); if (cmb != nullptr) @@ -207,7 +207,15 @@ wxSize wxCheckListBoxComboPopup::GetAdjustedSize(int minWidth, int prefHeight, i unsigned int count = GetCount(); if (count > 0) - size.SetHeight(count * DefaultItemHeight); + { + int max_width = size.x; + for (unsigned int i = 0; i < count; ++i) + { + max_width = std::max(max_width, 60 + GetTextExtent(GetString(i)).x); + } + size.SetWidth(max_width); + size.SetHeight(count * GetTextExtent(GetString(0)).y); + } else size.SetHeight(DefaultHeight);