forked from 1b-agent/opencadstudio-upstream
fix(web): render UI icons as SVG instead of font glyphs
UI chrome (dropdown carets, undo/redo, checkmarks, close/menu/osnap, layer/file-menu icons) and ribbon tool icons were drawn as Unicode glyphs. Desktop fills missing glyphs via system-font fallback, but the web build bundles only Fira Sans with no fallback, so they rendered as empty tofu boxes (issue #116). Add a shared src/ui/icons.rs (SVG-backed, tintable) plus bundled assets, and switch every glyph site and IconKind::Glyph tool def to SVG. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
4954551808
commit
864dd6cef7
81 files changed
+782
-372
No files matched your search
@@ -193,25 +193,33 @@ impl CadModule for AnnotateModule {
|
||||
RibbonItem::Tool(crate::modules::ToolDef {
|
||||
id: "ANNOSCALE",
|
||||
label: "Scale List",
|
||||
icon: crate::modules::IconKind::Glyph("⬡"),
|
||||
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::Glyph("⊕"),
|
||||
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::Glyph("≡"),
|
||||
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::Glyph("⇄"),
|
||||
icon: crate::modules::IconKind::Svg(include_bytes!(
|
||||
"../../../assets/icons/sync.svg"
|
||||
)),
|
||||
event: crate::modules::ModuleEvent::Command("SYNCPVIEWPORTS".to_string()),
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -7,7 +7,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "COLOR",
|
||||
label: "Color",
|
||||
icon: IconKind::Glyph("🎨"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../../assets/icons/color_palette.svg")),
|
||||
event: ModuleEvent::Command("COLOR".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "BYLAYER",
|
||||
label: "ByLayer",
|
||||
icon: IconKind::Glyph("⊟"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../../assets/icons/bylayer.svg")),
|
||||
event: ModuleEvent::Command("BYLAYER".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "BOX",
|
||||
label: "Box",
|
||||
icon: IconKind::Glyph("⬜"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/box3d.svg")),
|
||||
event: ModuleEvent::Command("BOX".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "CLEAR",
|
||||
label: "Clear",
|
||||
icon: IconKind::Glyph("🗑"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/clear_tool.svg")),
|
||||
event: ModuleEvent::ClearModels,
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "CYLINDER",
|
||||
label: "Cylinder",
|
||||
icon: IconKind::Glyph("⬡"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/cylinder3d.svg")),
|
||||
event: ModuleEvent::Command("CYLINDER".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "OPEN",
|
||||
label: "Open",
|
||||
icon: IconKind::Glyph("📂"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/import_obj.svg")),
|
||||
event: ModuleEvent::OpenFileDialog,
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "SPHERE",
|
||||
label: "Sphere",
|
||||
icon: IconKind::Glyph("⬤"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/sphere3d.svg")),
|
||||
event: ModuleEvent::Command("SPHERE".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,13 @@ pub fn paper_space_tools() -> Vec<ToolDef> {
|
||||
ToolDef {
|
||||
id: "PAGESETUP",
|
||||
label: "Page Setup",
|
||||
icon: IconKind::Glyph("📋"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/pagesetup.svg")),
|
||||
event: ModuleEvent::Command("PAGESETUP".to_string()),
|
||||
},
|
||||
ToolDef {
|
||||
id: "PLOT",
|
||||
label: "Export PDF",
|
||||
icon: IconKind::Glyph("🖨"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/plot.svg")),
|
||||
event: ModuleEvent::Command("PLOT".to_string()),
|
||||
},
|
||||
]
|
||||
@@ -48,14 +48,14 @@ impl CadModule for LayoutModule {
|
||||
ToolDef {
|
||||
id: "PAGESETUP",
|
||||
label: "Page Setup",
|
||||
icon: IconKind::Glyph("📋"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/pagesetup.svg")),
|
||||
event: ModuleEvent::Command("PAGESETUP".to_string()),
|
||||
}
|
||||
.into(),
|
||||
ToolDef {
|
||||
id: "PLOT",
|
||||
label: "Export PDF",
|
||||
icon: IconKind::Glyph("🖨"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/plot.svg")),
|
||||
event: ModuleEvent::Command("PLOT".to_string()),
|
||||
}
|
||||
.into(),
|
||||
|
||||
@@ -19,7 +19,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "MVIEW",
|
||||
label: "Viewport",
|
||||
icon: IconKind::Glyph("⬜"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/viewport.svg")),
|
||||
event: ModuleEvent::Command("MVIEW".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "MVIEW",
|
||||
label: "Viewport",
|
||||
icon: IconKind::Glyph("⬜"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/viewport.svg")),
|
||||
event: ModuleEvent::Command("MVIEW".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ pub fn tool() -> ToolDef {
|
||||
ToolDef {
|
||||
id: "OPTIONS",
|
||||
label: "Options",
|
||||
icon: IconKind::Glyph("⚙"),
|
||||
icon: IconKind::Svg(include_bytes!("../../../assets/icons/options_tool.svg")),
|
||||
event: ModuleEvent::Command("OPTIONS".to_string()),
|
||||
}
|
||||
}
|
||||
+22
-12
@@ -12,12 +12,22 @@ use crate::modules::{CadModule, IconKind, ModuleEvent, RibbonGroup, RibbonItem,
|
||||
|
||||
pub struct ModelModule;
|
||||
|
||||
const BOX_ICON: &[u8] = include_bytes!("../../../assets/icons/box3d.svg");
|
||||
const CYLINDER_ICON: &[u8] = include_bytes!("../../../assets/icons/cylinder3d.svg");
|
||||
const CONE_ICON: &[u8] = include_bytes!("../../../assets/icons/cone3d.svg");
|
||||
const SPHERE_ICON: &[u8] = include_bytes!("../../../assets/icons/sphere3d.svg");
|
||||
const WEDGE_ICON: &[u8] = include_bytes!("../../../assets/icons/wedge3d.svg");
|
||||
const TORUS_ICON: &[u8] = include_bytes!("../../../assets/icons/torus3d.svg");
|
||||
const UNION_ICON: &[u8] = include_bytes!("../../../assets/icons/union.svg");
|
||||
const SUBTRACT_ICON: &[u8] = include_bytes!("../../../assets/icons/subtract.svg");
|
||||
const INTERSECT_ICON: &[u8] = include_bytes!("../../../assets/icons/intersect.svg");
|
||||
|
||||
/// Helper to declare a ribbon tool that fires a named command.
|
||||
fn tool(id: &'static str, label: &'static str, glyph: &'static str) -> ToolDef {
|
||||
fn tool(id: &'static str, label: &'static str, icon: &'static [u8]) -> ToolDef {
|
||||
ToolDef {
|
||||
id,
|
||||
label,
|
||||
icon: IconKind::Glyph(glyph),
|
||||
icon: IconKind::Svg(icon),
|
||||
event: ModuleEvent::Command(id.to_string()),
|
||||
}
|
||||
}
|
||||
@@ -35,16 +45,16 @@ impl CadModule for ModelModule {
|
||||
RibbonGroup {
|
||||
title: "Model",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool("BOX", "Box", "▦")),
|
||||
RibbonItem::LargeTool(tool("CYLINDER", "Cylinder", "⬭")),
|
||||
RibbonItem::LargeTool(tool("CONE", "Cone", "△")),
|
||||
RibbonItem::LargeTool(tool("SPHERE", "Sphere", "◯")),
|
||||
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::Glyph("◰"),
|
||||
icon: IconKind::Svg(WEDGE_ICON),
|
||||
items: vec![
|
||||
("WEDGE", "Wedge", IconKind::Glyph("◣")),
|
||||
("TORUS", "Torus", IconKind::Glyph("◎")),
|
||||
("WEDGE", "Wedge", IconKind::Svg(WEDGE_ICON)),
|
||||
("TORUS", "Torus", IconKind::Svg(TORUS_ICON)),
|
||||
],
|
||||
default: "WEDGE",
|
||||
},
|
||||
@@ -53,9 +63,9 @@ impl CadModule for ModelModule {
|
||||
RibbonGroup {
|
||||
title: "Design",
|
||||
tools: vec![
|
||||
RibbonItem::LargeTool(tool("UNION", "Union", "⊕")),
|
||||
RibbonItem::LargeTool(tool("SUBTRACT", "Subtract", "⊖")),
|
||||
RibbonItem::LargeTool(tool("INTERSECT", "Intersect", "⊗")),
|
||||
RibbonItem::LargeTool(tool("UNION", "Union", UNION_ICON)),
|
||||
RibbonItem::LargeTool(tool("SUBTRACT", "Subtract", SUBTRACT_ICON)),
|
||||
RibbonItem::LargeTool(tool("INTERSECT", "Intersect", INTERSECT_ICON)),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user