- 在上一节我们使用
painter绘制了一个可以拖拽的小方块,现在我们来用painter将两个小方块连接起来,类似这种:

- 首先我们需要在我们的方块上添加一个连接点,这是为了区分方块本体和连接点之间的拖拽事件:
let port_rect = egui::Rect::from_center_size(body_rect.min, egui::vec2(10.0, 10.0));
let port_resp = ui.allocate_rect(port_rect, egui::Sense::click_and_drag());
ui.painter()
.circle(port_rect.center(), 5.0, egui::Color32::BLUE, egui::Stroke::NONE);
结果如下:

- 上述代码同时返回了拖拽事件,然后我们就需要对拖拽事件进行处理,进而在连接点与鼠标光标之间绘制一条线,以下是绘制函数:
fn draw_connection(painter: &egui::Painter, src_pos: egui::Pos2, dst_pos: egui::Pos2, color: egui::Color32) {
let connection_stroke = egui::Stroke { width: 5.0, color };
let control_scale = ((dst_pos.x - src_pos.x) / 2.0).max(30.0);
let src_control = src_pos + egui::Vec2::X * control_scale;
let dst_control = dst_pos - egui::Vec2::X * control_scale;
let bezier = egui::epaint::CubicBezierShape::from_points_stroke(
[src_pos, src_control, dst_control, dst_pos],
false,
egui::Color32::TRANSPARENT,
connection_stroke,
);
painter.add(bezier);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 所以我们的目标是确定
connection的起点和终点,起点自然是方块的连接点,终点则是光标的位置:let cursor_pos = ui
.ctx()
.input(|i| i.pointer.hover_pos().unwrap_or(egui::Pos2::ZERO));
- 同时,这个
connection只有在我们开始拖拽,以及拖拽过程中才会有:if port_resp.drag_started() {
self.in_drag_port = true;
} else if port_resp.drag_released() {
self.in_drag_port = false;
}
if self.in_drag_port {
draw_connection(ui.painter(), cursor_pos,port_rect.center(), egui::Color32::BROWN);
}
- 最终的结果如下
