Show the plate's IMEX mode on its mode button

The plate's mode button showed one icon whatever the mode. It now shows the
mode the plate slices as, the one its ghosts follow. imex_mode_kind() reads it
from the heads beside the mode's primary: none is Normal, any Span head is
Custom (the multicolor modes), otherwise any Mirror head is Mirror, and heads
that all copy are Copy. One Mirror head is enough because an IQEX mirror mode
copies within the primary's gantry.

The icons are Felix14-v2's: the four kinds, each in light and dark with a hover
state, replacing the single mode icon. Two fixes to them: the light Normal
border used the dark theme's gray, and an opacity="undefined" attribute hid one
of its strokes in nanosvg. The knight outlines are drawn at 1.0 rather than
0.8, matching the other plate icons and keeping Copy and Mirror apart when
zoomed out.

Co-authored-by: Felix14_v2 <75726196+Felix14-v2@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Clifford Garwood
2026-10-02 11:29:33 -04:00
co-authored by Felix14_v2 Claude Opus 5.5
parent e8cd4be675
commit 0d36324323
25 changed files with 203 additions and 57 deletions
+14
View File
@@ -308,6 +308,20 @@ std::vector<std::pair<int, ImexRole>> parse_imex_active_tools(const std::string&
return out;
}
ImexModeKind imex_mode_kind(const std::string& active_tools_for_mode)
{
const int primary = imex_primary_tool_for_mode(active_tools_for_mode);
std::set<ImexRole> roles;
for (const auto& [phys, role] : parse_imex_active_tools(active_tools_for_mode))
if (phys != primary && role != ImexRole::Primary)
roles.insert(role);
if (roles.empty())
return ImexModeKind::Primary;
if (roles.count(ImexRole::Span))
return ImexModeKind::Custom;
return roles.count(ImexRole::Mirror) ? ImexModeKind::Mirror : ImexModeKind::Copy;
}
ImexGantryGrouping group_imex_active_tools_by_gantry(const std::string& active_tools_for_mode,
int tools_per_gantry)
{