Keep the sketch value field on top of the dimension labels

Dimension labels drawn after the value field each lifted their own
window to the front, so a label could print over the number being typed.
This commit is contained in:
SoftFever committed 2026-10-02 01:11:04 +08:00
1 parent 410399fdb5
commit 6a90946294
3 files changed
+18 -3

No files matched your search

+4
View File
@@ -8988,6 +8988,10 @@ void DesignSketchTool::render(GLCanvas3D& canvas)
// not there — there is no window to fall back to any more.
if (inline_editor != nullptr)
inline_editor->render(*wxGetApp().imgui(), m_render_scale);
// ...and on top of the dimension labels, which are all drawn after it and each lift their
// own window to the front (draw_dim_label): without this a label prints across the number
// being typed. A guard, because the labels come from many of the exit paths below.
ScopeGuard field_on_top([this] { if (inline_editor != nullptr) inline_editor->bring_to_front(); });
if (render_overlays)
render_overlays();
(void)canvas;
+12 -3
View File
@@ -7,7 +7,7 @@
#include "libslic3r/Color.hpp"
#include <imgui/imgui.h>
#include <imgui/imgui_internal.h> // BringWindowToDisplayFront / GetCurrentWindow
#include <imgui/imgui_internal.h> // FindWindowByName / BringWindowToDisplayFront
#include <cstdio>
#include <cstdlib>
@@ -19,6 +19,8 @@ namespace GUI {
namespace {
const char* const kWindowName = "##sketchvalue";
// Numbers are typed and shown with a POINT, whatever the locale: this field feeds a CAD kernel,
// and a decimal comma reaching it as a thousands separator is a silent order-of-magnitude error.
// Parsing accepts either separator because a keyboard's numeric pad may only offer one.
@@ -181,10 +183,9 @@ bool SketchInlineEditor::render(ImGuiWrapper& imgui, float scale)
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f);
// NoInputs is what every other sketch overlay sets and is exactly what this one must not:
// it is the only overlay in the tab that the user types into.
imgui.begin(std::string("##sketchvalue"),
imgui.begin(std::string(kWindowName),
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration
| ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings);
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
if (!m_title.empty() || !m_err.empty()) {
if (m_err.empty()) {
@@ -243,4 +244,12 @@ bool SketchInlineEditor::render(ImGuiWrapper& imgui, float scale)
return true;
}
void SketchInlineEditor::bring_to_front()
{
// Not gated on m_open: a commit closes the field after it was drawn, and that frame still
// shows it. A window that did not Begin this frame is not rendered, so lifting it is inert.
if (ImGuiWindow* w = ImGui::FindWindowByName(kWindowName))
ImGui::BringWindowToDisplayFront(w);
}
}} // namespace Slic3r::GUI
@@ -57,6 +57,8 @@ public:
// Draw it, and let ImGui do the editing. Called from DesignSketchTool::render() inside the
// frame's ImGui pass; `scale` is the tool's m_render_scale. Returns true if it drew.
bool render(ImGuiWrapper& imgui, float scale);
// Lift the field above every other overlay. Call it after the frame's last overlay is drawn.
void bring_to_front();
// Ask for another frame. THE FIELD DOES NOT WORK WITHOUT THIS, and the reason is a deadlock
// that only a per-frame trace shows: