Skip to content

Commit 1b69b3b

Browse files
committed
feat: 支持选择节点
1 parent 6a64257 commit 1b69b3b

4 files changed

Lines changed: 49 additions & 11 deletions

File tree

crates/project_graph/src/stage.rs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub mod render_context;
55

66
use camera::Camera;
77
use context::StageContext;
8+
use egui::{Vec2, vec2};
89

910
use crate::stage::{
1011
elements::{Element, ElementTrait, entities::EntityTrait},
@@ -16,13 +17,15 @@ use crate::stage::{
1617
pub struct Stage {
1718
pub camera: Camera,
1819
pub context: StageContext,
20+
pub selection: Vec<String>,
1921
}
2022

2123
impl Stage {
2224
pub fn new() -> Self {
2325
Stage {
2426
camera: Camera::new(),
2527
context: StageContext::random(),
28+
selection: Vec::new(),
2629
}
2730
}
2831

@@ -46,20 +49,49 @@ impl Stage {
4649

4750
visible_count += 1;
4851

52+
let selected = self.selection.contains(&entity.id().to_string());
53+
4954
let screen_pos = self
5055
.camera
51-
.world_to_screen(entity.position(), screen_center);
56+
.world_to_screen(entity.position(), screen_center)
57+
- if selected {
58+
vec2(4.0, 4.0) * self.camera.zoom()
59+
} else {
60+
Vec2::ZERO
61+
};
5262

5363
egui::Area::new(ui.make_persistent_id(entity.id()))
5464
.order(egui::Order::Foreground)
5565
.fixed_pos(screen_pos)
5666
.show(ui.ctx(), |ui| {
57-
entity.ui(
58-
ui,
59-
&RenderContext {
60-
zoom: self.camera.zoom(),
61-
},
62-
);
67+
let response = egui::Frame::new()
68+
.inner_margin(4.0 * self.camera.zoom())
69+
.corner_radius(24.0 * self.camera.zoom())
70+
.stroke(if selected {
71+
egui::Stroke::new(
72+
4.0 * self.camera.zoom(),
73+
egui::Color32::LIGHT_BLUE,
74+
)
75+
} else {
76+
egui::Stroke::NONE
77+
})
78+
.show(ui, |ui| {
79+
entity.ui(
80+
ui,
81+
&mut RenderContext {
82+
zoom: self.camera.zoom(),
83+
selected: selected,
84+
},
85+
);
86+
})
87+
.response
88+
.interact(egui::Sense::click());
89+
90+
if response.clicked() {
91+
log::info!("Entity {} clicked", entity.id());
92+
self.selection.clear();
93+
self.selection.push(entity.id().to_string());
94+
}
6395
});
6496
}
6597

crates/project_graph/src/stage/elements.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub trait ElementTrait {
1313
/// 原则上应该是一个 nanoid
1414
fn id(&self) -> &str;
1515
/// 渲染函数
16-
fn ui(&self, ui: &mut egui::Ui, rc: &RenderContext);
16+
fn ui(&self, ui: &mut egui::Ui, rc: &mut RenderContext);
1717
}
1818

1919
#[enum_dispatch(ElementTrait)]

crates/project_graph/src/stage/elements/entities/text.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@ impl ElementTrait for Text {
3131
fn id(&self) -> &str {
3232
&self.id
3333
}
34-
fn ui(&self, ui: &mut egui::Ui, rc: &RenderContext) {
34+
fn ui(&self, ui: &mut egui::Ui, rc: &mut RenderContext) {
3535
let response = egui::Frame::new()
36-
.fill(egui::Color32::from_rgba_unmultiplied(255, 255, 255, 25))
36+
.fill(if rc.selected {
37+
egui::Color32::from_rgba_unmultiplied(150, 150, 255, 75)
38+
} else {
39+
egui::Color32::from_rgba_unmultiplied(255, 255, 255, 25)
40+
})
3741
.corner_radius(16.0 * rc.zoom)
3842
.inner_margin(egui::Margin::symmetric(12, 10) * rc.zoom)
3943
.show(ui, |ui| {
@@ -42,7 +46,8 @@ impl ElementTrait for Text {
4246
.wrap_mode(egui::TextWrapMode::Extend),
4347
);
4448
})
45-
.response;
49+
.response
50+
.interact(egui::Sense::click());
4651
}
4752
}
4853
impl EntityTrait for Text {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub struct RenderContext {
22
pub zoom: f32,
3+
pub selected: bool,
34
}
45

56
impl RenderContext {}

0 commit comments

Comments
 (0)