From f7662682c85126a2164d564d9bb09f7d0beaecf6 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 5 Nov 2021 14:46:44 +0100 Subject: [PATCH] Tech ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT - Modified ImGuiWrapper::slider_float() to create a compound widget where an additional button can be used to set the keyboard focus into the slider to allow the user to type in the desired value --- src/libslic3r/Technologies.hpp | 19 +++++-- src/slic3r/GUI/GCodeViewer.cpp | 12 +++++ src/slic3r/GUI/GLCanvas3D.cpp | 51 +++++++++++++------ src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 4 ++ src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 23 +++++++++ .../GUI/Gizmos/GLGizmoMmuSegmentation.cpp | 15 ++++++ src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp | 9 ++++ src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 4 ++ src/slic3r/GUI/ImGuiWrapper.cpp | 50 +++++++++++++++--- src/slic3r/GUI/ImGuiWrapper.hpp | 31 ++++++++--- 11 files changed, 183 insertions(+), 37 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index b22448a88..4f5098d59 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -74,16 +74,25 @@ //==================== -// 2.4.0.alpha4 techs +// 2.4.0.beta1 techs //==================== -#define ENABLE_2_4_0_ALPHA4 1 +#define ENABLE_2_4_0_BETA1 1 // Enable rendering modifiers and similar objects always as transparent -#define ENABLE_MODIFIERS_ALWAYS_TRANSPARENT (1 && ENABLE_2_4_0_ALPHA4) - +#define ENABLE_MODIFIERS_ALWAYS_TRANSPARENT (1 && ENABLE_2_4_0_BETA1) // Enable the fix for the detection of the out of bed state for sinking objects // and detection of out of bed using the bed perimeter -#define ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS (1 && ENABLE_2_4_0_ALPHA4) +#define ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS (1 && ENABLE_2_4_0_BETA1) +//==================== +// 2.4.0.beta2 techs +//==================== +#define ENABLE_2_4_0_BETA2 1 + +// Enable modified ImGuiWrapper::slider_float() to create a compound widget where +// an additional button can be used to set the keyboard focus into the slider +// to allow the user to type in the desired value +#define ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT (1 && ENABLE_2_4_0_BETA2) + #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 00fa066c9..1d4551f2e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -286,8 +286,12 @@ void GCodeViewer::SequentialView::Marker::render() const if (width != last_window_width || length != last_text_length) { last_window_width = width; last_text_length = length; +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + imgui.set_requires_extra_frame(); +#else wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT } imgui.end(); @@ -3379,8 +3383,12 @@ void GCodeViewer::render_legend(float& legend_height) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); // to avoid the tooltip to change size when moving the mouse +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + imgui.set_requires_extra_frame(); +#else wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT } } @@ -4115,8 +4123,12 @@ void GCodeViewer::render_legend(float& legend_height) if (can_show_mode_button(mode)) { if (imgui.button(label)) { m_time_estimate_mode = mode; +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + imgui.set_requires_extra_frame(); +#else wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT } } }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 18618e930..1c8a362c0 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -722,8 +722,13 @@ void GLCanvas3D::Labels::render(const std::vector& sorted_ } // force re-render while the windows gets to its final size (it takes several frames) +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + if (ImGui::GetWindowContentRegionWidth() + 2.0f * ImGui::GetStyle().WindowPadding.x != ImGui::CalcWindowNextAutoFitSize(ImGui::GetCurrentWindow()).x) + imgui.set_requires_extra_frame(); +#else if (ImGui::GetWindowContentRegionWidth() + 2.0f * ImGui::GetStyle().WindowPadding.x != ImGui::CalcWindowNextAutoFitSize(ImGui::GetCurrentWindow()).x) m_canvas.request_extra_frame(); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT imgui.end(); ImGui::PopStyleColor(); @@ -734,47 +739,48 @@ void GLCanvas3D::Labels::render(const std::vector& sorted_ void GLCanvas3D::Tooltip::set_text(const std::string& text) { // If the mouse is inside an ImGUI dialog, then the tooltip is suppressed. - const std::string &new_text = m_in_imgui ? std::string() : text; - if (m_text != new_text) { - if (m_text.empty()) - m_start_time = std::chrono::steady_clock::now(); - - m_text = new_text; - } + m_text = m_in_imgui ? std::string() : text; } -void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas) const +void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas) { static ImVec2 size(0.0f, 0.0f); auto validate_position = [](const Vec2d& position, const GLCanvas3D& canvas, const ImVec2& wnd_size) { - Size cnv_size = canvas.get_canvas_size(); - float x = std::clamp((float)position(0), 0.0f, (float)cnv_size.get_width() - wnd_size.x); - float y = std::clamp((float)position(1) + 16, 0.0f, (float)cnv_size.get_height() - wnd_size.y); + const Size cnv_size = canvas.get_canvas_size(); + const float x = std::clamp((float)position.x(), 0.0f, (float)cnv_size.get_width() - wnd_size.x); + const float y = std::clamp((float)position.y() + 16.0f, 0.0f, (float)cnv_size.get_height() - wnd_size.y); return Vec2f(x, y); }; - if (m_text.empty()) + if (m_text.empty()) { + m_start_time = std::chrono::steady_clock::now(); return; + } // draw the tooltip as hidden until the delay is expired // use a value of alpha slightly different from 0.0f because newer imgui does not calculate properly the window size if alpha == 0.0f - float alpha = (std::chrono::duration_cast(std::chrono::steady_clock::now() - m_start_time).count() < 500) ? 0.01f : 1.0f; + const float alpha = (std::chrono::duration_cast(std::chrono::steady_clock::now() - m_start_time).count() < 500) ? 0.01f : 1.0f; - Vec2f position = validate_position(mouse_position, canvas, size); + const Vec2f position = validate_position(mouse_position, canvas, size); ImGuiWrapper& imgui = *wxGetApp().imgui(); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha); - imgui.set_next_window_pos(position(0), position(1), ImGuiCond_Always, 0.0f, 0.0f); + imgui.set_next_window_pos(position.x(), position.y(), ImGuiCond_Always, 0.0f, 0.0f); imgui.begin(wxString("canvas_tooltip"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing); ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); ImGui::TextUnformatted(m_text.c_str()); // force re-render while the windows gets to its final size (it may take several frames) or while hidden +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + if (alpha < 1.0f || ImGui::GetWindowContentRegionWidth() + 2.0f * ImGui::GetStyle().WindowPadding.x != ImGui::CalcWindowNextAutoFitSize(ImGui::GetCurrentWindow()).x) + imgui.set_requires_extra_frame(); +#else if (alpha < 1.0f || ImGui::GetWindowContentRegionWidth() + 2.0f * ImGui::GetStyle().WindowPadding.x != ImGui::CalcWindowNextAutoFitSize(ImGui::GetCurrentWindow()).x) canvas.request_extra_frame(); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT size = ImGui::GetWindowSize(); @@ -2250,14 +2256,29 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) m_dirty |= wxGetApp().plater()->get_notification_manager()->update_notifications(*this); auto gizmo = wxGetApp().plater()->canvas3D()->get_gizmos_manager().get_current(); if (gizmo != nullptr) m_dirty |= gizmo->update_items_state(); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + // ImGuiWrapper::m_requires_extra_frame may have been set by a render made outside of the OnIdle mechanism + bool imgui_requires_extra_frame = wxGetApp().imgui()->requires_extra_frame(); + m_dirty |= imgui_requires_extra_frame; +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT if (!m_dirty) return; +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + // this needs to be done here. + // during the render launched by the refresh the value may be set again + wxGetApp().imgui()->reset_requires_extra_frame(); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + _refresh_if_shown_on_screen(); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + if (m_extra_frame_requested || mouse3d_controller_applied || imgui_requires_extra_frame || wxGetApp().imgui()->requires_extra_frame()) { +#else if (m_extra_frame_requested || mouse3d_controller_applied) { m_dirty = true; +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT m_extra_frame_requested = false; evt.RequestMore(); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e521add98..71f713100 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -390,7 +390,7 @@ class GLCanvas3D public: bool is_empty() const { return m_text.empty(); } void set_text(const std::string& text); - void render(const Vec2d& mouse_position, GLCanvas3D& canvas) const; + void render(const Vec2d& mouse_position, GLCanvas3D& canvas); // Indicates that the mouse is inside an ImGUI dialog, therefore the tooltip should be suppressed. void set_in_imgui(bool b) { m_in_imgui = b; } bool is_in_imgui() const { return m_in_imgui; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index b14819671..d2c32d488 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -167,7 +167,11 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit) ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always); if (last_h != win_h || last_y != y) { // ask canvas for another frame to render the window in the correct position +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + m_imgui->set_requires_extra_frame(); +#else m_parent.request_extra_frame(); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT if (last_h != win_h) last_h = win_h; if (last_y != y) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 16856a9e3..fcdecfaab 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -170,7 +170,13 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l float slider_start_position = std::max(position_before_text_y, position_after_text_y - slider_height); ImGui::SetCursorPosY(slider_start_position); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + wxString tooltip = format_wxstr(_L("Preselects faces by overhang angle. It is possible to restrict paintable facets to only preselected faces when " + "the option \"%1%\" is enabled."), m_desc["on_overhangs_only"]); + if (m_imgui->slider_float("##angle_threshold_deg", &m_highlight_by_angle_threshold_deg, 0.f, 90.f, format_str.data(), 1.0f, true, tooltip)) { +#else if (m_imgui->slider_float("##angle_threshold_deg", &m_highlight_by_angle_threshold_deg, 0.f, 90.f, format_str.data())) { +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT m_parent.set_slope_normal_angle(90.f - m_highlight_by_angle_threshold_deg); if (! m_parent.is_using_slope()) { m_parent.use_slope(true); @@ -182,9 +188,11 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::SetCursorPosY(std::max(position_before_text_y + slider_height, position_after_text_y)); const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; +#if !ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT if (ImGui::IsItemHovered()) m_imgui->tooltip(format_wxstr(_L("Preselects faces by overhang angle. It is possible to restrict paintable facets to only preselected faces when " "the option \"%1%\" is enabled."), m_desc["on_overhangs_only"]), max_tooltip_width); +#endif // !ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT m_imgui->disabled_begin(m_highlight_by_angle_threshold_deg == 0.f); ImGui::NewLine(); @@ -267,9 +275,13 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l m_imgui->text(m_desc.at("cursor_size")); ImGui::SameLine(sliders_left_width); ImGui::PushItemWidth(window_width - sliders_left_width); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + m_imgui->slider_float("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true, _L("Alt + Mouse wheel")); +#else m_imgui->slider_float("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); if (ImGui::IsItemHovered()) m_imgui->tooltip(_L("Alt + Mouse wheel"), max_tooltip_width); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT m_imgui->checkbox(m_desc["split_triangles"], m_triangle_splitting_enabled); @@ -284,14 +296,20 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::SameLine(sliders_left_width); ImGui::PushItemWidth(window_width - sliders_left_width); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + if (m_imgui->slider_float("##smart_fill_angle", &m_smart_fill_angle, SmartFillAngleMin, SmartFillAngleMax, format_str.data(), 1.0f, true, _L("Alt + Mouse wheel"))) +#else if (m_imgui->slider_float("##smart_fill_angle", &m_smart_fill_angle, SmartFillAngleMin, SmartFillAngleMax, format_str.data())) +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT for (auto &triangle_selector : m_triangle_selectors) { triangle_selector->seed_fill_unselect_all_triangles(); triangle_selector->request_update_render_data(); } +#if !ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT if (ImGui::IsItemHovered()) m_imgui->tooltip(_L("Alt + Mouse wheel"), max_tooltip_width); +#endif // !ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT } ImGui::Separator(); @@ -310,11 +328,16 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::SameLine(sliders_left_width); ImGui::PushItemWidth(window_width - sliders_left_width); auto clp_dist = float(m_c->object_clipper()->get_position()); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel"))) + m_c->object_clipper()->set_position(clp_dist, true); +#else if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f")) m_c->object_clipper()->set_position(clp_dist, true); if (ImGui::IsItemHovered()) m_imgui->tooltip(_L("Ctrl + Mouse wheel"), max_tooltip_width); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT ImGui::Separator(); if (m_imgui->button(m_desc.at("remove_all"))) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 4e86b562b..ee7a61082 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -441,9 +441,13 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott m_imgui->text(m_desc.at("cursor_size")); ImGui::SameLine(sliders_width); ImGui::PushItemWidth(window_width - sliders_width); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + m_imgui->slider_float("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true, _L("Alt + Mouse wheel")); +#else m_imgui->slider_float("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); if (ImGui::IsItemHovered()) m_imgui->tooltip(_L("Alt + Mouse wheel"), max_tooltip_width); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT m_imgui->checkbox(m_desc["split_triangles"], m_triangle_splitting_enabled); @@ -460,14 +464,20 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott "placed after the number with no whitespace in between."); ImGui::SameLine(sliders_width); ImGui::PushItemWidth(window_width - sliders_width); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + if (m_imgui->slider_float("##smart_fill_angle", &m_smart_fill_angle, SmartFillAngleMin, SmartFillAngleMax, format_str.data(), 1.0f, true, _L("Alt + Mouse wheel"))) +#else if(m_imgui->slider_float("##smart_fill_angle", &m_smart_fill_angle, SmartFillAngleMin, SmartFillAngleMax, format_str.data())) +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT for (auto &triangle_selector : m_triangle_selectors) { triangle_selector->seed_fill_unselect_all_triangles(); triangle_selector->request_update_render_data(); } +#if !ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT if (ImGui::IsItemHovered()) m_imgui->tooltip(_L("Alt + Mouse wheel"), max_tooltip_width); +#endif // !ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT ImGui::Separator(); } @@ -484,11 +494,16 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott ImGui::SameLine(sliders_width); ImGui::PushItemWidth(window_width - sliders_width); auto clp_dist = float(m_c->object_clipper()->get_position()); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel"))) + m_c->object_clipper()->set_position(clp_dist, true); +#else if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f")) m_c->object_clipper()->set_position(clp_dist, true); if (ImGui::IsItemHovered()) m_imgui->tooltip(_L("Ctrl + Mouse wheel"), max_tooltip_width); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT ImGui::Separator(); if (m_imgui->button(m_desc.at("remove_all"))) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index 6971e7cdb..b4378319c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -128,9 +128,13 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) m_imgui->text(m_desc.at("cursor_size")); ImGui::SameLine(sliders_width); ImGui::PushItemWidth(window_width - sliders_width); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + m_imgui->slider_float("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true, _L("Alt + Mouse wheel")); +#else m_imgui->slider_float("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); if (ImGui::IsItemHovered()) m_imgui->tooltip(_L("Alt + Mouse wheel"), max_tooltip_width); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("cursor_type")); @@ -168,11 +172,16 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) ImGui::SameLine(sliders_width); ImGui::PushItemWidth(window_width - sliders_width); auto clp_dist = float(m_c->object_clipper()->get_position()); +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true, _L("Ctrl + Mouse wheel"))) + m_c->object_clipper()->set_position(clp_dist, true); +#else if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f")) m_c->object_clipper()->set_position(clp_dist, true); if (ImGui::IsItemHovered()) m_imgui->tooltip(_L("Ctrl + Mouse wheel"), max_tooltip_width); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT ImGui::Separator(); if (m_imgui->button(m_desc.at("remove_all"))) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index f2faa29d0..9170db603 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -644,7 +644,11 @@ RENDER_AGAIN: if ((last_h != win_h) || (last_y != y)) { // ask canvas for another frame to render the window in the correct position +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + m_imgui->set_requires_extra_frame(); +#else m_parent.request_extra_frame(); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT if (last_h != win_h) last_h = win_h; if (last_y != y) diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index a65991a1e..d18b7bf91 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -85,14 +85,6 @@ const ImVec4 ImGuiWrapper::COL_BUTTON_HOVERED = COL_ORANGE_LIGHT; const ImVec4 ImGuiWrapper::COL_BUTTON_ACTIVE = ImGuiWrapper::COL_BUTTON_HOVERED; ImGuiWrapper::ImGuiWrapper() - : m_glyph_ranges(nullptr) - , m_font_cjk(false) - , m_font_size(18.0) - , m_font_texture(0) - , m_style_scaling(1.0) - , m_mouse_buttons(0) - , m_disabled(false) - , m_new_frame_open(false) { ImGui::CreateContext(); @@ -484,6 +476,47 @@ void ImGuiWrapper::tooltip(const wxString &label, float wrap_width) ImGui::EndTooltip(); } +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT +bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float v_max, const char* format/* = "%.3f"*/, float power/* = 1.0f*/, bool clamp /*= true*/, const wxString& tooltip /*= ""*/, bool show_edit_btn /*= true*/) +{ + const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; + + bool ret = ImGui::SliderFloat(label, v, v_min, v_max, format, power); + if (!tooltip.empty() && ImGui::IsItemHovered()) + this->tooltip(into_u8(tooltip).c_str(), max_tooltip_width); + + if (clamp) + *v = std::clamp(*v, v_min, v_max); + + if (show_edit_btn) { + const ImGuiStyle& style = ImGui::GetStyle(); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, { 1, style.ItemSpacing.y }); + ImGui::SameLine(); + const std::string btn_name = "..." + std::string(label); + if (ImGui::Button(btn_name.c_str())) { + ImGui::SetKeyboardFocusHere(-1); + this->set_requires_extra_frame(); + } + if (ImGui::IsItemHovered()) + this->tooltip(into_u8(_L("Edit")).c_str(), max_tooltip_width); + + ImGui::PopStyleVar(); + } + + return ret; +} + +bool ImGuiWrapper::slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format/* = "%.3f"*/, float power/* = 1.0f*/, bool clamp /*= true*/, const wxString& tooltip /*= ""*/, bool show_edit_btn /*= true*/) +{ + return this->slider_float(label.c_str(), v, v_min, v_max, format, power, clamp, tooltip, show_edit_btn); +} + +bool ImGuiWrapper::slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format/* = "%.3f"*/, float power/* = 1.0f*/, bool clamp /*= true*/, const wxString& tooltip /*= ""*/, bool show_edit_btn /*= true*/) +{ + auto label_utf8 = into_u8(label); + return this->slider_float(label_utf8.c_str(), v, v_min, v_max, format, power, clamp, tooltip, show_edit_btn); +} +#else bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float v_max, const char* format/* = "%.3f"*/, float power/* = 1.0f*/, bool clamp /*= true*/) { bool ret = ImGui::SliderFloat(label, v, v_min, v_max, format, power); @@ -502,6 +535,7 @@ bool ImGuiWrapper::slider_float(const wxString& label, float* v, float v_min, fl auto label_utf8 = into_u8(label); return this->slider_float(label_utf8.c_str(), v, v_min, v_max, format, power, clamp); } +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT bool ImGuiWrapper::combo(const wxString& label, const std::vector& options, int& selection) { diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 27cd098ff..a56af2236 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -22,15 +22,18 @@ namespace GUI { class ImGuiWrapper { - const ImWchar *m_glyph_ranges; + const ImWchar* m_glyph_ranges{ nullptr }; // Chinese, Japanese, Korean - bool m_font_cjk; - float m_font_size; - unsigned m_font_texture; - float m_style_scaling; - unsigned m_mouse_buttons; - bool m_disabled; - bool m_new_frame_open; + bool m_font_cjk{ false }; + float m_font_size{ 18.0 }; + unsigned m_font_texture{ 0 }; + float m_style_scaling{ 1.0 }; + unsigned m_mouse_buttons{ 0 }; + bool m_disabled{ false }; + bool m_new_frame_open{ false }; +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + bool m_requires_extra_frame{ false }; +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT std::string m_clipboard_text; public: @@ -90,9 +93,15 @@ public: void tooltip(const wxString &label, float wrap_width); // Float sliders: Manually inserted values aren't clamped by ImGui.Using this wrapper function does (when clamp==true). +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + bool slider_float(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = "", bool show_edit_btn = true); + bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = "", bool show_edit_btn = true); + bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = "", bool show_edit_btn = true); +#else bool slider_float(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true); bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true); bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true); +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT bool combo(const wxString& label, const std::vector& options, int& selection); // Use -1 to not mark any option as selected bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected, int& mouse_wheel); @@ -108,6 +117,12 @@ public: bool want_text_input() const; bool want_any_input() const; +#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + bool requires_extra_frame() const { return m_requires_extra_frame; } + void set_requires_extra_frame() { m_requires_extra_frame = true; } + void reset_requires_extra_frame() { m_requires_extra_frame = false; } +#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + static const ImVec4 COL_GREY_DARK; static const ImVec4 COL_GREY_LIGHT; static const ImVec4 COL_ORANGE_DARK;