Bodies: colour that survives selection, hide that toggles twice, Delete that acts

Three defects behind one report ("bodies cannot be moved or hidden/shown or
deleted, colour does not work"). They are unrelated to each other; only the
symptom was shared.

1. The Color tool wrote a per-body override that was correct end to end —
   stored on CadBody, carried across recompute (CadDocument.cpp:3381), read
   back by DesignCanvas::body_color() — and then overpainted every frame.
   m_body_selected is a DOCUMENT-WIDE flag raised whenever a non-Sketch
   feature row is selected, which is the resting state after any modelling
   operation, and while it was true every body rendered gold. An explicit
   colour now outranks the selection tint; unpainted bodies still tint, which
   is all the tint was ever for.

2. The eye toggle re-selected the body row through m_tree, using item ids that
   belong to m_parts. The row came back unselected, so the second press found
   tree_body_selection() == -1 and fell through to the feature-level branch
   instead of un-hiding. Hide worked exactly once. The sibling call in
   refresh_parts() had it right.

3. The tree card's Delete button answered a selected body row with "select the
   FEATURE that created this body" — an instruction the user cannot act on,
   because the tree does not say which feature that is. on_delete_body()
   already resolves CadBody::source_feature and confirms by name; it was
   reachable only from the right-click offer. The button now routes to it.

Reviewed and compiled (libslic3r_gui, RC=0); not exercised — needs a session at
the machine to confirm all three in the viewport. snaporca-zjvg.
This commit is contained in:
Tommaso Bianchi
2026-08-12 19:57:14 +02:00
parent 606026a920
commit 3f62d4d58d
2 changed files with 26 additions and 6 deletions
+11 -3
View File
@@ -290,9 +290,17 @@ void DesignCanvas::reload(bool keep_view)
if (m_body_hidden) hidden = true;
v->is_active = !hidden; // per-body visibility toggle
if (!hidden) {
// Selection tint wins; otherwise the per-body override (Color tool) or the
// auto palette via body_color().
ColorRGBA c = m_body_selected ? sel_gold : body_color(b);
// An EXPLICIT colour outranks the selection tint. m_body_selected is a
// document-wide flag raised whenever a non-Sketch feature row is selected —
// the normal resting state after any modelling operation — so painting every
// body gold on it made the Color tool look broken: the override was written,
// carried across recompute and read back correctly, and then overpainted here
// every single frame. A body the user deliberately coloured keeps its colour;
// the rest still tint, which is all the tint was ever for.
const bool overridden = m_color_bodies != nullptr && b >= 0
&& b < int(m_color_bodies->size())
&& (*m_color_bodies)[b].has_color;
ColorRGBA c = (m_body_selected && !overridden) ? sel_gold : body_color(b);
if (b == m_hl_body_target) c = ColorRGBA(0.30f, 0.90f, 0.70f, 1.0f); // target = teal-green
else if (b == m_hl_body_tool) c = ColorRGBA(1.00f, 0.55f, 0.15f, 1.0f); // tool = orange
if (m_body_translucent) c.a(0.30f);
+15 -3
View File
@@ -2966,7 +2966,15 @@ DesignPanel::DesignPanel(wxWindow* parent)
auto* vis = edit_btn("design_eye", _L("Show / hide"));
vis->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { on_toggle_visibility(); });
auto* del = edit_btn("design_delete", _L("Delete"));
del->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { on_delete_feature(); });
del->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
// A body row deletes the feature that made it. on_delete_body() already resolves
// CadBody::source_feature and asks for confirmation by name; it was reachable only
// from the right-click offer, so this button answered a selected body row with
// "select the FEATURE that created this body" — an instruction the user cannot act
// on, since the tree does not say which feature that is. It does now.
if (tree_body_selection() >= 0) on_delete_body();
else on_delete_feature();
});
auto* up = edit_btn("design_moveup", _L("Move up"));
up->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { on_move_feature(-1); });
auto* down = edit_btn("design_movedown", _L("Move down"));
@@ -6302,8 +6310,12 @@ void DesignPanel::on_toggle_visibility()
&m_body_visible, &m_body_xform);
}
refresh_tree();
if (bsel < int(m_tree_body_items.size())) // keep the row selected for repeat toggles
m_tree->SelectItem(m_tree_body_items[bsel]);
// Keep the row selected for repeat toggles. m_parts, NOT m_tree: these ids belong
// to the Bodies list, and handing a foreign item to the feature tree left the row
// unselected — so the second press of the eye found tree_body_selection() == -1 and
// fell through to the FEATURE-level branch below instead of un-hiding the body.
if (m_parts != nullptr && bsel < int(m_tree_body_items.size()))
m_parts->SelectItem(m_tree_body_items[bsel]);
m_status->SetForegroundColour(wxNullColour);
set_status(wxString::Format(now_visible ? _L("Body %d shown")
: _L("Body %d hidden"), bsel + 1));