• 【rust/egui】(十)使用painter绘制一些图形—connections


    说在前面

    • 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);
      
      • 1
      • 2
      • 3
      • 4
      结果如下:
      在这里插入图片描述
    • 上述代码同时返回了拖拽事件,然后我们就需要对拖拽事件进行处理,进而在连接点与鼠标光标之间绘制一条线,以下是绘制函数:
      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));
      
      • 1
      • 2
      • 3
    • 同时,这个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);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 最终的结果如下
      在这里插入图片描述

    建立连接

    • 如果有多个方块,那我们就可以将方块连接起来,这里为了简化,我们将另一个方块只保留连接点:
      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,
      );
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      在这里插入图片描述
    • 然后,我们需要在将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,
          );
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      结果如下
      在这里插入图片描述

    参考

  • 相关阅读:
    MyCat简介与安装
    LeetCode 45. 跳跃游戏 II
    Java常用基础知识点
    生产者、消费者问题
    Element 2 组件源码剖析之布局容器
    【AI核心能力】第2讲 机器学习初探
    卷积神经网络信号处理,卷积神经网络应用领域
    python学习主要应该学些什么
    Linux dts list python tool
    【 安全】什么是CSRF攻击?如何避免?开发的时候怎么预防?
  • 原文地址:https://blog.csdn.net/qq_33446100/article/details/132792406