Design tab: stop eight tool cards rendering at startup; regroup the drawers

The sidebar opened with eight tool cards stacked in it — Transform, Mirror,
Thicken, Rib, Project, Delete Face, Helix and Mate. A card added to the cards
sizer is visible until something hides it, and close_tool()'s hide-all only
runs on a tool SWITCH, so anything missing from the construction-time hide
block is on screen from the moment the tab opens. Those eight were wired into
close_tool() but never added here. All 37 cards are now hidden at startup.

Worth stating because it invalidates a check I ran while diagnosing this: every
card IS hidden somewhere in the file, so grepping for "hidden anywhere" says
nothing. The block that matters is the one in the constructor.

Second, the drawers mixed unrelated operations, and two group tooltips no
longer described their contents — Dress-up listed eight tools spanning three
different kinds of operation, and Add material still claimed to hold only
extrude/revolve/sweep/loft after Thicken and Rib were added to it.

One concept per drawer now:

  Add material   extrude, revolve, sweep, loft, thicken, rib
                 -> grows new solid material, whether from a profile, a face or
                    a line
  Surface        unchanged; already coherent
  Datum / Curve  plane, axis, coord sys, helix, PROJECT
                 -> reference geometry and derived curves. Project consumes a
                    body but PRODUCES sketch entities, so it is curve creation,
                    not a finishing operation
  Placement      TRANSFORM, MIRROR, MATE                              (new)
                 -> moves a body without changing its shape; a mate places one
                    body relative to another
  Dress-up       fillet/chamfer, draft, shell, delete face
                 -> finishing on the faces and edges of an existing solid
  Hole / thread  unchanged

The new drawer costs no toolbar width: the layout order already contained an
empty put("place") slot between "material" and "plane" with nothing registered
to it. Shift+Y and Shift+Z follow Transform and Mirror; every tool still
appears exactly once.

Compiles clean; kernel untouched, so the suite is unaffected at 139 cases /
1960 assertions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tommaso Bianchi
2026-07-25 17:39:53 +02:00
co-authored by Claude Opus 5
parent 6372b3b505
commit d4904b8e2e
+86 -63
View File
@@ -493,8 +493,9 @@ DesignPanel::DesignPanel(wxWindow* parent)
b_sketch->Bind(wxEVT_BUTTON, [act_sketch](wxCommandEvent&) { act_sketch(); });
m_keys_feature[SHIFT('S')] = act_sketch;
fadd("sketch", b_sketch);
// Add material: Extrude / Revolve / Sweep / Loft
feat_dropdown("material", "design_extrude", _L("Add material (extrude / revolve / sweep / loft)"), {
// Add material: every feature that grows new solid material — from a profile
// (extrude/revolve/sweep/loft), from a face (thicken) or from a line (rib).
feat_dropdown("material", "design_extrude", _L("Add material (extrude / revolve / sweep / loft / thicken / rib)"), {
{"design_extrude", _L("Extrude"), _L("Extrude a sketch profile, or push/pull a picked face"),
[this] {
// Onshape push/pull: an explicitly picked solid face (Face-level cycle, no loop
@@ -699,7 +700,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
}, SHIFT('V')},
});
feat_dropdown("plane", "design_plane", _L("Datum / Curve (plane / axis / coord sys / helix)"), {
feat_dropdown("plane", "design_plane", _L("Datum / Curve (plane / axis / coord sys / helix / project)"), {
{"design_plane", _L("Plane"), _L("Reference plane (offset / tilt / midplane / tangent / two edges / coincident)"),
[this] {
populate_plane_choices(m_plane_base);
@@ -723,6 +724,73 @@ DesignPanel::DesignPanel(wxWindow* parent)
populate_plane_choices(m_helix_plane);
open_tool(Tool::Helix);
}, 0},
// Project belongs here, not in Dress-up: it consumes a body but PRODUCES sketch
// geometry, so it is reference/curve creation like the four above, not a finishing op.
{"design_sketch", _L("Project"), _L("Project body edges onto a plane as sketch entities"),
[this] {
if (m_doc.bodies.empty()) {
m_status->SetForegroundColour(wxColour(235, 110, 110));
m_status->SetLabel(_L("Project needs a body — add or import one first"));
m_status->Refresh();
return;
}
{
m_proj_source_body->Clear();
for (size_t i = 0; i < m_doc.bodies.size(); ++i) {
const std::string& n = m_doc.bodies[i].name;
m_proj_source_body->Append(n.empty() ? wxString::Format(_L("Body %zu"), i + 1) : wxString::FromUTF8(n));
}
if (m_proj_source_body->GetCount() > 0) m_proj_source_body->SetSelection(0);
}
populate_plane_choices(m_proj_plane);
m_sel_solid_face = -1;
m_proj_face_label->SetLabel(_L("(all edges)"));
open_tool(Tool::Project);
}, 0},
});
// Placement — operations that MOVE a body without changing its shape. Transform and
// Mirror place one body directly; a Mate places one body relative to another. They were
// in Dress-up (fillet/draft/shell) and Datum, which mixed shape-finishing and reference
// geometry with rigid-body placement. "place" was already an empty slot in the bar order.
feat_dropdown("place", "design_move", _L("Placement (transform / mirror / mate)"), {
{"design_move", _L("Transform"), _L("Move and/or rotate an existing body"),
[this] {
if (m_doc.bodies.empty()) {
m_status->SetForegroundColour(wxColour(235, 110, 110));
m_status->SetLabel(_L("Transform needs a body — add or import one first"));
m_status->Refresh();
return;
}
{
m_xf_body->Clear();
for (size_t i = 0; i < m_doc.bodies.size(); ++i) {
const std::string& n = m_doc.bodies[i].name;
m_xf_body->Append(n.empty() ? wxString::Format(_L("Body %zu"), i + 1) : wxString::FromUTF8(n));
}
if (m_xf_body->GetCount() > 0) m_xf_body->SetSelection(0);
}
open_tool(Tool::Transform);
}, SHIFT('Y')},
{"design_mirror", _L("Mirror"), _L("Reflect a body about a plane"),
[this] {
if (m_doc.bodies.empty()) {
m_status->SetForegroundColour(wxColour(235, 110, 110));
m_status->SetLabel(_L("Mirror needs a body — add or import one first"));
m_status->Refresh();
return;
}
{
m_mirror_body->Clear();
for (size_t i = 0; i < m_doc.bodies.size(); ++i) {
const std::string& n = m_doc.bodies[i].name;
m_mirror_body->Append(n.empty() ? wxString::Format(_L("Body %zu"), i + 1) : wxString::FromUTF8(n));
}
if (m_mirror_body->GetCount() > 0) m_mirror_body->SetSelection(0);
}
populate_plane_choices(m_mirror_plane);
open_tool(Tool::Mirror);
}, SHIFT('Z')},
{"design_plane", _L("Mate"), _L("Assembly: align two CoordSys features (fastened, planar, revolute, slider, cylindrical)"),
[this] {
open_tool(Tool::Mate);
@@ -767,72 +835,15 @@ DesignPanel::DesignPanel(wxWindow* parent)
b_color->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { on_set_body_color(); });
fadd("color", b_color);
// Dress-up: Fillet/Chamfer / Draft / Shell / Transform / Mirror / Project / Delete Face
feat_dropdown("dressup", "design_dressup", _L("Dress-up (fillet / chamfer / draft / shell / transform / mirror / project / delete)"), {
// Dress-up: finishing operations on the faces and edges of an existing solid — nothing
// that moves a body (see the Placement drawer) and nothing that creates geometry.
feat_dropdown("dressup", "design_dressup", _L("Dress-up (fillet / chamfer / draft / shell / delete face)"), {
{"design_dressup", _L("Fillet / Chamfer"), _L("Round or bevel a picked edge"),
[this] { open_tool(Tool::Dressup); }, SHIFT('F')},
{"design_draft", _L("Draft (taper a face)"), _L("Tilt a picked face by a draft angle"),
[this] { open_tool(Tool::Draft); }, SHIFT('D')},
{"design_shell", _L("Shell"), _L("Hollow the body to a wall thickness, opening a picked face"),
[this] { open_tool(Tool::Shell); }, SHIFT('K')},
{"design_move", _L("Transform"), _L("Move and/or rotate an existing body"),
[this] {
if (m_doc.bodies.empty()) {
m_status->SetForegroundColour(wxColour(235, 110, 110));
m_status->SetLabel(_L("Transform needs a body — add or import one first"));
m_status->Refresh();
return;
}
{
m_xf_body->Clear();
for (size_t i = 0; i < m_doc.bodies.size(); ++i) {
const std::string& n = m_doc.bodies[i].name;
m_xf_body->Append(n.empty() ? wxString::Format(_L("Body %zu"), i + 1) : wxString::FromUTF8(n));
}
if (m_xf_body->GetCount() > 0) m_xf_body->SetSelection(0);
}
open_tool(Tool::Transform);
}, SHIFT('Y')},
{"design_mirror", _L("Mirror"), _L("Reflect a body about a plane"),
[this] {
if (m_doc.bodies.empty()) {
m_status->SetForegroundColour(wxColour(235, 110, 110));
m_status->SetLabel(_L("Mirror needs a body — add or import one first"));
m_status->Refresh();
return;
}
{
m_mirror_body->Clear();
for (size_t i = 0; i < m_doc.bodies.size(); ++i) {
const std::string& n = m_doc.bodies[i].name;
m_mirror_body->Append(n.empty() ? wxString::Format(_L("Body %zu"), i + 1) : wxString::FromUTF8(n));
}
if (m_mirror_body->GetCount() > 0) m_mirror_body->SetSelection(0);
}
populate_plane_choices(m_mirror_plane);
open_tool(Tool::Mirror);
}, SHIFT('Z')},
{"design_sketch", _L("Project"), _L("Project body edges onto a plane as sketch entities"),
[this] {
if (m_doc.bodies.empty()) {
m_status->SetForegroundColour(wxColour(235, 110, 110));
m_status->SetLabel(_L("Project needs a body — add or import one first"));
m_status->Refresh();
return;
}
{
m_proj_source_body->Clear();
for (size_t i = 0; i < m_doc.bodies.size(); ++i) {
const std::string& n = m_doc.bodies[i].name;
m_proj_source_body->Append(n.empty() ? wxString::Format(_L("Body %zu"), i + 1) : wxString::FromUTF8(n));
}
if (m_proj_source_body->GetCount() > 0) m_proj_source_body->SetSelection(0);
}
populate_plane_choices(m_proj_plane);
m_sel_solid_face = -1;
m_proj_face_label->SetLabel(_L("(all edges)"));
open_tool(Tool::Project);
}, 0},
{"design_dressup", _L("Delete Face"), _L("Remove faces from a body and heal the solid"),
[this] {
if (m_doc.bodies.empty()) {
@@ -2856,6 +2867,18 @@ DesignPanel::DesignPanel(wxWindow* parent)
cards->Show(m_box_sketch_session, false, true);
cards->Show(m_box_constraints, false, true);
cards->Show(m_box_expr, false, true);
// A card added to the cards sizer is VISIBLE until something hides it. close_tool()'s
// hide-all only runs on a tool switch, so any card missing from THIS block renders
// stacked in the sidebar from the moment the tab opens. These eight were wired into
// close_tool() but not here, which is what bloated the panel.
cards->Show(m_box_transform, false, true);
cards->Show(m_box_mirror, false, true);
cards->Show(m_box_thicken, false, true);
cards->Show(m_box_rib, false, true);
cards->Show(m_box_project, false, true);
cards->Show(m_box_delete_face, false, true);
cards->Show(m_box_helix, false, true);
cards->Show(m_box_mate, false, true);
m_form->FitInside();
m_form->SetScrollRate(0, 10); // vertical only, like Prepare's sidebar: never scroll labels out