diff --git a/src/slic3r/GUI/DesignCanvas.cpp b/src/slic3r/GUI/DesignCanvas.cpp index 1a36467363..b7d72bab14 100644 --- a/src/slic3r/GUI/DesignCanvas.cpp +++ b/src/slic3r/GUI/DesignCanvas.cpp @@ -970,6 +970,10 @@ void DesignCanvas::set_status_text(const wxString& text, const wxColour& colour) void DesignCanvas::place_status_hud() { if (!m_status_hud || !m_canvas_widget || m_status_hud_last.IsEmpty()) return; + // The canvas has a client size even while its page is hidden, and it is not the size the + // page will have when shown — anchoring against it put the chip up on the tab bar, where it + // 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(); const wxSize hs = m_status_hud->GetSize(); // Clear of the view cube and the two round view buttons, which own the bottom-left corner. @@ -983,6 +987,13 @@ void DesignCanvas::place_status_hud() m_status_hud->Move(bl); } +void DesignCanvas::show_status_hud(bool on) +{ + if (!m_status_hud) return; + if (on) place_status_hud(); // re-anchors first: the page may have been resized while away + else m_status_hud->Hide(); +} + void DesignCanvas::set_body_highlight(bool on) { if (m_body_selected == on) return; diff --git a/src/slic3r/GUI/DesignCanvas.hpp b/src/slic3r/GUI/DesignCanvas.hpp index 4462de096b..c94f7f584b 100644 --- a/src/slic3r/GUI/DesignCanvas.hpp +++ b/src/slic3r/GUI/DesignCanvas.hpp @@ -186,6 +186,10 @@ public: // the panel clips it at ~73 characters with no warning (snaporca-8cc), the viewport's // bottom margin has the whole window width to spare. Empty text hides it. void set_status_text(const wxString& text, const wxColour& colour); + // Take the status line down / bring it back when the Design page leaves and re-enters view. + // A popup is a TOP-LEVEL window: hiding the page it belongs to does not hide it. Keeps the + // text, so coming back needs no re-selection. + void show_status_hud(bool on); void set_operand_bodies(int target_body, int tool_body); // -1,-1 clears void set_body_translucent(bool on); // render the solid see-through (fillet/chamfer preview) void set_body_hidden(bool on); // preview-only: hide base bodies, show only the result ghost diff --git a/src/slic3r/GUI/DesignPanel.cpp b/src/slic3r/GUI/DesignPanel.cpp index b64c1e2b38..a9f04d56a4 100644 --- a/src/slic3r/GUI/DesignPanel.cpp +++ b/src/slic3r/GUI/DesignPanel.cpp @@ -5694,8 +5694,20 @@ wxString DesignPanel::idle_hint() const : _L("No solid yet — select a sketch and right-click it to Extrude."); } +// The Design tab is no longer the visible page (snaporca-dlj). The status line is a popup floating +// over the GL canvas, so it does NOT go away when this page does — it stayed up over Prepare and +// over the home screen, still reading like a live Design selection ("selected (whole body) — +// right-click for what applies to it") on a tab that has no such selection and no such menu. +// Nothing else in the panel needs to know: the popup keeps its text and comes straight back. +void DesignPanel::on_tab_hidden() +{ + if (m_viewport) m_viewport->show_status_hud(false); +} + void DesignPanel::on_tab_shown() { + if (m_viewport) m_viewport->show_status_hud(true); // ...and back on the way in + if (m_active == Tool::None && m_doc.display_mesh.its.indices.empty()) set_status(idle_hint()); // first paint: the tab has never been edited diff --git a/src/slic3r/GUI/DesignPanel.hpp b/src/slic3r/GUI/DesignPanel.hpp index 37535b42c6..a1c265ffd5 100644 --- a/src/slic3r/GUI/DesignPanel.hpp +++ b/src/slic3r/GUI/DesignPanel.hpp @@ -50,6 +50,7 @@ class DesignPanel : public wxPanel public: explicit DesignPanel(wxWindow* parent); void on_tab_shown(); // re-sync bed to the active printer when the Design tab is activated + void on_tab_hidden(); // another tab took over: take the viewport status line down with us // Rebuild off the UI thread (progress dialog only if it turns out to be slow), so a feature // op on a heavy imported solid does not freeze the window. Returns m_doc.recompute()'s result. bool recompute_guarded(const wxString& message); diff --git a/src/slic3r/GUI/DesignSketchTool.cpp b/src/slic3r/GUI/DesignSketchTool.cpp index 637a36e26e..30a73ef6e9 100644 --- a/src/slic3r/GUI/DesignSketchTool.cpp +++ b/src/slic3r/GUI/DesignSketchTool.cpp @@ -8068,6 +8068,27 @@ bool DesignSketchTool::on_mouse_impl(wxMouseEvent& evt, GLCanvas3D& canvas) return true; } m_display_pick = -1; m_display_pick_region = -1; // clicked bare plate -> drop highlight + // ...and the SOLID selection goes with it (snaporca-od0). A click that hits nothing has to + // mean what a rubber band that sweeps nothing already means — pick_bodies_in_rectangle + // clears on an empty sweep, and the two gestures cannot disagree about the same outcome. + // Until now the face survived a click on bare plate, so "click away, then click the face + // again" arrived here as the SECOND click on the same face and escalated to the whole + // body, when the click away was the user letting go of it. + // + // The cost is real and is the intended trade: Thicken / Shell / Draft hold their input + // face in the panel's m_sel_solid_face, so a stray click on empty canvas with one of + // those cards open gives that face back. Their handlers already write the "(pick a solid + // face)" placeholder and rebuild the ghost at level 0, so the card SAYS it lost the pick + // rather than confirming against a face the viewport has stopped highlighting. + // + // Guarded on there being something to clear: this runs on every click that misses, and + // the callback re-renders the open card's preview. + if (m_solid_sel != SolidSel::None) { + clear_solid_selection(); + dp_pick_trace("clicked empty space -> selection cleared"); + if (on_solid_selection_changed) + on_solid_selection_changed(int(m_solid_sel), m_sel_body, m_sel_face, m_sel_edge); + } // Last resort: a click that hit no geometry but landed on a reference/base plane picks it. if (m_dbp_active) { const int h = hit_test_base_pick(canvas, evt); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index aa3c932569..572ef30e47 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1290,6 +1290,11 @@ void MainFrame::init_tabpanel() { else if (panel == m_monitor) { //monitor } +#ifdef SLIC3R_CAD + // Any page that is not Design takes the Design status line down with it — see + // DesignPanel::on_tab_hidden for why the popup does not follow the page on its own. + if (m_design_panel != nullptr && panel != m_design_panel) m_design_panel->on_tab_hidden(); +#endif #ifndef __APPLE__ if (sel == tp3DEditor) { m_topbar->EnableUndoRedoItems();