mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-19 15:03:05 +00:00
Design: clicking the same face twice takes the body, and the status line moves onto the viewport
A click could point at a face, an edge or a vertex, but never at the body those
belong to: offer_selection_kind() can only return BodySolid when all three are
clear, which a viewport click never produces. The rubber band was the only door,
and the status line said "face 5 selected" while the user believed they had taken
the body. A second click on the SAME sub-element now escalates to it (snaporca-gem).
Not the pick cycle that was removed in bc2b741ce9 -- that one was silent and three
deep, so no click had a predictable meaning. Here the status line names the next
click before you make it, and a further click just takes the face under the cursor
again, which needs no teaching. Double-click is untouched: wx sends Down/Up/DClick/Up
and only the first Up carries a pending press, so a fast double-click still zooms to
fit and picks once.
The status line itself moved to the base of the viewport. In the side panel it was
clipped at ~73 characters with no warning and no wrap -- set_status()'s Wrap() never
took effect (snaporca-8cc) -- which silently length-limited every hint in the tab; the
first version of this change lost a clause to it. m_status is kept, hidden, as the
owner of the text and its colour, and the line is drawn in a bottom-left twin of the
readout HUD where there is a whole window's width.
Three defects found driving it on the rig, none of which the build could see:
* the HUD as a wxFrame took the WM's keyboard focus every time it was raised, and
the canvas then received NO key events -- every sketch shortcut silently dead.
Caught with SNAPORCA_KEYTRACE: shift+S logged a line, the following R logged
nothing. It is a wxPopupWindow now, which cannot be focused. SetFocus() on the
canvas does not fix it: focus was on another toplevel.
* zero vertical padding fits the popup tighter than the font's line box and clips
the glyphs; 6 (what the readout uses) reads as a two-line box. 3 is right.
* "has a caller chosen a colour?" compared the label's foreground against its
PARENT's, which differ by default, so every line counted as chosen and the
neutral text came out the panel's dark grey -- invisible on a dark chip. Compare
against the colour the label was created with, captured before any caller writes.
Verified on both rigs against fresh binaries: sketch -> extrude -> click face ->
click again -> whole body tinted, offer opens with the body rows live and Create /
Add material correctly greyed. Keyboard drives the whole sequence.
Filed and NOT fixed here: snaporca-od0 -- a bare-plate click does not deselect the
solid, so "click away, click back" escalates. Pre-existing; clearing there would also
drop the face the Thicken/Shell/Draft cards hold, which needs its own pass.
Refs: snaporca-gem, snaporca-8cc, snaporca-od0
This commit is contained in:
@@ -132,6 +132,36 @@ DesignCanvas::DesignCanvas(wxWindow* parent)
|
||||
}
|
||||
m_sketch_tool.on_readout = [this](const std::string& s) { set_readout(s); };
|
||||
|
||||
// Bottom-LEFT twin, carrying the status line. Top-level for the same reason as the readout
|
||||
// (a child widget is hidden by the GL surface) but a wxPopupWindow rather than a wxFrame,
|
||||
// because a popup cannot take keyboard focus. The readout gets away with a frame only
|
||||
// because it appears mid-gesture and the next input is the mouse; this one is up
|
||||
// permanently and is re-raised on every status change. As a frame it took the WM's focus
|
||||
// each time and the canvas stopped receiving keys at all — every sketch shortcut silently
|
||||
// dead, which reads as a broken tool. Do not "simplify" it back to a wxFrame.
|
||||
// Its colour is set per message — the panel decides whether a line is neutral or an error.
|
||||
{
|
||||
wxWindow* top = wxGetTopLevelParent(m_canvas_widget);
|
||||
m_status_hud = new wxPopupWindow(top, wxBORDER_NONE);
|
||||
m_status_hud->SetBackgroundColour(wxColour(28, 30, 34));
|
||||
m_status_hud_label = new wxStaticText(m_status_hud, wxID_ANY, wxEmptyString);
|
||||
auto* ss = new wxBoxSizer(wxHORIZONTAL);
|
||||
// The line never wraps — there is a whole window's width down here — so the chip is
|
||||
// ONE LINE tall. Spacers rather than a wxALL border because the two axes want
|
||||
// different numbers: roomy at the sides so it reads as a label, and just enough top
|
||||
// and bottom to clear the descenders. Zero vertical clips the glyphs; 6 (what the
|
||||
// readout chip uses) makes it look like a two-line box.
|
||||
ss->AddSpacer(10);
|
||||
ss->Add(m_status_hud_label, 0, wxTOP | wxBOTTOM, 3);
|
||||
ss->AddSpacer(10);
|
||||
m_status_hud->SetSizerAndFit(ss);
|
||||
m_status_hud->Hide();
|
||||
}
|
||||
// A floating frame does not follow its parent, so the anchor has to be recomputed whenever
|
||||
// the canvas changes size. The readout HUD gets away without this because it is transient;
|
||||
// the status line is on screen almost permanently and would visibly detach.
|
||||
m_canvas_widget->Bind(wxEVT_SIZE, [this](wxSizeEvent& e) { place_status_hud(); e.Skip(); });
|
||||
|
||||
refresh_bed();
|
||||
|
||||
m_canvas->bind_event_handlers();
|
||||
@@ -924,6 +954,35 @@ void DesignCanvas::set_readout(const std::string& text)
|
||||
m_hud->Raise();
|
||||
}
|
||||
|
||||
void DesignCanvas::set_status_text(const wxString& text, const wxColour& colour)
|
||||
{
|
||||
if (!m_status_hud || !m_status_hud_label || !m_canvas_widget) return;
|
||||
if (text == m_status_hud_last && colour == m_status_hud_colour) return;
|
||||
m_status_hud_last = text;
|
||||
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();
|
||||
place_status_hud();
|
||||
}
|
||||
|
||||
void DesignCanvas::place_status_hud()
|
||||
{
|
||||
if (!m_status_hud || !m_canvas_widget || m_status_hud_last.IsEmpty()) return;
|
||||
const wxSize cs = m_canvas_widget->GetClientSize();
|
||||
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 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
|
||||
// caught with SNAPORCA_KEYTRACE — shift+S logged a line, the following R logged nothing, and
|
||||
// the only thing between them was the first status update showing this window.
|
||||
if (!m_status_hud->IsShown()) m_status_hud->Show(); // Show before Move (GTK ignores pre-map Move)
|
||||
m_status_hud->Move(bl);
|
||||
}
|
||||
|
||||
void DesignCanvas::set_body_highlight(bool on)
|
||||
{
|
||||
if (m_body_selected == on) return;
|
||||
|
||||
Reference in New Issue
Block a user