Design status: clear the DoF line on leaving sketch mode, and wrap the HUD chip

Two independent leftovers, both in the same status area.

snaporca-752: the "N degrees of freedom" line described a sketch's constraint
state and stayed on screen after Confirm, Cancel and the Escape downgrade, in
Feature mode where it means nothing — visible in every Feature-mode screenshot of
the 2026-07-27 sweep. Cleared in set_ui_mode rather than at those three exits,
because that is the one place all of them pass through and a fourth exit added
later would otherwise reintroduce it. Constrain mode keeps the readout: that is
where the number is the whole point.

snaporca-8cc: moving the status out of the panel and into the viewport HUD
removed the clipping, but not the underlying problem. The chip is a top-level
popup that Fit()s to its text, so a long sentence grew past the right edge of the
canvas and hung over the window instead of being cut off inside it — the same
silent length limit wearing a different hat. The label now wraps to the room
actually available (canvas width minus the view-cube inset), which is what makes
the earlier promise that "a sentence can be a sentence" true at 1366 as well as
at 1920.

SetLabel + Wrap + Fit are now one function called from both the text change and
the placement. Wrap() rewrites the label it is handed, so it has to follow a
fresh SetLabel every time, and the placement path runs on resize — a chip wrapped
for the old width either overhangs a narrowed canvas or wastes a widened one.
The left inset is one constant now because the wrap width and the anchor have to
agree, or the chip wraps to a width it is not then given.

snaporca-752, snaporca-8cc. Reviewed and compiled (RC=0), not exercised.
This commit is contained in:
Tommaso Bianchi
2026-08-13 08:49:18 +02:00
parent 8737ff701e
commit 13922a52b6
3 changed files with 39 additions and 4 deletions
+29 -4
View File
@@ -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
+1
View File
@@ -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<void(const SketchProfile&, const SketchPlane&)> m_on_sketch_commit;
std::function<void(const std::vector<SketchEntity>&,
const std::vector<SketchEntityConstraintDef>&,
+9
View File
@@ -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);