Design: use Orca's teal CheckBox instead of raw wxCheckBox

Design drew raw OS wxCheckBoxes (grey square + inline text) where Prepare shows
Orca's teal check, one of the most visible reasons the two panels looked
unrelated. The six sidebar checkboxes (extrude flip, hole through, thread
internal, revolve flip, boolean keep-tool, loft ruled) now use Widgets/CheckBox:
the widget carries no text, so each label moves into the row's left column,
which is also Prepare's row idiom and matches the label/control grids.

CheckBox is a wxBitmapToggleButton, so its per-control Binds and the panel-wide
preview refresh listen for wxEVT_TOGGLEBUTTON as well; boolean/loft get a
label+control row instead of a bare full-width control. Checkboxes align to the
left edge of the control column, as Prepare aligns its own.

The two sketch-toolbar checkboxes are left alone — they live in the top toolbar,
not the left panel.

Verified on :10: Flip direction renders as a teal check with a white tick and
toggles correctly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q
This commit is contained in:
Tommaso Bianchi
2026-07-19 13:15:35 +02:00
co-authored by Claude Opus 4.8
parent d25ff88d76
commit f4469b8450
2 changed files with 36 additions and 23 deletions
+29 -17
View File
@@ -43,6 +43,7 @@
#include "Widgets/Label.hpp" // HarmonyOS Sans fonts (Head_*/Body_*) shared with the rest of Orca #include "Widgets/Label.hpp" // HarmonyOS Sans fonts (Head_*/Body_*) shared with the rest of Orca
#include "Widgets/DropDown.hpp" // Orca-themed combo dropdown (white/teal selector) for the tool flyouts #include "Widgets/DropDown.hpp" // Orca-themed combo dropdown (white/teal selector) for the tool flyouts
#include "Widgets/Button.hpp" // Orca-styled Button (ButtonStyle/ButtonType) — same look as Prepare #include "Widgets/Button.hpp" // Orca-styled Button (ButtonStyle/ButtonType) — same look as Prepare
#include "Widgets/CheckBox.hpp" // Orca teal check (label lives in the row's left column)
#include "libslic3r/SketchImport.hpp" // text_to_regions / svg_to_regions #include "libslic3r/SketchImport.hpp" // text_to_regions / svg_to_regions
#include "libslic3r/ThreadStandards.hpp" // ISO metric / Unified imperial thread tables #include "libslic3r/ThreadStandards.hpp" // ISO metric / Unified imperial thread tables
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
@@ -1036,9 +1037,9 @@ DesignPanel::DesignPanel(wxWindow* parent)
eform->Add(new wxStaticText(m_form, wxID_ANY, _L("Result")), 0, wxALIGN_CENTER_VERTICAL); eform->Add(new wxStaticText(m_form, wxID_ANY, _L("Result")), 0, wxALIGN_CENTER_VERTICAL);
eform->Add(m_mode, 0, wxEXPAND); eform->Add(m_mode, 0, wxEXPAND);
m_flip = new wxCheckBox(m_form, wxID_ANY, _L("Flip direction")); m_flip = new CheckBox(m_form);
eform->Add(new wxStaticText(m_form, wxID_ANY, wxEmptyString)); eform->Add(new wxStaticText(m_form, wxID_ANY, _L("Flip direction")), 0, wxALIGN_CENTER_VERTICAL);
eform->Add(m_flip, 0, wxEXPAND); eform->Add(m_flip, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
m_box_extrude->Add(eform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12); m_box_extrude->Add(eform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
} }
@@ -1110,10 +1111,10 @@ DesignPanel::DesignPanel(wxWindow* parent)
hform->Add(new wxStaticText(m_form, wxID_ANY, _L("Pos Y")), 0, wxALIGN_CENTER_VERTICAL); hform->Add(new wxStaticText(m_form, wxID_ANY, _L("Pos Y")), 0, wxALIGN_CENTER_VERTICAL);
hform->Add(m_hole_y, 0, wxEXPAND); hform->Add(m_hole_y, 0, wxEXPAND);
m_hole_through = new wxCheckBox(m_form, wxID_ANY, _L("Through")); m_hole_through = new CheckBox(m_form);
m_hole_through->SetValue(true); m_hole_through->SetValue(true);
hform->Add(new wxStaticText(m_form, wxID_ANY, _L("Mode")), 0, wxALIGN_CENTER_VERTICAL); hform->Add(new wxStaticText(m_form, wxID_ANY, _L("Through")), 0, wxALIGN_CENTER_VERTICAL);
hform->Add(m_hole_through, 0, wxEXPAND); hform->Add(m_hole_through, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
m_box_hole = new wxBoxSizer(wxVERTICAL); m_box_hole = new wxBoxSizer(wxVERTICAL);
m_box_hole->Add(card_header("design_hole", _L("Hole"), m_hdr_hole), 0, wxLEFT | wxRIGHT | wxTOP, 12); m_box_hole->Add(card_header("design_hole", _L("Hole"), m_hdr_hole), 0, wxLEFT | wxRIGHT | wxTOP, 12);
@@ -1169,16 +1170,16 @@ DesignPanel::DesignPanel(wxWindow* parent)
tform->Add(new wxStaticText(m_form, wxID_ANY, _L("Pos Y")), 0, wxALIGN_CENTER_VERTICAL); tform->Add(new wxStaticText(m_form, wxID_ANY, _L("Pos Y")), 0, wxALIGN_CENTER_VERTICAL);
tform->Add(m_thread_y, 0, wxEXPAND); tform->Add(m_thread_y, 0, wxEXPAND);
m_thread_internal = new wxCheckBox(m_form, wxID_ANY, _L("Internal (tapped bore)")); m_thread_internal = new CheckBox(m_form);
m_thread_internal->SetValue(false); m_thread_internal->SetValue(false);
// External rod uses the major radius; an internal tapped bore uses the minor // External rod uses the major radius; an internal tapped bore uses the minor
// (tap-drill) radius — re-derive the nominal radius when the role flips. // (tap-drill) radius — re-derive the nominal radius when the role flips.
m_thread_internal->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) { m_thread_internal->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& e) {
apply_thread_standard(); apply_thread_standard();
e.Skip(); e.Skip();
}); });
tform->Add(new wxStaticText(m_form, wxID_ANY, _L("Internal")), 0, wxALIGN_CENTER_VERTICAL); tform->Add(new wxStaticText(m_form, wxID_ANY, _L("Internal")), 0, wxALIGN_CENTER_VERTICAL);
tform->Add(m_thread_internal, 0, wxEXPAND); tform->Add(m_thread_internal, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
m_box_thread = new wxBoxSizer(wxVERTICAL); m_box_thread = new wxBoxSizer(wxVERTICAL);
m_box_thread->Add(card_header("design_thread", _L("Thread"), m_hdr_thread), 0, wxLEFT | wxRIGHT | wxTOP, 12); m_box_thread->Add(card_header("design_thread", _L("Thread"), m_hdr_thread), 0, wxLEFT | wxRIGHT | wxTOP, 12);
@@ -1215,9 +1216,9 @@ DesignPanel::DesignPanel(wxWindow* parent)
rform->Add(new wxStaticText(m_form, wxID_ANY, _L("Mode")), 0, wxALIGN_CENTER_VERTICAL); rform->Add(new wxStaticText(m_form, wxID_ANY, _L("Mode")), 0, wxALIGN_CENTER_VERTICAL);
rform->Add(m_revolve_mode, 0, wxEXPAND); rform->Add(m_revolve_mode, 0, wxEXPAND);
m_revolve_flip = new wxCheckBox(m_form, wxID_ANY, _L("Flip direction")); m_revolve_flip = new CheckBox(m_form);
rform->Add(new wxStaticText(m_form, wxID_ANY, wxEmptyString)); rform->Add(new wxStaticText(m_form, wxID_ANY, _L("Flip direction")), 0, wxALIGN_CENTER_VERTICAL);
rform->Add(m_revolve_flip, 0, wxEXPAND); rform->Add(m_revolve_flip, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
m_box_revolve->Add(rform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12); m_box_revolve->Add(rform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
} }
@@ -1322,9 +1323,13 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_box_boolean->Add(bform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12); m_box_boolean->Add(bform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
m_bool_keep = new wxCheckBox(m_form, wxID_ANY, _L("Keep tool body")); m_bool_keep = new CheckBox(m_form);
m_bool_keep->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { refresh_preview(); }); m_bool_keep->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent&) { refresh_preview(); });
m_box_boolean->Add(m_bool_keep, 0, wxLEFT | wxRIGHT | wxTOP, 12); auto* keeprow = new wxBoxSizer(wxHORIZONTAL);
keeprow->Add(new wxStaticText(m_form, wxID_ANY, _L("Keep tool body")), 0, wxALIGN_CENTER_VERTICAL);
keeprow->AddStretchSpacer();
keeprow->Add(m_bool_keep, 0, wxALIGN_CENTER_VERTICAL);
m_box_boolean->Add(keeprow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
} }
root->Add(m_box_boolean, 0, wxEXPAND); root->Add(m_box_boolean, 0, wxEXPAND);
@@ -1454,8 +1459,14 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_box_loft->Add(lform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12); m_box_loft->Add(lform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
} }
m_loft_ruled = new wxCheckBox(m_form, wxID_ANY, _L("Ruled (straight) sections")); m_loft_ruled = new CheckBox(m_form);
m_box_loft->Add(m_loft_ruled, 0, wxLEFT | wxRIGHT | wxTOP, 12); {
auto* lrow = new wxBoxSizer(wxHORIZONTAL);
lrow->Add(new wxStaticText(m_form, wxID_ANY, _L("Ruled (straight) sections")), 0, wxALIGN_CENTER_VERTICAL);
lrow->AddStretchSpacer();
lrow->Add(m_loft_ruled, 0, wxALIGN_CENTER_VERTICAL);
m_box_loft->Add(lrow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
}
root->Add(m_box_loft, 0, wxEXPAND); root->Add(m_box_loft, 0, wxEXPAND);
// --- Shell (hollow the current body to a wall thickness, removing one picked face) --- // --- Shell (hollow the current body to a wall thickness, removing one picked face) ---
@@ -1745,6 +1756,7 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_form->Bind(wxEVT_SPINCTRLDOUBLE, [this](wxSpinDoubleEvent& e) { refresh_preview(); e.Skip(); }); m_form->Bind(wxEVT_SPINCTRLDOUBLE, [this](wxSpinDoubleEvent& e) { refresh_preview(); e.Skip(); });
m_form->Bind(wxEVT_CHOICE, [this](wxCommandEvent& e) { refresh_preview(); e.Skip(); }); m_form->Bind(wxEVT_CHOICE, [this](wxCommandEvent& e) { refresh_preview(); e.Skip(); });
m_form->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) { refresh_preview(); e.Skip(); }); m_form->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) { refresh_preview(); e.Skip(); });
m_form->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& e) { refresh_preview(); e.Skip(); });
m_form->SetSizer(root); m_form->SetSizer(root);
+7 -6
View File
@@ -22,6 +22,7 @@ class wxImageList;
class wxStaticText; class wxStaticText;
class wxStaticLine; class wxStaticLine;
class Button; // Orca-styled button (Widgets/Button.hpp) class Button; // Orca-styled button (Widgets/Button.hpp)
class CheckBox; // Orca teal checkbox (Widgets/CheckBox.hpp)
class wxSizer; class wxSizer;
class wxButton; class wxButton;
class wxPanel; class wxPanel;
@@ -294,7 +295,7 @@ private:
wxChoice* m_extrude_end{nullptr}; // Blind/Symmetric/TwoSided/ThroughAll/UpTo* wxChoice* m_extrude_end{nullptr}; // Blind/Symmetric/TwoSided/ThroughAll/UpTo*
wxSpinCtrlDouble* m_distance2{nullptr}; // second-side depth (Two-sided) wxSpinCtrlDouble* m_distance2{nullptr}; // second-side depth (Two-sided)
wxSpinCtrlDouble* m_taper{nullptr}; // draft angle (deg) wxSpinCtrlDouble* m_taper{nullptr}; // draft angle (deg)
wxCheckBox* m_flip{nullptr}; // reverse extrude direction CheckBox* m_flip{nullptr}; // reverse extrude direction
wxStaticText* m_extrude_sketch_label{nullptr}; wxStaticText* m_extrude_sketch_label{nullptr};
int m_extrude_sketch_ref{-1}; int m_extrude_sketch_ref{-1};
@@ -304,7 +305,7 @@ private:
wxSpinCtrlDouble* m_revolve_angle{nullptr}; wxSpinCtrlDouble* m_revolve_angle{nullptr};
wxChoice* m_revolve_axis{nullptr}; // 0 = plane X, 1 = plane Y wxChoice* m_revolve_axis{nullptr}; // 0 = plane X, 1 = plane Y
wxChoice* m_revolve_mode{nullptr}; // New/Add/Cut/Intersect wxChoice* m_revolve_mode{nullptr}; // New/Add/Cut/Intersect
wxCheckBox* m_revolve_flip{nullptr}; CheckBox* m_revolve_flip{nullptr};
int m_revolve_sketch_ref{-1}; int m_revolve_sketch_ref{-1};
// Sweep controls (sweep a profile sketch along a path sketch). // Sweep controls (sweep a profile sketch along a path sketch).
@@ -316,7 +317,7 @@ private:
// Loft controls (skin a solid through 2+ ordered profile Sketches). // Loft controls (skin a solid through 2+ ordered profile Sketches).
wxCheckListBox* m_loft_list{nullptr}; // every Sketch; check 2+ in list order = profiles wxCheckListBox* m_loft_list{nullptr}; // every Sketch; check 2+ in list order = profiles
wxCheckBox* m_loft_ruled{nullptr}; // ruled (straight) vs smooth sections CheckBox* m_loft_ruled{nullptr}; // ruled (straight) vs smooth sections
wxChoice* m_loft_mode{nullptr}; // New/Add/Cut/Intersect wxChoice* m_loft_mode{nullptr}; // New/Add/Cut/Intersect
std::vector<int> m_loft_sketch_idx; // feature index for each row in m_loft_list std::vector<int> m_loft_sketch_idx; // feature index for each row in m_loft_list
std::vector<int> m_loft_refs; // chosen profile refs (for re-edit pre-check) std::vector<int> m_loft_refs; // chosen profile refs (for re-edit pre-check)
@@ -331,7 +332,7 @@ private:
wxChoice* m_bool_op{nullptr}; // 0 = Union, 1 = Subtract, 2 = Intersect wxChoice* m_bool_op{nullptr}; // 0 = Union, 1 = Subtract, 2 = Intersect
wxChoice* m_bool_target{nullptr}; // body that survives (selection == body index) wxChoice* m_bool_target{nullptr}; // body that survives (selection == body index)
wxChoice* m_bool_tool{nullptr}; // body consumed (selection == body index) wxChoice* m_bool_tool{nullptr}; // body consumed (selection == body index)
wxCheckBox* m_bool_keep{nullptr}; // keep the tool body after the op CheckBox* m_bool_keep{nullptr}; // keep the tool body after the op
wxSpinCtrlDouble* m_bool_tol{nullptr}; // OCCT fuzzy tolerance (mm); robust cut on near-coincident faces wxSpinCtrlDouble* m_bool_tol{nullptr}; // OCCT fuzzy tolerance (mm); robust cut on near-coincident faces
// Plane Cut (split-by-plane): a reference plane + offset splits the target body into // Plane Cut (split-by-plane): a reference plane + offset splits the target body into
@@ -378,7 +379,7 @@ private:
wxChoice* m_hole_plane{nullptr}; wxChoice* m_hole_plane{nullptr};
wxSpinCtrlDouble* m_hole_diameter{nullptr}; wxSpinCtrlDouble* m_hole_diameter{nullptr};
wxSpinCtrlDouble* m_hole_depth{nullptr}; wxSpinCtrlDouble* m_hole_depth{nullptr};
wxCheckBox* m_hole_through{nullptr}; CheckBox* m_hole_through{nullptr};
wxSpinCtrlDouble* m_hole_x{nullptr}; wxSpinCtrlDouble* m_hole_x{nullptr};
wxSpinCtrlDouble* m_hole_y{nullptr}; wxSpinCtrlDouble* m_hole_y{nullptr};
// #2: when the Hole tool is opened on a picked solid face, drill on that face centred // #2: when the Hole tool is opened on a picked solid face, drill on that face centred
@@ -398,7 +399,7 @@ private:
wxSpinCtrlDouble* m_thread_pitch{nullptr}; wxSpinCtrlDouble* m_thread_pitch{nullptr};
wxSpinCtrlDouble* m_thread_height{nullptr}; wxSpinCtrlDouble* m_thread_height{nullptr};
wxSpinCtrlDouble* m_thread_depth{nullptr}; wxSpinCtrlDouble* m_thread_depth{nullptr};
wxCheckBox* m_thread_internal{nullptr}; CheckBox* m_thread_internal{nullptr};
wxSpinCtrlDouble* m_thread_x{nullptr}; wxSpinCtrlDouble* m_thread_x{nullptr};
wxSpinCtrlDouble* m_thread_y{nullptr}; wxSpinCtrlDouble* m_thread_y{nullptr};
// #3: when the Thread tool is opened on a picked cylindrical face (a hole bore or a // #3: when the Thread tool is opened on a picked cylindrical face (a hole bore or a