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

news2025/1/17 15:57:11

说在前面

  • 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/997913.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《深度学习初探:使用TensorFlow和Keras构建你的第一个神经网络》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

GCP之Google Cloud Infrastructure

Google Cloud 的物理网络是如何连接的&#xff1f; Google Cloud 分为 regions&#xff0c;regions 又分为 zones。 region 是一个地理区域&#xff0c;其中一个 VM 到另一个 VM 的往返时间 &#xff08;RTT&#xff09; 通常小于 1毫秒&#xff1b;zone 是 region 中的部署区…

canvas基础笔记

一、简介 Canvas是HTML5中的一个元素&#xff0c;它提供了一个可以使用JavaScript绘制图形的区域。它提供了一个强大的绘图API&#xff0c;可以用于创建各种图形&#xff0c;包括线条、矩形、圆形、文本等 Canvas 是 HTML5 中的一个元素&#xff0c;用于绘制图形、动画和图像。…

架构核心技术之微服务架构

小熊学Java&#xff1a;https://www.javaxiaobear.cn/&#xff0c;文末有免费资源 本文我们来学习微服务的架构设计 主要包括如下内容。 单体系统的困难&#xff1a;编译部署困难、数据库连接耗尽、服务复用困难、新增业务困难。 微服务框架&#xff1a;Dubbo 和 Spring Clou…

sdkman 的安装配置与 sdk 管理

sdkman 的安装配置与 sdk 管理 记录一下项目使用的工具&#xff0c;目前环境的管理有以下几个&#xff1a; sdkmanpyenvnvm 这里主要讲一下 sdkman&#xff0c;我们项目是通过 sdkman 进行 java 和 maven 的管理&#xff0c;这个写的挺简单的&#xff0c;加上一个自己写的自…

unipush2.0实现APP消息推送(2)云函数多个方法的创建与使用

问题&#xff1a;上篇文章我们已经介绍到了unipush2.0消息推送的实现思路&#xff0c;但是遇到一个问题就是如何在一个云函数里写多个方法供传统服务端调用&#xff1f; 这样做的目的&#xff1a;这样传统服务端就可以调用一个云函数url路径传递不同的参数标识走不同的方法了 …

uni-app--》基于小程序开发的电商平台项目实战(一)

&#x1f3cd;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名在校大学生 &#x1f6f5;个人主页&#xff1a;亦世凡华、 &#x1f6fa;系列专栏&#xff1a;uni-app &#x1f6b2;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

《AI一键生成抖音商品种草文案》让你秒变带货王!

在这个数字化的时代&#xff0c;我们的生活被各种应用所包围&#xff0c;其中&#xff0c;抖音作为一款短视频分享平台&#xff0c;已经成为了我们生活中不可或缺的一部分。然而&#xff0c;作为一名抖音创作者&#xff0c;你是否曾经遇到过这样的困扰&#xff1a;在创作商品种…

Linux C : select简介和epoll 实现

目录 一、基础知识 二、select 模型服务流程 二、select 模式的缺点。 三、poll 概要 四、epoll 服务端实现流程 1.epoll_create&#xff1a; 2.epoll_ctl 3.epoll_wait 五、epoll示例代码实现 1.epoll实现服务端 2.客户端采用tcp进行访问 一、基础知识 首先要知道&…

flink的几种常见的执行模式

背景 在运行flink时&#xff0c;我们经常会有几种不同的执行模式&#xff0c;比如在IDE中启动时&#xff0c;通过提交到YARN上&#xff0c;还有通过Kebernates启动时&#xff0c;本文就来记录一下这几种模式 flink的几种执行模式 flink嵌入式模式&#xff1a; 这是一种我们在…

基于keras中Lenet对于mnist的处理

文章目录 MNIST导入必要的包加载数据可视化数据集查看数据集的分布开始训练画出loss图画出accuracy图 使用数据外的图来测试图片可视化转化灰度图的可视化可视化卷积层的特征图第一层卷积 conv1 和 pool1第二层卷积 conv2 和 pool2 MNIST MNIST&#xff08;Modified National …

从零开始的PICO教程(4)--- UI界面绘制与响应事件

从零开始的PICO教程&#xff08;4&#xff09;— UI界面绘制与响应事件 文章目录 从零开始的PICO教程&#xff08;4&#xff09;--- UI界面绘制与响应事件一、前言1、大纲2、教程示例 二、具体步骤1、PICO VR环境配置2、XR的UI Canvas画布创建与调整&#xff08;1&#xff09;C…

【雷达原理】雷达信号级建模与仿真

目录 前言一、LFMCW信号概述1.1 优点1.2 缺点 二、LFMCW信号模型2.1 发射信号模型2.2 接收信号模型2.3 信号混频 三、MATLAB仿真3.1 仿真结果3.2 代码 四、参考文献 前言 雷达信号形式多种多样&#xff0c;按照雷达的体制进行分类&#xff0c;有脉冲雷达和连续波雷达。脉冲雷达…

C#程序到底从哪里开始看,从Main函数开始,那么Main函数是什么?

视觉人机器视觉粉丝问我,拿到自己公司得架构,问我,C#程序到底从哪里看,从Main函数开始,那么Main函数是什么? Main()函数 Main()是C#应用程序的入口点,执行这个函数就是执行应用程序。也就是说,在执行过程开始时,会执行Main()函数,在Main()函数执行完毕时,执行过…

微信小程序上拉触底事件

一、什么是上拉触底事件 上拉触底是移动端的专有名词&#xff0c;通过手指在屏幕上的上拉滑动操作&#xff0c;从而加载更多数据的行为。 二、监听上拉触底事件 在页面的.js文件中&#xff0c;通过onReachBottom()函数即可监听当前页面的上拉触底事件。 三、配置上拉触底距…

vue组件库开发,webpack打包,发布npm

做一个像elment-ui一样的vue组件库 那多好啊&#xff01;这是我前几年就想做的 但webpack真的太难用&#xff0c;也许是我功力不够 今天看到一个视频&#xff0c;早上6-13点&#xff0c;终于实现了&#xff0c;呜呜 感谢视频的分享-来龙去脉-大家可以看这个视频&#xff1a;htt…

【List篇】ArrayList 的线程不安全介绍

ArrayList 为什么线程不安全&#xff1f; 主要原因是ArrayList是非同步的,没有同步机制,并且其底层实现是基于数组&#xff0c;而数组的长度是固定的。当对 ArrayList 进行增删操作时&#xff0c;需要改变数组的长度&#xff0c;这就会导致多个线程可能同时操作同一个数组&…

Unlikely argument type for equals(): int seems to be unrelated to String

前面字符串 后面数值 if (new Integer(2).equals(loginUser.getStatus())) 或者另外定义一个吧

JAVASE 窗口

本文目录 1、前言2、JFrame、JButton3、JLabl4、ImageIcon 1、前言 java提供了很多已经写好了的类供我们使用&#xff0c;而我们没必要去细腻研究它的构成原理&#xff0c;就好比我们让我们编程让机器人动起来&#xff0c;没必要细腻研究机器人每个器件是怎么做出来的一样&…

Qt Designer UI设计布局小结

目录 前言1 居中布局2 左右布局3 上下布局4 复杂页面布局总结 前言 本文总结了在开发Qt应用程序时使用 Designer 进行UI布局的一些心得体会。Qt Designer是Qt提供的一个可视化界面设计工具&#xff0c;旨在帮助开发人员快速创建和布局用户界面。它提供了丰富的布局管理器和控件…