From 53511371836b782f995b09f44979836560403767 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 6 Dec 2022 13:49:05 +0100 Subject: [PATCH] (Win Only) Detection of cursor size, to place tooltips on scene, performed on tooltip text setting instead of being repeated every frame --- src/slic3r/GUI/GLCanvas3D.cpp | 72 ++++++++++++++++++----------------- src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/Selection.cpp | 4 -- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9fa54b9a0..79370022b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -773,53 +773,55 @@ void GLCanvas3D::Labels::render(const std::vector& sorted_ } } +static float get_cursor_height() +{ + float ret = 16.0f; +#ifdef _WIN32 + // see: https://forums.codeguru.com/showthread.php?449040-get-the-system-current-cursor-size + // this code is not perfect because it returns a maximum height equal to 31 even if the cursor bitmap shown on screen is bigger + // but at least it gives the same result as wxWidgets in the settings tabs + ICONINFO ii; + if (::GetIconInfo((HICON)GetCursor(), &ii) != 0) { + BITMAP bitmap; + ::GetObject(ii.hbmMask, sizeof(BITMAP), &bitmap); + const int width = bitmap.bmWidth; + const int height = (ii.hbmColor == nullptr) ? bitmap.bmHeight / 2 : bitmap.bmHeight; + HDC dc = ::CreateCompatibleDC(nullptr); + if (dc != nullptr) { + if (::SelectObject(dc, ii.hbmMask) != nullptr) { + for (int i = 0; i < width; ++i) { + for (int j = 0; j < height; ++j) { + if (::GetPixel(dc, i, j) != RGB(255, 255, 255)) { + if (ret < float(j)) + ret = float(j); + } + } + } + ::DeleteDC(dc); + } + } + ::DeleteObject(ii.hbmColor); + ::DeleteObject(ii.hbmMask); + } +#endif // _WIN32 + return ret; +} + void GLCanvas3D::Tooltip::set_text(const std::string& text) { // If the mouse is inside an ImGUI dialog, then the tooltip is suppressed. m_text = m_in_imgui ? std::string() : text; + m_cursor_height = get_cursor_height(); } 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) { - auto calc_cursor_height = []() { - float ret = 16.0f; -#ifdef _WIN32 - // see: https://forums.codeguru.com/showthread.php?449040-get-the-system-current-cursor-size - // this code is not perfect because it returns a maximum height equal to 31 even if the cursor bitmap shown on screen is bigger - // but at least it gives the same result as wxWidgets in the settings tabs - ICONINFO ii; - if (::GetIconInfo((HICON)GetCursor(), &ii) != 0) { - BITMAP bitmap; - ::GetObject(ii.hbmMask, sizeof(BITMAP), &bitmap); - int width = bitmap.bmWidth; - int height = (ii.hbmColor == nullptr) ? bitmap.bmHeight / 2 : bitmap.bmHeight; - HDC dc = ::CreateCompatibleDC(nullptr); - if (dc != nullptr) { - if (::SelectObject(dc, ii.hbmMask) != nullptr) { - for (int i = 0; i < width; ++i) { - for (int j = 0; j < height; ++j) { - if (::GetPixel(dc, i, j) != RGB(255, 255, 255)) { - if (ret < float(j)) - ret = float(j); - } - } - } - ::DeleteDC(dc); - } - } - ::DeleteObject(ii.hbmColor); - ::DeleteObject(ii.hbmMask); - } -#endif // _WIN32 - return ret; - }; - + auto validate_position = [this](const Vec2d& position, const GLCanvas3D& canvas, const ImVec2& wnd_size) { 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()) + calc_cursor_height(), 0.0f, float(cnv_size.get_height()) - wnd_size.y); + const float y = std::clamp(float(position.y()) + m_cursor_height, 0.0f, float(cnv_size.get_height()) - wnd_size.y); return Vec2f(x, y); }; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 41880d2b2..7b5a1084c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -400,6 +400,7 @@ class GLCanvas3D std::chrono::steady_clock::time_point m_start_time; // Indicator that the mouse is inside an ImGUI dialog, therefore the tooltip should be suppressed. bool m_in_imgui = false; + float m_cursor_height{ 16.0f }; public: bool is_empty() const { return m_text.empty(); } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 2dde431f0..e242b6e6f 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -584,15 +584,11 @@ bool Selection::is_sla_compliant() const bool Selection::is_single_text() const { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_WORLD_COORDINATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!is_single_volume_or_modifier()) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #else if (!is_single_volume() && !is_single_modifier()) #endif // ENABLE_WORLD_COORDINATE -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return false; const GLVolume* gl_volume = (*m_volumes)[*m_list.begin()];