forked from 1b-agent/opencadstudio-upstream
perf(core): cache ribbon_groups() with OnceLock, avoid per-frame tree allocations
Change CadModule::ribbon_groups() from -> Vec<RibbonGroup> to -> &[RibbonGroup], backed by a per-module OnceLock cache. The ribbon group tree is static data (&'static str, Copy enums) that was being fully reconstructed — Vecs, String clones, enum discriminants — on every call, including all three per-frame call sites (view(), dropdown_overlay(), style_combo_overlay()). - 7 built-in modules + 2 plugin templates cache via function-local OnceLock. Safe because each is a unit struct with exactly one instance per process (plugins run in isolated child processes; see PluginProcess::spawn()). - SharedCadModule avoids the static pattern entirely, storing groups in an instance field (owned.rs). - IPC runner converts &RibbonGroup -> OwnedRibbonGroup directly via new From<&T> impls, avoiding an intermediate clone. - render_small/render_large and the two make_tool_row closures now borrow (&RibbonItem, &[ToolDef]) instead of taking ownership, so the view loop doesn't need to clone items to satisfy the old by-value signatures. - Various match-ergonomics deref fixes (*id, *default, *icon, etc.) from the &RibbonItem pattern change.
This commit is contained in:
1 parent
8164e14a19
commit
73b05e1dec
14 files changed
+947
-690
No files matched your search
+190
-183
@@ -38,193 +38,200 @@ impl CadModule for AnnotateModule {
|
||||
"Annotate"
|
||||
}
|
||||
|
||||
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
|
||||
fn ribbon_groups(&self) -> &[RibbonGroup] {
|
||||
use crate::modules::draw::draw::{revcloud, wipeout};
|
||||
|
||||
vec![
|
||||
// ── Text ─────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Text",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATE_TEXT",
|
||||
label: "Multiline\nText",
|
||||
icon: mtext::ICON,
|
||||
items: vec![
|
||||
(mtext::tool().id, mtext::tool().label, mtext::tool().icon),
|
||||
(text::tool().id, text::tool().label, text::tool().icon),
|
||||
(ddedit::tool().id, ddedit::tool().label, ddedit::tool().icon),
|
||||
],
|
||||
default: "MTEXT",
|
||||
},
|
||||
RibbonItem::StyleComboGroup {
|
||||
style_key: StyleKey::TextStyle,
|
||||
combo_id: "TEXT_STYLE_COMBO",
|
||||
manager_cmd: Some("STYLE"),
|
||||
rows: vec![vec![crate::modules::ToolDef {
|
||||
id: "FIND",
|
||||
label: "Find",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/find.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("FIND".to_string()),
|
||||
}]],
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Dimensions ───────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Dimensions",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATE_DIM",
|
||||
label: "Dimension",
|
||||
icon: linear_dim::ICON,
|
||||
items: vec![
|
||||
(
|
||||
linear_dim::tool().id,
|
||||
linear_dim::tool().label,
|
||||
linear_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
aligned_dim::tool().id,
|
||||
aligned_dim::tool().label,
|
||||
aligned_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
angular_dim::tool().id,
|
||||
angular_dim::tool().label,
|
||||
angular_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
radius_dim::tool().id,
|
||||
radius_dim::tool().label,
|
||||
radius_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
diameter_dim::tool().id,
|
||||
diameter_dim::tool().label,
|
||||
diameter_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
ordinate_dim::tool().id,
|
||||
ordinate_dim::tool().label,
|
||||
ordinate_dim::tool().icon,
|
||||
),
|
||||
(qdim::tool().id, qdim::tool().label, qdim::tool().icon),
|
||||
],
|
||||
default: "DIMLINEAR",
|
||||
},
|
||||
RibbonItem::StyleComboGroup {
|
||||
style_key: StyleKey::DimStyle,
|
||||
combo_id: "DIM_STYLE_COMBO",
|
||||
manager_cmd: Some("DIMSTYLE"),
|
||||
rows: vec![
|
||||
vec![qdim::tool(), dim_continue::tool(), dim_baseline::tool()],
|
||||
vec![
|
||||
tolerance_cmd::tool(),
|
||||
dimedit::tool(),
|
||||
dimtedit::tool(),
|
||||
dimbreak::tool(),
|
||||
dimspace::tool(),
|
||||
dimjogline::tool(),
|
||||
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
|
||||
GROUPS.get_or_init(|| {
|
||||
vec![
|
||||
// ── Text ─────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Text",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATE_TEXT",
|
||||
label: "Multiline\nText",
|
||||
icon: mtext::ICON,
|
||||
items: vec![
|
||||
(mtext::tool().id, mtext::tool().label, mtext::tool().icon),
|
||||
(text::tool().id, text::tool().label, text::tool().icon),
|
||||
(ddedit::tool().id, ddedit::tool().label, ddedit::tool().icon),
|
||||
],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Leaders ──────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Leaders",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATE_LEADER",
|
||||
label: "Multileader",
|
||||
icon: mleader_cmd::ICON,
|
||||
items: vec![
|
||||
(
|
||||
mleader_cmd::tool().id,
|
||||
mleader_cmd::tool().label,
|
||||
mleader_cmd::tool().icon,
|
||||
default: "MTEXT",
|
||||
},
|
||||
RibbonItem::StyleComboGroup {
|
||||
style_key: StyleKey::TextStyle,
|
||||
combo_id: "TEXT_STYLE_COMBO",
|
||||
manager_cmd: Some("STYLE"),
|
||||
rows: vec![vec![crate::modules::ToolDef {
|
||||
id: "FIND",
|
||||
label: "Find",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/find.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("FIND".to_string()),
|
||||
}]],
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Dimensions ───────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Dimensions",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATE_DIM",
|
||||
label: "Dimension",
|
||||
icon: linear_dim::ICON,
|
||||
items: vec![
|
||||
(
|
||||
linear_dim::tool().id,
|
||||
linear_dim::tool().label,
|
||||
linear_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
aligned_dim::tool().id,
|
||||
aligned_dim::tool().label,
|
||||
aligned_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
angular_dim::tool().id,
|
||||
angular_dim::tool().label,
|
||||
angular_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
radius_dim::tool().id,
|
||||
radius_dim::tool().label,
|
||||
radius_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
diameter_dim::tool().id,
|
||||
diameter_dim::tool().label,
|
||||
diameter_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
ordinate_dim::tool().id,
|
||||
ordinate_dim::tool().label,
|
||||
ordinate_dim::tool().icon,
|
||||
),
|
||||
(qdim::tool().id, qdim::tool().label, qdim::tool().icon),
|
||||
],
|
||||
default: "DIMLINEAR",
|
||||
},
|
||||
RibbonItem::StyleComboGroup {
|
||||
style_key: StyleKey::DimStyle,
|
||||
combo_id: "DIM_STYLE_COMBO",
|
||||
manager_cmd: Some("DIMSTYLE"),
|
||||
rows: vec![
|
||||
vec![qdim::tool(), dim_continue::tool(), dim_baseline::tool()],
|
||||
vec![
|
||||
tolerance_cmd::tool(),
|
||||
dimedit::tool(),
|
||||
dimtedit::tool(),
|
||||
dimbreak::tool(),
|
||||
dimspace::tool(),
|
||||
dimjogline::tool(),
|
||||
],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Leaders ──────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Leaders",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATE_LEADER",
|
||||
label: "Multileader",
|
||||
icon: mleader_cmd::ICON,
|
||||
items: vec![
|
||||
(
|
||||
mleader_cmd::tool().id,
|
||||
mleader_cmd::tool().label,
|
||||
mleader_cmd::tool().icon,
|
||||
),
|
||||
(
|
||||
leader_cmd::tool().id,
|
||||
leader_cmd::tool().label,
|
||||
leader_cmd::tool().icon,
|
||||
),
|
||||
],
|
||||
default: "MLEADER",
|
||||
},
|
||||
RibbonItem::StyleComboGroup {
|
||||
style_key: StyleKey::MLeaderStyle,
|
||||
combo_id: "MLEADER_STYLE_COMBO",
|
||||
manager_cmd: Some("MLEADERSTYLE"),
|
||||
rows: vec![
|
||||
vec![mleader_edit::tool_add(), mleader_edit::tool_remove()],
|
||||
vec![mleader_edit::tool_align(), mleader_edit::tool_collect()],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Tables ───────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Tables",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(table_cmd::tool()),
|
||||
RibbonItem::StyleComboGroup {
|
||||
style_key: StyleKey::TableStyle,
|
||||
combo_id: "TABLE_STYLE_COMBO",
|
||||
manager_cmd: Some("TABLESTYLE"),
|
||||
rows: vec![vec![data_extract::tool(), data_link::tool()]],
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Markup ───────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Markup",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(wipeout::tool()),
|
||||
RibbonItem::LargeTool(revcloud::tool()),
|
||||
],
|
||||
},
|
||||
// ── Annotation Scaling ───────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Annotation Scaling",
|
||||
tools: vec![
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "ANNOSCALE",
|
||||
label: "Scale List",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/scale_list.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("ANNOSCALE".to_string()),
|
||||
}),
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "OBJECTSCALE",
|
||||
label: "Add Scale",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/add_scale.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("OBJECTSCALE".to_string()),
|
||||
}),
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "SCALELISTEDIT",
|
||||
label: "Scale Edit",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/scale_list.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command(
|
||||
"SCALELISTEDIT".to_string(),
|
||||
),
|
||||
(
|
||||
leader_cmd::tool().id,
|
||||
leader_cmd::tool().label,
|
||||
leader_cmd::tool().icon,
|
||||
}),
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "SYNCPVIEWPORTS",
|
||||
label: "Sync Scales",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/sync.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command(
|
||||
"SYNCPVIEWPORTS".to_string(),
|
||||
),
|
||||
],
|
||||
default: "MLEADER",
|
||||
},
|
||||
RibbonItem::StyleComboGroup {
|
||||
style_key: StyleKey::MLeaderStyle,
|
||||
combo_id: "MLEADER_STYLE_COMBO",
|
||||
manager_cmd: Some("MLEADERSTYLE"),
|
||||
rows: vec![
|
||||
vec![mleader_edit::tool_add(), mleader_edit::tool_remove()],
|
||||
vec![mleader_edit::tool_align(), mleader_edit::tool_collect()],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Tables ───────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Tables",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(table_cmd::tool()),
|
||||
RibbonItem::StyleComboGroup {
|
||||
style_key: StyleKey::TableStyle,
|
||||
combo_id: "TABLE_STYLE_COMBO",
|
||||
manager_cmd: Some("TABLESTYLE"),
|
||||
rows: vec![vec![data_extract::tool(), data_link::tool()]],
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Markup ───────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Markup",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(wipeout::tool()),
|
||||
RibbonItem::LargeTool(revcloud::tool()),
|
||||
],
|
||||
},
|
||||
// ── Annotation Scaling ───────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Annotation Scaling",
|
||||
tools: vec![
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "ANNOSCALE",
|
||||
label: "Scale List",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/scale_list.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("ANNOSCALE".to_string()),
|
||||
}),
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "OBJECTSCALE",
|
||||
label: "Add Scale",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/add_scale.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("OBJECTSCALE".to_string()),
|
||||
}),
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "SCALELISTEDIT",
|
||||
label: "Scale Edit",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/scale_list.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("SCALELISTEDIT".to_string()),
|
||||
}),
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "SYNCPVIEWPORTS",
|
||||
label: "Sync Scales",
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/sync.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("SYNCPVIEWPORTS".to_string()),
|
||||
}),
|
||||
],
|
||||
},
|
||||
]
|
||||
}),
|
||||
],
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
+189
-186
@@ -26,7 +26,7 @@ impl CadModule for DrawModule {
|
||||
"Draw"
|
||||
}
|
||||
|
||||
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
|
||||
fn ribbon_groups(&self) -> &[RibbonGroup] {
|
||||
use crate::modules::annotate::{
|
||||
angular_dim, leader_cmd, linear_dim, mleader_cmd, mtext, radius_dim, text,
|
||||
};
|
||||
@@ -43,190 +43,193 @@ impl CadModule for DrawModule {
|
||||
};
|
||||
use properties::match_prop;
|
||||
|
||||
vec![
|
||||
RibbonGroup {
|
||||
title: "Draw",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(line::tool()),
|
||||
RibbonItem::LargeTool(polyline::tool()),
|
||||
RibbonItem::LargeDropdown {
|
||||
id: circle::DROPDOWN_ID,
|
||||
label: "Circle",
|
||||
icon: circle::ICON,
|
||||
items: circle::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "CIRCLE",
|
||||
},
|
||||
RibbonItem::LargeDropdown {
|
||||
id: arc::DROPDOWN_ID,
|
||||
label: "Arc",
|
||||
icon: arc::ICON,
|
||||
items: arc::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "ARC",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: shapes::DROPDOWN_ID,
|
||||
icon: shapes::ICON,
|
||||
items: shapes::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "RECT",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: ellipse::DROPDOWN_ID,
|
||||
icon: ellipse::ICON,
|
||||
items: ellipse::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "ELLIPSE",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: hatch::DROPDOWN_ID,
|
||||
icon: hatch::ICON,
|
||||
items: hatch::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "HATCH",
|
||||
},
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Modify",
|
||||
tools: vec![
|
||||
translate::tool().into(),
|
||||
copy::tool().into(),
|
||||
stretch::tool().into(),
|
||||
rotate::tool().into(),
|
||||
mirror::tool().into(),
|
||||
scale::tool().into(),
|
||||
RibbonItem::Dropdown {
|
||||
id: trim::DROPDOWN_ID,
|
||||
icon: trim::ICON,
|
||||
items: trim::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "TRIM",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: fillet::DROPDOWN_ID,
|
||||
icon: fillet::ICON,
|
||||
items: fillet::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "FILLET",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: array::DROPDOWN_ID,
|
||||
icon: array::ICON,
|
||||
items: array::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "ARRAYRECT",
|
||||
},
|
||||
delete::tool().into(),
|
||||
explode::tool().into(),
|
||||
offset::tool().into(),
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Annotation",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATION_TEXT",
|
||||
label: "Text",
|
||||
icon: text::ICON,
|
||||
items: vec![
|
||||
(text::tool().id, text::tool().label, text::tool().icon),
|
||||
(mtext::tool().id, mtext::tool().label, mtext::tool().icon),
|
||||
],
|
||||
default: "TEXT",
|
||||
},
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATION_DIMENSIONS",
|
||||
label: "Dimensions",
|
||||
icon: linear_dim::ICON,
|
||||
items: vec![
|
||||
(
|
||||
linear_dim::tool().id,
|
||||
linear_dim::tool().label,
|
||||
linear_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
radius_dim::tool().id,
|
||||
radius_dim::tool().label,
|
||||
radius_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
angular_dim::tool().id,
|
||||
angular_dim::tool().label,
|
||||
angular_dim::tool().icon,
|
||||
),
|
||||
],
|
||||
default: "DIMLINEAR",
|
||||
},
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATION_LEADER",
|
||||
label: "Leader",
|
||||
icon: leader_cmd::ICON,
|
||||
items: vec![
|
||||
(
|
||||
mleader_cmd::tool().id,
|
||||
mleader_cmd::tool().label,
|
||||
mleader_cmd::tool().icon,
|
||||
),
|
||||
(
|
||||
leader_cmd::tool().id,
|
||||
leader_cmd::tool().label,
|
||||
leader_cmd::tool().icon,
|
||||
),
|
||||
],
|
||||
default: "MLEADER",
|
||||
},
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Layers",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(panel::tool()),
|
||||
RibbonItem::LayerComboGroup {
|
||||
row2: vec![
|
||||
layoff::tool(),
|
||||
layfrz::tool(),
|
||||
laylck::tool(),
|
||||
make_current::tool(),
|
||||
],
|
||||
row3: vec![
|
||||
layon::tool(),
|
||||
laythw::tool(),
|
||||
layulk::tool(),
|
||||
match_layer::tool(),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Block",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(create_block::tool()),
|
||||
RibbonItem::LargeTool(insert_block::tool()),
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Properties",
|
||||
tools: vec![RibbonItem::PropertiesGroup {
|
||||
match_prop: match_prop::tool(),
|
||||
}],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Groups",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(group::tool()),
|
||||
RibbonItem::LargeTool(ungroup::tool()),
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Clipboard",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "PASTE_MENU",
|
||||
label: "Paste",
|
||||
icon: paste::ICON,
|
||||
items: paste::MENU_ITEMS.to_vec(),
|
||||
default: "PASTECLIP",
|
||||
},
|
||||
copy_clip::tool().into(),
|
||||
cut::tool().into(),
|
||||
],
|
||||
},
|
||||
// Support group lives on the Start tab now (see view.rs:
|
||||
// start_page_view). Removed from the Draw ribbon to declutter.
|
||||
]
|
||||
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
|
||||
GROUPS.get_or_init(|| {
|
||||
vec![
|
||||
RibbonGroup {
|
||||
title: "Draw",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(line::tool()),
|
||||
RibbonItem::LargeTool(polyline::tool()),
|
||||
RibbonItem::LargeDropdown {
|
||||
id: circle::DROPDOWN_ID,
|
||||
label: "Circle",
|
||||
icon: circle::ICON,
|
||||
items: circle::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "CIRCLE",
|
||||
},
|
||||
RibbonItem::LargeDropdown {
|
||||
id: arc::DROPDOWN_ID,
|
||||
label: "Arc",
|
||||
icon: arc::ICON,
|
||||
items: arc::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "ARC",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: shapes::DROPDOWN_ID,
|
||||
icon: shapes::ICON,
|
||||
items: shapes::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "RECT",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: ellipse::DROPDOWN_ID,
|
||||
icon: ellipse::ICON,
|
||||
items: ellipse::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "ELLIPSE",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: hatch::DROPDOWN_ID,
|
||||
icon: hatch::ICON,
|
||||
items: hatch::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "HATCH",
|
||||
},
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Modify",
|
||||
tools: vec![
|
||||
translate::tool().into(),
|
||||
copy::tool().into(),
|
||||
stretch::tool().into(),
|
||||
rotate::tool().into(),
|
||||
mirror::tool().into(),
|
||||
scale::tool().into(),
|
||||
RibbonItem::Dropdown {
|
||||
id: trim::DROPDOWN_ID,
|
||||
icon: trim::ICON,
|
||||
items: trim::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "TRIM",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: fillet::DROPDOWN_ID,
|
||||
icon: fillet::ICON,
|
||||
items: fillet::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "FILLET",
|
||||
},
|
||||
RibbonItem::Dropdown {
|
||||
id: array::DROPDOWN_ID,
|
||||
icon: array::ICON,
|
||||
items: array::DROPDOWN_ITEMS.to_vec(),
|
||||
default: "ARRAYRECT",
|
||||
},
|
||||
delete::tool().into(),
|
||||
explode::tool().into(),
|
||||
offset::tool().into(),
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Annotation",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATION_TEXT",
|
||||
label: "Text",
|
||||
icon: text::ICON,
|
||||
items: vec![
|
||||
(text::tool().id, text::tool().label, text::tool().icon),
|
||||
(mtext::tool().id, mtext::tool().label, mtext::tool().icon),
|
||||
],
|
||||
default: "TEXT",
|
||||
},
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATION_DIMENSIONS",
|
||||
label: "Dimensions",
|
||||
icon: linear_dim::ICON,
|
||||
items: vec![
|
||||
(
|
||||
linear_dim::tool().id,
|
||||
linear_dim::tool().label,
|
||||
linear_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
radius_dim::tool().id,
|
||||
radius_dim::tool().label,
|
||||
radius_dim::tool().icon,
|
||||
),
|
||||
(
|
||||
angular_dim::tool().id,
|
||||
angular_dim::tool().label,
|
||||
angular_dim::tool().icon,
|
||||
),
|
||||
],
|
||||
default: "DIMLINEAR",
|
||||
},
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "ANNOTATION_LEADER",
|
||||
label: "Leader",
|
||||
icon: leader_cmd::ICON,
|
||||
items: vec![
|
||||
(
|
||||
mleader_cmd::tool().id,
|
||||
mleader_cmd::tool().label,
|
||||
mleader_cmd::tool().icon,
|
||||
),
|
||||
(
|
||||
leader_cmd::tool().id,
|
||||
leader_cmd::tool().label,
|
||||
leader_cmd::tool().icon,
|
||||
),
|
||||
],
|
||||
default: "MLEADER",
|
||||
},
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Layers",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(panel::tool()),
|
||||
RibbonItem::LayerComboGroup {
|
||||
row2: vec![
|
||||
layoff::tool(),
|
||||
layfrz::tool(),
|
||||
laylck::tool(),
|
||||
make_current::tool(),
|
||||
],
|
||||
row3: vec![
|
||||
layon::tool(),
|
||||
laythw::tool(),
|
||||
layulk::tool(),
|
||||
match_layer::tool(),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Block",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(create_block::tool()),
|
||||
RibbonItem::LargeTool(insert_block::tool()),
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Properties",
|
||||
tools: vec![RibbonItem::PropertiesGroup {
|
||||
match_prop: match_prop::tool(),
|
||||
}],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Groups",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(group::tool()),
|
||||
RibbonItem::LargeTool(ungroup::tool()),
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Clipboard",
|
||||
tools: vec![
|
||||
RibbonItem::LargeDropdown {
|
||||
id: "PASTE_MENU",
|
||||
label: "Paste",
|
||||
icon: paste::ICON,
|
||||
items: paste::MENU_ITEMS.to_vec(),
|
||||
default: "PASTECLIP",
|
||||
},
|
||||
copy_clip::tool().into(),
|
||||
cut::tool().into(),
|
||||
],
|
||||
},
|
||||
// Support group lives on the Start tab now (see view.rs:
|
||||
// start_page_view). Removed from the Draw ribbon to declutter.
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
+89
-86
@@ -35,91 +35,94 @@ impl CadModule for InsertModule {
|
||||
"Insert"
|
||||
}
|
||||
|
||||
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
|
||||
vec![
|
||||
// ── Reference ────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Reference",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(xattach::tool()),
|
||||
RibbonItem::LargeTool(xclip::tool()),
|
||||
RibbonItem::LargeTool(xadjust::tool()),
|
||||
RibbonItem::Tool(underlay_layers::tool()),
|
||||
RibbonItem::Dropdown {
|
||||
id: "FRAMES_DROPDOWN",
|
||||
icon: IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/underlay_frames.svg"
|
||||
)),
|
||||
items: vec![
|
||||
(
|
||||
"FRAMES0",
|
||||
"Frames Off",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/underlay_frames.svg"
|
||||
)),
|
||||
),
|
||||
(
|
||||
"FRAMES1",
|
||||
"Frames On",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/underlay_frames.svg"
|
||||
)),
|
||||
),
|
||||
(
|
||||
"FRAMES2",
|
||||
"Frames & Print",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/underlay_frames.svg"
|
||||
)),
|
||||
),
|
||||
],
|
||||
default: "FRAMES1",
|
||||
},
|
||||
RibbonItem::Tool(snap_underlays::tool()),
|
||||
],
|
||||
},
|
||||
// ── Point Cloud ───────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Point Cloud",
|
||||
tools: vec![RibbonItem::LargeTool(pc_attach::tool())],
|
||||
},
|
||||
// ── Block ─────────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Block",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(mview_block::tool()),
|
||||
RibbonItem::LargeTool(insert_block::tool()),
|
||||
RibbonItem::Tool(create_block::tool()),
|
||||
RibbonItem::Tool(edit_block::tool()),
|
||||
RibbonItem::Tool(base_point::tool()),
|
||||
],
|
||||
},
|
||||
// ── Attributes ────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Attributes",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(attdef::tool()),
|
||||
RibbonItem::LargeTool(attedit::tool()),
|
||||
RibbonItem::Tool(attman::tool()),
|
||||
RibbonItem::Tool(attsync::tool()),
|
||||
],
|
||||
},
|
||||
// ── Import ────────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Import",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(open_obj::tool()),
|
||||
RibbonItem::LargeTool(landxml::tool()),
|
||||
],
|
||||
},
|
||||
// ── Content ───────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Content",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(content_browser::tool()),
|
||||
RibbonItem::LargeTool(design_center::tool()),
|
||||
],
|
||||
},
|
||||
]
|
||||
fn ribbon_groups(&self) -> &[RibbonGroup] {
|
||||
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
|
||||
GROUPS.get_or_init(|| {
|
||||
vec![
|
||||
// ── Reference ────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Reference",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(xattach::tool()),
|
||||
RibbonItem::LargeTool(xclip::tool()),
|
||||
RibbonItem::LargeTool(xadjust::tool()),
|
||||
RibbonItem::Tool(underlay_layers::tool()),
|
||||
RibbonItem::Dropdown {
|
||||
id: "FRAMES_DROPDOWN",
|
||||
icon: IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/underlay_frames.svg"
|
||||
)),
|
||||
items: vec![
|
||||
(
|
||||
"FRAMES0",
|
||||
"Frames Off",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/underlay_frames.svg"
|
||||
)),
|
||||
),
|
||||
(
|
||||
"FRAMES1",
|
||||
"Frames On",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/underlay_frames.svg"
|
||||
)),
|
||||
),
|
||||
(
|
||||
"FRAMES2",
|
||||
"Frames & Print",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/underlay_frames.svg"
|
||||
)),
|
||||
),
|
||||
],
|
||||
default: "FRAMES1",
|
||||
},
|
||||
RibbonItem::Tool(snap_underlays::tool()),
|
||||
],
|
||||
},
|
||||
// ── Point Cloud ───────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Point Cloud",
|
||||
tools: vec![RibbonItem::LargeTool(pc_attach::tool())],
|
||||
},
|
||||
// ── Block ─────────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Block",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(mview_block::tool()),
|
||||
RibbonItem::LargeTool(insert_block::tool()),
|
||||
RibbonItem::Tool(create_block::tool()),
|
||||
RibbonItem::Tool(edit_block::tool()),
|
||||
RibbonItem::Tool(base_point::tool()),
|
||||
],
|
||||
},
|
||||
// ── Attributes ────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Attributes",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(attdef::tool()),
|
||||
RibbonItem::LargeTool(attedit::tool()),
|
||||
RibbonItem::Tool(attman::tool()),
|
||||
RibbonItem::Tool(attsync::tool()),
|
||||
],
|
||||
},
|
||||
// ── Import ────────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Import",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(open_obj::tool()),
|
||||
RibbonItem::LargeTool(landxml::tool()),
|
||||
],
|
||||
},
|
||||
// ── Content ───────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Content",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(content_browser::tool()),
|
||||
RibbonItem::LargeTool(design_center::tool()),
|
||||
],
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
+31
-26
@@ -36,31 +36,36 @@ impl CadModule for LayoutModule {
|
||||
"Layout"
|
||||
}
|
||||
|
||||
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
|
||||
vec![
|
||||
RibbonGroup {
|
||||
title: "Viewport",
|
||||
tools: vec![mview::tool().into()],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Plot",
|
||||
tools: vec![
|
||||
ToolDef {
|
||||
id: "PAGESETUP",
|
||||
label: "Page Setup",
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/pagesetup.svg")),
|
||||
event: ModuleEvent::Command("PAGESETUP".to_string()),
|
||||
}
|
||||
.into(),
|
||||
ToolDef {
|
||||
id: "PLOT",
|
||||
label: "Export PDF",
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/plot.svg")),
|
||||
event: ModuleEvent::Command("PLOT".to_string()),
|
||||
}
|
||||
.into(),
|
||||
],
|
||||
},
|
||||
]
|
||||
fn ribbon_groups(&self) -> &[RibbonGroup] {
|
||||
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
|
||||
GROUPS.get_or_init(|| {
|
||||
vec![
|
||||
RibbonGroup {
|
||||
title: "Viewport",
|
||||
tools: vec![mview::tool().into()],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Plot",
|
||||
tools: vec![
|
||||
ToolDef {
|
||||
id: "PAGESETUP",
|
||||
label: "Page Setup",
|
||||
icon: IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/pagesetup.svg"
|
||||
)),
|
||||
event: ModuleEvent::Command("PAGESETUP".to_string()),
|
||||
}
|
||||
.into(),
|
||||
ToolDef {
|
||||
id: "PLOT",
|
||||
label: "Export PDF",
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/plot.svg")),
|
||||
event: ModuleEvent::Command("PLOT".to_string()),
|
||||
}
|
||||
.into(),
|
||||
],
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
+56
-53
@@ -21,58 +21,61 @@ impl CadModule for ManageModule {
|
||||
"Manage"
|
||||
}
|
||||
|
||||
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
|
||||
vec![
|
||||
// ── Customization ─────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Customization",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(user_interface::tool()),
|
||||
RibbonItem::LargeTool(crate::modules::ToolDef {
|
||||
id: "TOOLPALETTES",
|
||||
label: "Tool\nPalettes",
|
||||
icon: IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/tool_palettes.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("TOOLPALETTES".to_string()),
|
||||
}),
|
||||
RibbonItem::Tool(cui_import::tool()),
|
||||
RibbonItem::Tool(cui_export::tool()),
|
||||
RibbonItem::Dropdown {
|
||||
id: "ALIASEDIT_DROPDOWN",
|
||||
icon: IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/edit_aliases.svg"
|
||||
)),
|
||||
items: vec![
|
||||
(
|
||||
"ALIASEDIT",
|
||||
"Edit Aliases",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/edit_aliases.svg"
|
||||
)),
|
||||
),
|
||||
(
|
||||
"CUILOAD",
|
||||
"Load Partial CUI",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/cui_import.svg"
|
||||
)),
|
||||
),
|
||||
],
|
||||
default: "ALIASEDIT",
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Cleanup ───────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Cleanup",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(find_nonpurgeable::tool()),
|
||||
RibbonItem::Tool(purge::tool()),
|
||||
RibbonItem::Tool(overkill::tool()),
|
||||
RibbonItem::Tool(audit::tool()),
|
||||
],
|
||||
},
|
||||
]
|
||||
fn ribbon_groups(&self) -> &[RibbonGroup] {
|
||||
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
|
||||
GROUPS.get_or_init(|| {
|
||||
vec![
|
||||
// ── Customization ─────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Customization",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(user_interface::tool()),
|
||||
RibbonItem::LargeTool(crate::modules::ToolDef {
|
||||
id: "TOOLPALETTES",
|
||||
label: "Tool\nPalettes",
|
||||
icon: IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/tool_palettes.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("TOOLPALETTES".to_string()),
|
||||
}),
|
||||
RibbonItem::Tool(cui_import::tool()),
|
||||
RibbonItem::Tool(cui_export::tool()),
|
||||
RibbonItem::Dropdown {
|
||||
id: "ALIASEDIT_DROPDOWN",
|
||||
icon: IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/edit_aliases.svg"
|
||||
)),
|
||||
items: vec![
|
||||
(
|
||||
"ALIASEDIT",
|
||||
"Edit Aliases",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/edit_aliases.svg"
|
||||
)),
|
||||
),
|
||||
(
|
||||
"CUILOAD",
|
||||
"Load Partial CUI",
|
||||
IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/cui_import.svg"
|
||||
)),
|
||||
),
|
||||
],
|
||||
default: "ALIASEDIT",
|
||||
},
|
||||
],
|
||||
},
|
||||
// ── Cleanup ───────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Cleanup",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(find_nonpurgeable::tool()),
|
||||
RibbonItem::Tool(purge::tool()),
|
||||
RibbonItem::Tool(overkill::tool()),
|
||||
RibbonItem::Tool(audit::tool()),
|
||||
],
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
+32
-29
@@ -40,34 +40,37 @@ impl CadModule for ModelModule {
|
||||
"Model"
|
||||
}
|
||||
|
||||
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
|
||||
vec![
|
||||
RibbonGroup {
|
||||
title: "Model",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool("BOX", "Box", BOX_ICON)),
|
||||
RibbonItem::LargeTool(tool("CYLINDER", "Cylinder", CYLINDER_ICON)),
|
||||
RibbonItem::LargeTool(tool("CONE", "Cone", CONE_ICON)),
|
||||
RibbonItem::LargeTool(tool("SPHERE", "Sphere", SPHERE_ICON)),
|
||||
RibbonItem::Dropdown {
|
||||
id: "MODEL_MORE",
|
||||
icon: IconKind::Svg(WEDGE_ICON),
|
||||
items: vec![
|
||||
("WEDGE", "Wedge", IconKind::Svg(WEDGE_ICON)),
|
||||
("TORUS", "Torus", IconKind::Svg(TORUS_ICON)),
|
||||
],
|
||||
default: "WEDGE",
|
||||
},
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Design",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool("UNION", "Union", UNION_ICON)),
|
||||
RibbonItem::LargeTool(tool("SUBTRACT", "Subtract", SUBTRACT_ICON)),
|
||||
RibbonItem::LargeTool(tool("INTERSECT", "Intersect", INTERSECT_ICON)),
|
||||
],
|
||||
},
|
||||
]
|
||||
fn ribbon_groups(&self) -> &[RibbonGroup] {
|
||||
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
|
||||
GROUPS.get_or_init(|| {
|
||||
vec![
|
||||
RibbonGroup {
|
||||
title: "Model",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool("BOX", "Box", BOX_ICON)),
|
||||
RibbonItem::LargeTool(tool("CYLINDER", "Cylinder", CYLINDER_ICON)),
|
||||
RibbonItem::LargeTool(tool("CONE", "Cone", CONE_ICON)),
|
||||
RibbonItem::LargeTool(tool("SPHERE", "Sphere", SPHERE_ICON)),
|
||||
RibbonItem::Dropdown {
|
||||
id: "MODEL_MORE",
|
||||
icon: IconKind::Svg(WEDGE_ICON),
|
||||
items: vec![
|
||||
("WEDGE", "Wedge", IconKind::Svg(WEDGE_ICON)),
|
||||
("TORUS", "Torus", IconKind::Svg(TORUS_ICON)),
|
||||
],
|
||||
default: "WEDGE",
|
||||
},
|
||||
],
|
||||
},
|
||||
RibbonGroup {
|
||||
title: "Design",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool("UNION", "Union", UNION_ICON)),
|
||||
RibbonItem::LargeTool(tool("SUBTRACT", "Subtract", SUBTRACT_ICON)),
|
||||
RibbonItem::LargeTool(tool("INTERSECT", "Intersect", INTERSECT_ICON)),
|
||||
],
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
+93
-90
@@ -45,96 +45,99 @@ impl CadModule for ViewModule {
|
||||
"View"
|
||||
}
|
||||
|
||||
fn ribbon_groups(&self) -> Vec<RibbonGroup> {
|
||||
vec![
|
||||
// ── Viewport Tools ───────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Viewport Tools",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(ucs_icon::tool()),
|
||||
RibbonItem::LargeTool(viewcube::tool()),
|
||||
],
|
||||
},
|
||||
// ── Navigate ─────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Navigate",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(zoom_ext::tool()),
|
||||
RibbonItem::Tool(zoom_window::tool()),
|
||||
RibbonItem::Tool(zoom_in::tool()),
|
||||
RibbonItem::Tool(zoom_out::tool()),
|
||||
RibbonItem::Tool(pan::tool()),
|
||||
RibbonItem::Tool(orbit::tool()),
|
||||
],
|
||||
},
|
||||
// ── Model Viewports ───────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Model Viewports",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(vports_config::tool()),
|
||||
RibbonItem::Tool(vports_named::tool()),
|
||||
RibbonItem::Tool(vports_join::tool()),
|
||||
RibbonItem::Tool(vports_restore::tool()),
|
||||
],
|
||||
},
|
||||
// ── Visual Style ──────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
// WIREFRAME and SOLID ids are special-cased in ribbon.rs
|
||||
// for toggle-state highlighting based on Ribbon::wireframe.
|
||||
title: "Visual Style",
|
||||
tools: vec![RibbonItem::LargeDropdown {
|
||||
id: "VISUAL_STYLE",
|
||||
label: "Visual\nStyle",
|
||||
icon: wireframe::tool().icon,
|
||||
items: vec![
|
||||
("WIREFRAME", "Wireframe", wireframe::tool().icon),
|
||||
("SOLID", "Shaded", solid::tool().icon),
|
||||
("HIDDEN", "Hidden", hidden::tool().icon),
|
||||
("XRAY", "X-Ray", xray::tool().icon),
|
||||
fn ribbon_groups(&self) -> &[RibbonGroup] {
|
||||
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
|
||||
GROUPS.get_or_init(|| {
|
||||
vec![
|
||||
// ── Viewport Tools ───────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Viewport Tools",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(ucs_icon::tool()),
|
||||
RibbonItem::LargeTool(viewcube::tool()),
|
||||
],
|
||||
default: "WIREFRAME",
|
||||
}],
|
||||
},
|
||||
// ── Projection ────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
// ORTHO and PERSP ids are special-cased in ribbon.rs
|
||||
// for toggle-state highlighting based on Camera::projection.
|
||||
title: "Projection",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(ortho::tool()),
|
||||
RibbonItem::LargeTool(persp::tool()),
|
||||
],
|
||||
},
|
||||
// ── Preset Views ──────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Preset",
|
||||
tools: vec![
|
||||
RibbonItem::Tool(view_top::tool()),
|
||||
RibbonItem::Tool(view_front::tool()),
|
||||
RibbonItem::Tool(view_right::tool()),
|
||||
RibbonItem::Tool(view_iso::tool()),
|
||||
],
|
||||
},
|
||||
// ── Palettes ──────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Palettes",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool_palettes::tool()),
|
||||
RibbonItem::LargeTool(properties_palette::tool()),
|
||||
RibbonItem::LargeTool(sheetset::tool()),
|
||||
],
|
||||
},
|
||||
// ── Interface ─────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Interface",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(file_tabs::tool()),
|
||||
RibbonItem::LargeTool(layout_tabs::tool()),
|
||||
RibbonItem::Tool(tile_horiz::tool()),
|
||||
RibbonItem::Tool(tile_vert::tool()),
|
||||
RibbonItem::Tool(cascade::tool()),
|
||||
],
|
||||
},
|
||||
]
|
||||
},
|
||||
// ── Navigate ─────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Navigate",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(zoom_ext::tool()),
|
||||
RibbonItem::Tool(zoom_window::tool()),
|
||||
RibbonItem::Tool(zoom_in::tool()),
|
||||
RibbonItem::Tool(zoom_out::tool()),
|
||||
RibbonItem::Tool(pan::tool()),
|
||||
RibbonItem::Tool(orbit::tool()),
|
||||
],
|
||||
},
|
||||
// ── Model Viewports ───────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Model Viewports",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(vports_config::tool()),
|
||||
RibbonItem::Tool(vports_named::tool()),
|
||||
RibbonItem::Tool(vports_join::tool()),
|
||||
RibbonItem::Tool(vports_restore::tool()),
|
||||
],
|
||||
},
|
||||
// ── Visual Style ──────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
// WIREFRAME and SOLID ids are special-cased in ribbon.rs
|
||||
// for toggle-state highlighting based on Ribbon::wireframe.
|
||||
title: "Visual Style",
|
||||
tools: vec![RibbonItem::LargeDropdown {
|
||||
id: "VISUAL_STYLE",
|
||||
label: "Visual\nStyle",
|
||||
icon: wireframe::tool().icon,
|
||||
items: vec![
|
||||
("WIREFRAME", "Wireframe", wireframe::tool().icon),
|
||||
("SOLID", "Shaded", solid::tool().icon),
|
||||
("HIDDEN", "Hidden", hidden::tool().icon),
|
||||
("XRAY", "X-Ray", xray::tool().icon),
|
||||
],
|
||||
default: "WIREFRAME",
|
||||
}],
|
||||
},
|
||||
// ── Projection ────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
// ORTHO and PERSP ids are special-cased in ribbon.rs
|
||||
// for toggle-state highlighting based on Camera::projection.
|
||||
title: "Projection",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(ortho::tool()),
|
||||
RibbonItem::LargeTool(persp::tool()),
|
||||
],
|
||||
},
|
||||
// ── Preset Views ──────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Preset",
|
||||
tools: vec![
|
||||
RibbonItem::Tool(view_top::tool()),
|
||||
RibbonItem::Tool(view_front::tool()),
|
||||
RibbonItem::Tool(view_right::tool()),
|
||||
RibbonItem::Tool(view_iso::tool()),
|
||||
],
|
||||
},
|
||||
// ── Palettes ──────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Palettes",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool_palettes::tool()),
|
||||
RibbonItem::LargeTool(properties_palette::tool()),
|
||||
RibbonItem::LargeTool(sheetset::tool()),
|
||||
],
|
||||
},
|
||||
// ── Interface ─────────────────────────────────────────────────────
|
||||
RibbonGroup {
|
||||
title: "Interface",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(file_tabs::tool()),
|
||||
RibbonItem::LargeTool(layout_tabs::tool()),
|
||||
RibbonItem::Tool(tile_horiz::tool()),
|
||||
RibbonItem::Tool(tile_vert::tool()),
|
||||
RibbonItem::Tool(cascade::tool()),
|
||||
],
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user