说在前面
- rust新手,egui没啥找到啥教程,这里自己记录下学习过程
- 环境:windows11 22H2
- rust版本:rustc 1.71.1
- egui版本:0.22.0
- eframe版本:0.22.0
- 上一篇:这里
绘制连接
- 在上一节我们使用
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); }
- 所以我们的目标是确定
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); }
- 最终的结果如下
建立连接
- 如果有多个方块,那我们就可以将方块连接起来,这里为了简化,我们将另一个方块只保留连接点:
let fix_port_rect = egui::Rect::from_center_size(egui::pos2(500.0, 500.0), egui::vec2(10.0, 10.0)); ui.painter().circle( fix_port_rect.center(), 5.0, egui::Color32::GRAY, egui::Stroke::NONE, );
- 然后,我们需要在将
connection
的终点接近固定点
后,将连接状态记录下来,这样就可以在之后的update
中,通过这个连接状态把connection
绘制出来
结果如下if port_resp.drag_started() { self.in_drag_port = true; // 方块连接点拖拽开始时将连接取消 self.connected = false; } else if port_resp.drag_released() { self.in_drag_port = false; // 如果光标足够接近固定点时,建立连接,记录状态 self.connected = if let Some(pointer_pos) = ui.ctx().pointer_hover_pos() { fix_port_rect.center().distance(pointer_pos) < 10.0 } else { false }; } // 如果建立了连接 直接绘制 if self.connected { draw_connection( ui.painter(), fix_port_rect.center(), port_rect.center(), egui::Color32::BROWN, ); }
参考
- egui_node_graph
文章来源地址https://www.toymoban.com/news/detail-709091.html
文章来源:https://www.toymoban.com/news/detail-709091.html
到了这里,关于【rust/egui】(十)使用painter绘制一些图形—connections的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!