diff --git a/src/slic3r/GUI/CAD/DesignCanvas.cpp b/src/slic3r/GUI/CAD/DesignCanvas.cpp index 7ee18ad6f6..ef37cb055a 100644 --- a/src/slic3r/GUI/CAD/DesignCanvas.cpp +++ b/src/slic3r/GUI/CAD/DesignCanvas.cpp @@ -121,11 +121,13 @@ DesignCanvas::DesignCanvas(wxWindow* parent) // Bottom-right viewport HUD: a borderless, non-focusable float label showing the active // tool's current values. Top-level (a child widget is hidden by the GL surface, same as // the inline editor). Fed every frame by the tool's on_readout; empty text hides it. + // NON-FOCUSABLE IS THE LOAD-BEARING WORD, and a wxFrame is not: see the header. The chip + // outlives the gesture that drew it, and while it held the X input focus every sketch + // shortcut was swallowed until the user clicked the canvas. Same window class as the status + // chip below for the same reason. Do not "simplify" it back to a wxFrame. { wxWindow* top = wxGetTopLevelParent(m_canvas_widget); - m_hud = new wxFrame(top, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, - wxFRAME_NO_TASKBAR | wxBORDER_NONE | wxFRAME_FLOAT_ON_PARENT | - wxSTAY_ON_TOP | wxTRANSPARENT_WINDOW); + m_hud = new wxPopupWindow(top, wxBORDER_NONE); m_hud->SetBackgroundColour(wxColour(28, 30, 34)); m_hud_label = new wxStaticText(m_hud, wxID_ANY, wxEmptyString); m_hud_label->SetForegroundColour(wxColour(0x46, 0xE0, 0xC8)); // teal, reads on dark bed @@ -1158,6 +1160,13 @@ void DesignCanvas::set_readout(const std::string& text) m_hud_last = text; if (text.empty()) { m_hud->Hide(); return; } m_hud_label->SetLabel(wxString::FromUTF8(text)); + place_readout_hud(); +} + +void DesignCanvas::place_readout_hud() +{ + if (!m_hud || !m_hud_label || !m_canvas_widget) return; + if (m_hud_last.empty() || !m_canvas_widget->IsShownOnScreen()) { m_hud->Hide(); return; } m_hud->Fit(); // Anchor to the canvas's bottom-right corner with a small margin (screen coords). const wxSize cs = m_canvas_widget->GetClientSize(); @@ -1169,6 +1178,16 @@ void DesignCanvas::set_readout(const std::string& text) m_hud->Raise(); } +// A popup is override-redirect: the window manager does not own it, so an iconised or +// deactivated app would leave the chip sitting on the bare desktop. The status chip already +// had to answer this; now that the readout is a popup too, it answers it the same way. +void DesignCanvas::show_readout_hud(bool on) +{ + if (!m_hud) return; + if (on) place_readout_hud(); + else m_hud->Hide(); +} + // 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. @@ -1230,12 +1249,14 @@ void DesignCanvas::place_status_hud() void DesignCanvas::on_frame_iconize(wxIconizeEvent& e) { show_status_hud(!e.IsIconized()); + show_readout_hud(!e.IsIconized()); e.Skip(); } void DesignCanvas::on_frame_activate(wxActivateEvent& e) { show_status_hud(e.GetActive()); + show_readout_hud(e.GetActive()); e.Skip(); } diff --git a/src/slic3r/GUI/CAD/DesignCanvas.hpp b/src/slic3r/GUI/CAD/DesignCanvas.hpp index c6b7a3d2aa..1da8a17cf4 100644 --- a/src/slic3r/GUI/CAD/DesignCanvas.hpp +++ b/src/slic3r/GUI/CAD/DesignCanvas.hpp @@ -397,10 +397,19 @@ private: std::unique_ptr m_inline_editor; // floating in-canvas value editor // Bottom-right viewport HUD: a borderless float label over the GL canvas showing the // active tool's current values (fed by the tool's on_readout). Empty text hides it. - wxFrame* m_hud{nullptr}; + // A wxPopupWindow for the SAME reason as the status chip below, and it was a wxFrame until + // the reason was measured rather than assumed: "it appears mid-gesture and the next input is + // the mouse" is false. The chip keeps the last value on screen AFTER the gesture ends, and a + // frame holds the X input focus once it has it — so the next keystroke went to a 119x31 + // window that has no use for it. Measured on :10: focus on the chip, `r` produced no + // CHAR_HOOK line at all; one bare canvas click moved focus back and the same key armed the + // tool. That is every sketch shortcut dead after every dimensioned entity. + wxPopupWindow* m_hud{nullptr}; wxStaticText* m_hud_label{nullptr}; std::string m_hud_last; void set_readout(const std::string& text); + void place_readout_hud(); // anchor + show, using m_hud_last + void show_readout_hud(bool on); // iconise/deactivate: a popup would float on the desktop // Bottom-LEFT viewport HUD: the selection / tool status line, written by DesignPanel. // A wxPopupWindow, NOT the wxFrame the readout HUD uses: a frame accepts keyboard focus, diff --git a/src/slic3r/GUI/CAD/DesignPanel.cpp b/src/slic3r/GUI/CAD/DesignPanel.cpp index c35f773330..4165d752db 100644 --- a/src/slic3r/GUI/CAD/DesignPanel.cpp +++ b/src/slic3r/GUI/CAD/DesignPanel.cpp @@ -4483,11 +4483,15 @@ void DesignPanel::set_ui_mode(UiMode m) // rebuild, which is not an event that happens when you merely press Sketch. update_reference_planes(); - // Say where you are, in words, across the top of the viewport — and mute the printer bed - // while you are there. The plate grid and a sketch grid are the same visual language, and - // reading one as the other is how a sketch gets drawn against the wrong reference. The bed - // checkbox stays the stored preference and is restored on the way out; ticking it mid-sketch - // still shows the bed, because that is a deliberate act and this is only a default. + // Say where you are, in words, across the top of the viewport. + // + // THE BED IS NOT MUTED HERE, and it was: "a plate grid and a sketch grid are the same visual + // language" is true and still the wrong call, because there IS no sketch grid to replace it. + // Seen on the rig: pick XY, arm Line, and the viewport is an empty grey field — no bed, no + // grid, no origin, nothing to judge a length or a direction against. The plate grid was + // carrying the ground reference for the whole tab. The banner already says where you are; + // taking the floor away as well only made the sketch harder to draw. The Bed checkbox is the + // one thing that governs the bed, in every mode. if (m_sketch_banner != nullptr) { const bool sketching = (m == UiMode::Sketch); if (sketching && m_sketch_banner_txt != nullptr) @@ -4497,8 +4501,6 @@ void DesignPanel::set_ui_mode(UiMode m) m_feature_counter + 1)); m_sketch_banner->Show(sketching); m_sketch_banner->GetParent()->Layout(); - if (m_viewport != nullptr) - m_viewport->set_show_bed(!sketching && (m_show_bed == nullptr || m_show_bed->GetValue())); } } diff --git a/src/slic3r/GUI/CAD/DesignSketchTool.cpp b/src/slic3r/GUI/CAD/DesignSketchTool.cpp index 817ff7dc8c..653cfe3b75 100644 --- a/src/slic3r/GUI/CAD/DesignSketchTool.cpp +++ b/src/slic3r/GUI/CAD/DesignSketchTool.cpp @@ -4780,16 +4780,18 @@ void DesignSketchTool::clear_base_pick() m_dbp_hover = -1; } -// Reference planes are larger than the bed (Onshape default-plane feel). Half-extent = 0.6 * the -// bed's larger side, so the square fully overhangs the print area. Falls back to 150mm if the bed -// isn't queryable yet. +// Reference planes sit INSIDE the bed. They used to be 0.6 * the bed's larger side, i.e. a square +// 1.2x the plate, and three of them are drawn with depth testing off — so they painted over the +// plate grid from edge to edge and the bed simply was not readable any more. "The planes hide the +// bed", reported exactly that way. Small enough to leave the grid legible around them is also the +// Onshape look this was reaching for: a modest square at the origin, not a tablecloth. double DesignSketchTool::dbp_half_extent() const { - double half = 150.0; + double half = 75.0; if (auto* pl = wxGetApp().plater()) { const BoundingBoxf bb = pl->build_volume().bounding_volume2d(); const double w = bb.max.x() - bb.min.x(), d = bb.max.y() - bb.min.y(); - if (w > 1.0 && d > 1.0) half = 0.6 * std::max(w, d); + if (w > 1.0 && d > 1.0) half = 0.3 * std::max(w, d); } return half; }