feat(svg-editor): implement interactive SVG node editor with parsing and editing capabilities

feat(debug-logger): add DebugSignalLogger plugin for event logging and inspection

feat(plugins): introduce built-in plugins module and integrate debug logger

feat(plugin-integration): create integration layer for mapping Iced Messages to CoreEvents

feat(plugin-registry): establish PluginRegistry for managing plugins and event dispatching
This commit is contained in:
2026-07-20 01:43:22 +03:00
parent 6e0d179be9
commit 2fb47520b3
46 changed files with 4093 additions and 314 deletions
@@ -208,6 +208,7 @@ pub fn execute_actions(engine: &mut Engine, actions: &[ScriptAction]) {
255,
];
engine.add_vector_shape(hcie_engine_api::VectorShape::FreePath {
name: String::new(),
pts: path_points,
closed: *closed,
stroke: *stroke_width,
@@ -201,6 +201,7 @@ pub fn load_hcie(path: &Path, engine: &mut Engine) -> Result<(u32, u32, String),
// Wait, if shapes is empty, add_vector_shape won't create the layer.
// We can add a dummy line shape with opacity 0.0 to create a Vector layer.
let dummy = VectorShape::Line {
name: String::new(),
x1: 0.0,
y1: 0.0,
x2: 0.0,
@@ -731,6 +731,7 @@ fn parse_svg_shapes(svg_bytes: &[u8], scale_x: f32, scale_y: f32) -> Vec<VectorS
* scale_y;
if w > 0.0 && h > 0.0 {
shapes.push(VectorShape::Rect {
name: String::new(),
x1: x,
y1: y,
x2: x + w,
@@ -766,6 +767,7 @@ fn parse_svg_shapes(svg_bytes: &[u8], scale_x: f32, scale_y: f32) -> Vec<VectorS
* scale_x;
if r > 0.0 {
shapes.push(VectorShape::Circle {
name: String::new(),
x1: cx - r,
y1: cy - r,
x2: cx + r,
@@ -805,6 +807,7 @@ fn parse_svg_shapes(svg_bytes: &[u8], scale_x: f32, scale_y: f32) -> Vec<VectorS
* scale_y;
if rx > 0.0 && ry > 0.0 {
shapes.push(VectorShape::Circle {
name: String::new(),
x1: cx - rx,
y1: cy - ry,
x2: cx + rx,
@@ -845,6 +848,7 @@ fn parse_svg_shapes(svg_bytes: &[u8], scale_x: f32, scale_y: f32) -> Vec<VectorS
+ ty)
* scale_y;
shapes.push(VectorShape::Line {
name: String::new(),
x1,
y1,
x2,
@@ -873,6 +877,7 @@ fn parse_svg_shapes(svg_bytes: &[u8], scale_x: f32, scale_y: f32) -> Vec<VectorS
}
if pts.len() >= 2 {
shapes.push(VectorShape::FreePath {
name: String::new(),
pts,
closed: tag == "polygon",
stroke: stroke_width,
@@ -10,6 +10,10 @@ use crate::app::ToolState;
use crate::event_bus::AppEvent;
fn shape_label(shapes: &[VectorShape], i: usize) -> String {
let name = shapes[i].name();
if !name.is_empty() {
return name;
}
match &shapes[i] {
VectorShape::Line { .. } => format!("Line #{}", i + 1),
VectorShape::Rect { .. } => format!("Rect #{}", i + 1),
@@ -2184,6 +2184,7 @@ fn create_shape_from_drag(
match tool {
Tool::VectorLine => VectorShape::Line {
name: String::new(),
x1,
y1,
x2,
@@ -2197,6 +2198,7 @@ fn create_shape_from_drag(
hardness,
},
Tool::VectorRect => VectorShape::Rect {
name: String::new(),
x1,
y1,
x2,
@@ -2211,6 +2213,7 @@ fn create_shape_from_drag(
hardness,
},
Tool::VectorCircle => VectorShape::Circle {
name: String::new(),
x1,
y1,
x2,
@@ -2228,7 +2231,7 @@ fn create_shape_from_drag(
p.insert("thick".to_string(), 0.0);
match hcie_engine_api::create_vector_shape("arrow", x1, y1, x2, y2, &p) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2240,13 +2243,14 @@ fn create_shape_from_drag(
p.insert("inner_radius".to_string(), state.tool_configs.vector.star_inner_radius);
match hcie_engine_api::create_vector_shape("star", x1, y1, x2, y2, &p) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
}
},
Tool::VectorPolygon => VectorShape::Polygon {
name: String::new(),
x1,
y1,
x2,
@@ -2263,7 +2267,7 @@ fn create_shape_from_drag(
Tool::VectorRhombus => {
match hcie_engine_api::create_vector_shape("rhombus", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2272,7 +2276,7 @@ fn create_shape_from_drag(
Tool::VectorCylinder => {
match hcie_engine_api::create_vector_shape("cylinder", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2281,7 +2285,7 @@ fn create_shape_from_drag(
Tool::VectorHeart => {
match hcie_engine_api::create_vector_shape("heart", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2290,7 +2294,7 @@ fn create_shape_from_drag(
Tool::VectorBubble => {
match hcie_engine_api::create_vector_shape("bubble", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2299,7 +2303,7 @@ fn create_shape_from_drag(
Tool::VectorGear => {
match hcie_engine_api::create_vector_shape("gear", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2308,7 +2312,7 @@ fn create_shape_from_drag(
Tool::VectorCross => {
match hcie_engine_api::create_vector_shape("cross", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2317,7 +2321,7 @@ fn create_shape_from_drag(
Tool::VectorCrescent => {
match hcie_engine_api::create_vector_shape("crescent", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2326,7 +2330,7 @@ fn create_shape_from_drag(
Tool::VectorBolt => {
match hcie_engine_api::create_vector_shape("bolt", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2335,7 +2339,7 @@ fn create_shape_from_drag(
Tool::VectorArrow4 => {
match hcie_engine_api::create_vector_shape("arrow4", x1, y1, x2, y2, &std::collections::HashMap::new()) {
VectorShape::SvgShape { kind, svg, .. } => VectorShape::SvgShape {
kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
name: String::new(), kind, svg, x1, y1, x2, y2, stroke, color, fill_color, fill,
angle: 0.0, opacity, hardness,
},
_ => unreachable!(),
@@ -2344,6 +2348,7 @@ fn create_shape_from_drag(
Tool::CustomShape(idx) => {
if let Some(entry) = catalog.get(idx) {
VectorShape::SvgShape {
name: String::new(),
x1, y1, x2, y2,
kind: entry.kind.clone(),
svg: entry.svg.clone(),
@@ -2353,6 +2358,7 @@ fn create_shape_from_drag(
} else {
// Fallback: empty SVG rectangle
VectorShape::SvgShape {
name: String::new(),
x1, y1, x2, y2,
kind: "custom".to_string(),
svg: r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1"><path d="M 0,0 L 1,0 L 1,1 L 0,1 Z"/></svg>"#.to_string(),
@@ -2362,6 +2368,7 @@ fn create_shape_from_drag(
}
},
_ => VectorShape::Line {
name: String::new(),
x1,
y1,
x2,