Skip to content

Commit 1725d8f

Browse files
committed
feat: add Edge connection element and update RenderContext
1 parent 06c359e commit 1725d8f

5 files changed

Lines changed: 93 additions & 1 deletion

File tree

crates/project_graph/src/stage.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ impl Stage {
5656
zoom: self.camera.zoom(),
5757
selected,
5858
clicked: false,
59+
painter: painter.clone(),
60+
screen_center,
5961
};
6062

6163
let element_size = element.world_rect().size() * self.camera.zoom();

crates/project_graph/src/stage/elements.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ pub mod entities;
44

55
use enum_dispatch::enum_dispatch;
66

7-
use crate::stage::{elements::entities::Entity, render_context::RenderContext};
7+
use crate::stage::{
8+
elements::{connections::Connection, entities::Entity},
9+
render_context::RenderContext,
10+
};
811

912
/// 元素,以前称做舞台对象
1013
/// 所有可以被渲染的东西都应该实现这个 trait
@@ -22,4 +25,5 @@ pub trait ElementTrait {
2225
#[derive(knus::Decode, Debug, Clone)]
2326
pub enum Element {
2427
Entity(Entity),
28+
Connection(Connection),
2529
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
1+
pub mod edge;
2+
13
use crate::stage::elements::ElementTrait;
4+
pub use edge::Edge;
5+
use enum_dispatch::enum_dispatch;
26

37
/// 连接关系,连接节点端口的线段
48
/// 不能被包含,不能被连接
9+
#[enum_dispatch]
510
pub trait ConnectionTrait: ElementTrait {
611
/// 起点端口 id
712
fn from_port_id(&self) -> &str;
813
/// 终点端口 id
914
fn to_port_id(&self) -> &str;
1015
}
16+
17+
#[enum_dispatch(ConnectionTrait, ElementTrait)]
18+
#[derive(knus::Decode, Debug, Clone)]
19+
pub enum Connection {
20+
Edge(Edge),
21+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use nanoid::nanoid;
2+
use crate::stage::{
3+
elements::{ElementTrait, connections::ConnectionTrait, entities::EntityTrait},
4+
render_context::RenderContext,
5+
};
6+
7+
#[derive(knus::Decode, Debug, Clone)]
8+
pub struct Edge {
9+
#[knus(argument, default = nanoid!())]
10+
id: String,
11+
#[knus(child, unwrap(argument))]
12+
from: String,
13+
#[knus(child, unwrap(argument))]
14+
to: String,
15+
}
16+
17+
impl Edge {
18+
pub fn new(id: String, from: String, to: String) -> Self {
19+
Self { id, from, to }
20+
}
21+
}
22+
23+
impl ElementTrait for Edge {
24+
fn id(&self) -> &str {
25+
&self.id
26+
}
27+
28+
fn ui(&self, _ui: &mut egui::Ui, rc: &mut RenderContext) {
29+
// 暂存简单的线段和箭头绘制逻辑
30+
// 由于当前架构下 Element::ui 无法直接访问 StageContext 查找 from/to 节点的 Position
31+
// 我们这里先写好绘制逻辑,假设我们有了两个点
32+
}
33+
34+
fn world_rect(&self) -> egui::Rect {
35+
egui::Rect::NOTHING
36+
}
37+
}
38+
39+
impl Edge {
40+
/// 辅助函数:绘制带箭头的线段
41+
pub fn draw_arrow(painter: &egui::Painter, start: egui::Pos2, end: egui::Pos2, stroke: egui::Stroke) {
42+
painter.line_segment([start, end], stroke);
43+
44+
let vec = end - start;
45+
let mag = vec.length();
46+
if mag > 0.0 {
47+
let dir = vec / mag;
48+
let tip_size = 10.0 * stroke.width / 2.0; // 随粗细缩放
49+
let side_dir = egui::vec2(dir.y, -dir.x);
50+
51+
let p1 = end - dir * tip_size + side_dir * tip_size * 0.5;
52+
let p2 = end - dir * tip_size - side_dir * tip_size * 0.5;
53+
54+
painter.add(egui::Shape::convex_polygon(
55+
vec![end, p1, p2],
56+
stroke.color,
57+
egui::Stroke::NONE,
58+
));
59+
}
60+
}
61+
}
62+
63+
impl ConnectionTrait for Edge {
64+
fn from_port_id(&self) -> &str {
65+
&self.from
66+
}
67+
68+
fn to_port_id(&self) -> &str {
69+
&self.to
70+
}
71+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
use egui::Pos2;
2+
13
pub struct RenderContext {
24
pub zoom: f32,
35
pub selected: bool,
46
pub clicked: bool,
7+
pub painter: egui::Painter,
8+
pub screen_center: Pos2,
59
}
610

711
impl RenderContext {}

0 commit comments

Comments
 (0)