diff --git a/src/slic3r/GUI/DesignCanvas.cpp b/src/slic3r/GUI/DesignCanvas.cpp index 2d83ea026e..500dba8ad3 100644 --- a/src/slic3r/GUI/DesignCanvas.cpp +++ b/src/slic3r/GUI/DesignCanvas.cpp @@ -1027,6 +1027,11 @@ void DesignCanvas::set_readout(const std::string& text) m_hud->Raise(); } +// Clear of the view cube and the two round view buttons, which own the bottom-left corner. +// Shared by the placement and by the wrap width, which have to agree or the chip wraps to a +// width it is then not given. +static constexpr int kStatusHudLeftInsetDip = 190; + void DesignCanvas::set_status_text(const wxString& text, const wxColour& colour) { if (!m_status_hud || !m_status_hud_label || !m_canvas_widget) return; @@ -1035,11 +1040,29 @@ void DesignCanvas::set_status_text(const wxString& text, const wxColour& colour) m_status_hud_colour = colour; if (text.IsEmpty()) { m_status_hud->Hide(); return; } m_status_hud_label->SetForegroundColour(colour); - m_status_hud_label->SetLabel(text); - m_status_hud->Fit(); + apply_status_label(); place_status_hud(); } +// SetLabel + Wrap + Fit, in that order and always together. Moving the status out of the panel +// removed the clipping of snaporca-8cc but not the underlying problem: the chip is a top-level +// popup that Fit()s to its text, so a long sentence simply grew past the right edge of the canvas +// and hung over the window. Wrapping to the room actually available is what makes the earlier +// promise — "a sentence can be a sentence" — true at every window width, including the charter's +// 1366 reach. Wrap() rewrites the label it is given, so it must follow a fresh SetLabel every +// time; that is the whole reason this is one function instead of three call sites. +void DesignCanvas::apply_status_label() +{ + if (!m_status_hud || !m_status_hud_label || !m_canvas_widget) return; + m_status_hud_label->SetLabel(m_status_hud_last); + const int avail = m_canvas_widget->GetClientSize().GetWidth() + - m_canvas_widget->FromDIP(kStatusHudLeftInsetDip) + - m_canvas_widget->FromDIP(24); + if (avail > m_canvas_widget->FromDIP(120)) // a uselessly narrow canvas: leave it unwrapped + m_status_hud_label->Wrap(avail); + m_status_hud->Fit(); +} + void DesignCanvas::place_status_hud() { if (!m_status_hud || !m_canvas_widget || m_status_hud_last.IsEmpty()) return; @@ -1048,9 +1071,11 @@ void DesignCanvas::place_status_hud() // then stayed until the next status change moved it. Nothing to anchor to: stay down. if (!m_canvas_widget->IsShownOnScreen()) { m_status_hud->Hide(); return; } const wxSize cs = m_canvas_widget->GetClientSize(); + // Re-wrap first: this also runs on resize, and a chip wrapped for the old width either + // overhangs a narrowed canvas or wastes a widened one. + apply_status_label(); const wxSize hs = m_status_hud->GetSize(); - // Clear of the view cube and the two round view buttons, which own the bottom-left corner. - const int kLeftInset = m_canvas_widget->FromDIP(190); + const int kLeftInset = m_canvas_widget->FromDIP(kStatusHudLeftInsetDip); const wxPoint bl = m_canvas_widget->ClientToScreen( wxPoint(kLeftInset, cs.GetHeight() - hs.GetHeight() - 12)); // No Raise() and no focus juggling: a popup neither takes focus nor falls behind. This was diff --git a/src/slic3r/GUI/DesignCanvas.hpp b/src/slic3r/GUI/DesignCanvas.hpp index d0203f5863..657cddd924 100644 --- a/src/slic3r/GUI/DesignCanvas.hpp +++ b/src/slic3r/GUI/DesignCanvas.hpp @@ -330,6 +330,7 @@ private: wxString m_status_hud_last; wxColour m_status_hud_colour; void place_status_hud(); // re-anchors to the canvas corner (also on resize) + void apply_status_label(); // SetLabel + Wrap to the canvas width + Fit, always together std::function m_on_sketch_commit; std::function&, const std::vector&, diff --git a/src/slic3r/GUI/DesignPanel.cpp b/src/slic3r/GUI/DesignPanel.cpp index 1f60673c07..992c7f8dff 100644 --- a/src/slic3r/GUI/DesignPanel.cpp +++ b/src/slic3r/GUI/DesignPanel.cpp @@ -3918,6 +3918,15 @@ void DesignPanel::set_ui_mode(UiMode m) { m_ui_mode = m; if (m != UiMode::Sketch) m_sketch_on.clear(); // no stale "on the picked face" on the next hint + // The DoF readout describes a SKETCH's constraint state, so it means nothing back in Feature + // mode — where it nonetheless stayed on screen after every Confirm, Cancel and Escape + // (snaporca-752). Cleared here rather than at those three exits because this is the one place + // all of them pass through, and a fourth exit added later would otherwise reintroduce it. + // Constrain mode keeps it: that is where the number is the whole point. + if (m == UiMode::Feature && m_dof_status != nullptr) { + m_dof_status->SetLabel(wxString()); + m_dof_status->Show(false); + } wxSizer* s = m_toolbar->GetSizer(); s->Show(m_tb_feature, m == UiMode::Feature, true); s->Show(m_tb_sketch, m == UiMode::Sketch, true);