Rust egui(3) 增加多个tab

话说不知道咋写,要不直接上git patch吧。代码都是移植的官方demo,核心改动就是把原来的line_demo换成了plot_demo,里面实现多个ui,然后点击tab标题会切换不同的ui。
如下图,Lines和Markers两个不同的标签对应不同的ui。
参考 https://crazyskady.github.io/index.html
在这里插入图片描述
直接上git diff吧。

Subject: [PATCH] A demo for adding a new ui in a panel

---
 eframe_test/src/app.rs | 140 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 135 insertions(+), 5 deletions(-)

diff --git a/eframe_test/src/app.rs b/eframe_test/src/app.rs
index a2a1351..57d8107 100644
--- a/eframe_test/src/app.rs
+++ b/eframe_test/src/app.rs
@@ -4,16 +4,71 @@ use egui::*;
 
 use egui_plot::{
     CoordinatesFormatter, Corner, Legend, Line, LineStyle, 
-    Plot, PlotPoints,
+    Plot, PlotPoints, MarkerShape, Points, // 增加所需的库
 };
 //定义一个Panel类型,用于包裹不同类型的ui
+#[derive(PartialEq, Eq)]
+enum Panel {
+    Lines,
+    Markers,
+}
+
+impl Default for Panel {
+    fn default() -> Self {
+        Self::Lines
+    }
+}
+
// 用PlotDemo替换原来的LineDemo,其中open_panel用于标记当前切换到了哪个ui
+#[derive(PartialEq, Default)]
+pub struct PlotDemo {
+    line_demo: LineDemo,
+    marker_demo: MarkerDemo,
+    open_panel: Panel,
+}
+
+impl PlotDemo {
+    fn ui(&mut self, ui: &mut Ui) {
+        ui.horizontal(|ui| {
+            egui::reset_button(ui, self);
+            ui.collapsing("Instructions", |ui| {
+                ui.label("Pan by dragging, or scroll (+ shift = horizontal).");
+                ui.label("Box zooming: Right click to zoom in and zoom out using a selection.");
+                if cfg!(target_arch = "wasm32") {
+                    ui.label("Zoom with ctrl / ⌘ + pointer wheel, or with pinch gesture.");
+                } else if cfg!(target_os = "macos") {
+                    ui.label("Zoom with ctrl / ⌘ + scroll.");
+                } else {
+                    ui.label("Zoom with ctrl + scroll.");
+                }
+                ui.label("Reset view with double-click.");
+                //ui.add(crate::egui_github_link_file!());
+            });
+        });
+        ui.separator();
// 这里用selectable_value来设定两个Panel,绑定到self.open_panel上用于判断当前应该使用哪个ui来绘图
+        ui.horizontal(|ui| {
+            ui.selectable_value(&mut self.open_panel, Panel::Lines, "Lines");
+            ui.selectable_value(&mut self.open_panel, Panel::Markers, "Markers");
+        });
+        ui.separator();
+
// 根据open_panel来进行ui的绘制
+        match self.open_panel {
+            Panel::Lines => {
+                self.line_demo.ui(ui);
+            }
+            Panel::Markers => {
+                self.marker_demo.ui(ui);
+            }
+        }
+    }
+}
+
 #[derive(serde::Deserialize, serde::Serialize)]
 #[serde(default)] // if we add new fields, give them default values when deserializing old state
 pub struct TemplateApp {
     // Example stuff:
     label: String,
     #[serde(skip)]
// 替换掉原来单一的line_demo,替换为包含多个demo的plotdemo
-    line_demo: LineDemo,
+    plot_demo: PlotDemo,
     #[serde(skip)] // This how you opt-out of serialization of a field
     value: f32,
 }
@@ -23,7 +78,7 @@ impl Default for TemplateApp {
         Self {
             // Example stuff:
             label: "Hello World!Ruster.".to_owned(),
-            line_demo: LineDemo::default(),
+            plot_demo: PlotDemo::default(),
             value: 2.7,
         }
     }
@@ -75,7 +130,7 @@ impl eframe::App for TemplateApp {
             });
         });
         egui::CentralPanel::default().show(ctx, |ui| {
-            self.line_demo.ui(ui);
+            self.plot_demo.ui(ui);
         });
 /*
         egui::CentralPanel::default().show(ctx, |ui| {
@@ -294,4 +349,79 @@ impl LineDemo {
         })
         .response
     }
-}
\ No newline at end of file
+}
+
// 实现MarkerDemo
// 具体MarkerDemo的实现不做注释。。。。。
+#[derive(PartialEq)]
+struct MarkerDemo {
+    fill_markers: bool,
+    marker_radius: f32,
+    automatic_colors: bool,
+    marker_color: Color32,
+}
+
+impl Default for MarkerDemo {
+    fn default() -> Self {
+        Self {
+            fill_markers: true,
+            marker_radius: 5.0,
+            automatic_colors: true,
+            marker_color: Color32::GREEN,
+        }
+    }
+}
+
+impl MarkerDemo {
+    fn markers(&self) -> Vec<Points> {
+        MarkerShape::all()
+            .enumerate()
+            .map(|(i, marker)| {
+                let y_offset = i as f64 * 0.5 + 1.0;
+                let mut points = Points::new(vec![
+                    [1.0, 0.0 + y_offset],
+                    [2.0, 0.5 + y_offset],
+                    [3.0, 0.0 + y_offset],
+                    [4.0, 0.5 + y_offset],
+                    [5.0, 0.0 + y_offset],
+                    [6.0, 0.5 + y_offset],
+                ])
+                .name(format!("{marker:?}"))
+                .filled(self.fill_markers)
+                .radius(self.marker_radius)
+                .shape(marker);
+
+                if !self.automatic_colors {
+                    points = points.color(self.marker_color);
+                }
+
+                points
+            })
+            .collect()
+    }
+
+    fn ui(&mut self, ui: &mut Ui) -> Response {
+        ui.horizontal(|ui| {
+            ui.checkbox(&mut self.fill_markers, "Fill");
+            ui.add(
+                egui::DragValue::new(&mut self.marker_radius)
+                    .speed(0.1)
+                    .clamp_range(0.0..=f64::INFINITY)
+                    .prefix("Radius: "),
+            );
+            ui.checkbox(&mut self.automatic_colors, "Automatic colors");
+            if !self.automatic_colors {
+                ui.color_edit_button_srgba(&mut self.marker_color);
+            }
+        });
+
+        let markers_plot = Plot::new("markers_demo")
+            .data_aspect(1.0)
+            .legend(Legend::default());
+        markers_plot
+            .show(ui, |plot_ui| {
+                for marker in self.markers() {
+                    plot_ui.points(marker);
+                }
+            })
+            .response
+    }
+}
-- 

ffmpeg工具转的mov到gif看起来也还可以呀。。。像素懒得调了
请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pytest框架的封装以及用例管理框架

pytest框架的封装以及用例管理框架 公共类统一封装requests_util02.pytest_api01.py 自动化测试的基础自动化测试的介入点自动化测试和手工测试占比自动化实施过程 pytest元素定位元素定位查找元素定位的方式通过 ID 定位通过 Name 定位通过 Class Name 定位通过 Tag Name 定位…

数据结构面试常见问题之串的模式匹配(KMP算法)系列-简单解决方案

&#x1f600;前言 字符串匹配是计算机科学中一个常见的问题&#xff0c;指的是在一个长字符串中查找一个短字符串的出现位置。在文本编辑、生物信息学、数据挖掘等领域都有着广泛的应用。 本文将介绍 KMP 算法&#xff0c;一种用于解决字符串匹配问题的经典算法。KMP 算法可以…

鸿蒙网络开发学习:【ylong_http】

简介 ylong_http 构建了完整的 HTTP 能力&#xff0c;支持用户使用 HTTP 能力完成通信场景的需求。 ylong_http 使用 Rust 编写&#xff0c;为 OpenHarmony 的 Rust 能力构筑提供支持。 ylong_http 在 OpenHarmony 中的位置 ylong_http 向 OpenHarmony 系统服务层中的网络协…

flutter实现视频播放器,可根据指定视频地址播放、设置声音,进度条拖动,下载等

需要装依赖&#xff1a; gallery_saver: ^2.3.2video_player: ^2.8.3 AndroidManifest.xml <uses-permission android:name"android.permission.INTERNET"/> 实现代码 import dart:async; import dart:io;import package:flutter/material.dart; import pa…

深入理解栈和队列(二):队列

个人主页&#xff1a;17_Kevin-CSDN博客 专栏&#xff1a;《数据结构》 一、队列的概念和结构 队列是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#xff1a;进行插入操作的…

OC对象 - 关联对象(如何给分类添加成员变量)

文章目录 OC对象 - 关联对象&#xff08;如何给分类添加成员变量&#xff09;1. 基本使用1.1 提供的API1.1.1 添加关联对象1.1.2 获得关联对象1.1.3 移除所有关联对象1.1.3 修饰符 1.2 使用方法1.2 Key的常见用法1.2.1 使用的get方法的selecor作为key1.2.2 使用指针的地址作为k…

【Node.js】zlib

gzip 和 deflate 的基本使用 const zlib require("zlib"); const fs require(fs)// 压缩 1. createGzip .gz 2. createDeflate .deflate // const readStream fs.createReadStream(index.txt) // const writeStream fs.createWriteStream(index.txt.gz) // rea…

Python Flask 自定义404错误

from flask import Flask, abort, make_response, request, render_templateapp Flask(__name__)# 重定向到百度 app.route(/index, methods["GET", "POST"]) def index():if request.method "GET":return render_template("index.html&q…

Python Flask 自定义过滤器

{{ data.list | li2 }} li2就是自定义的 from flask import Flask, render_templateapp Flask(__name__)app.route("/index") def index():data {name: "张三","age": 18,list: [123123, 41, 123]}return render_template("index2.html…

nodejs+vue高校二手商品交易平台的设计与实现python-flask-django-php

当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统高校二手商品交易采取了人工的管理方法&#xf…

BUG未解之谜01-指针引用之谜

在leetcode里面刷题出现的问题&#xff0c;当我在sortedArrayToBST里面给root赋予初始值NULL之后&#xff0c;问题得到解决&#xff01; 理论上root是未初始化的变量&#xff0c;然后我进入insert函数之后&#xff0c;root引用的内容也是未知值&#xff0c;因此无法给原来的二叉…

array go 语言的数组 /切片

内存地址通过& package mainimport "fmt"func main() {var arr [2][3]int16fmt.Println(arr)fmt.Printf("arr的地址是: %p \n", &arr)fmt.Printf("arr[0]的地址是 %p \n", &arr[0])fmt.Printf("arr[0][0]的地址是 %p \n"…

【Linux 09】进程优先级

文章目录 &#x1f308; Ⅰ 什么是优先级&#x1f308; Ⅱ 为什么存在优先级&#x1f308; Ⅲ 查看进程优先级&#x1f308; Ⅳ 修改进程优先级 &#x1f308; Ⅰ 什么是优先级 优先级本质 指定进程获取某种资源的先后顺序。在 Linux 中&#xff0c;使用 task_struct 进程控制…

电子电器架构 —— 诊断数据DTC具体故障

电子电器架构 —— 诊断数据DTC具体故障 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师 (Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再挣…

【CDA二级数据分析备考思维导图】

CDA二级数据分析备考思维导图 CDA二级复习备考资料共计七个章节&#xff0c;如需资料&#xff0c;请留言&#xff0c;概览如下图&#xff1a;一、数据采集与处理1.数据采集方法2.市场调研和数据录入3、数据探索与可视化4、数据预处理方法 总结&#xff1a;以上为自己学习数据分…

现代化应用部署工具-Docker

Docker 简介 什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上。 Docker部署的优势 通过使用Docker等容器技术&#xff0c;可以将应用程序及其依赖项…

R-Linux 免费ext2 / 3 / 4文件系统恢复软件简介(推荐)

R-Linux&#xff1a;只适合 3种类型的发行版使用。 R-Linux 免费ext2 / 3 / 4文件系统恢复软件简介&#xff08;推荐&#xff09; https://blog.csdn.net/allway2/article/details/102632495 R-Linux for Linux Technical Documentation https://www.r-studio.com/free-linux…

【docker常用命令】

1. 什么是docker Docker 是一种开源的容器化平台&#xff0c;用于开发、交付和运行应用程序。它允许开发人员将应用程序及其依赖项&#xff08;如库、环境变量、配置文件等&#xff09;打包到一个被称为容器的标准化单元中。这个容器包含了一切应用程序需要运行的所有内容&…

漫画之家”系统设计与实现|SpringBoot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;…

nodejs+vue高校工作室管理系统python-flask-django-php

系统根据现有的管理模块进行开发和扩展&#xff0c;采用面向对象的开发的思想和结构化的开发方法对高校工作室管理的现状进行系统调查。采用结构化的分析设计&#xff0c;该方法要求结合一定的图表&#xff0c;在模块化的基础上进行系统的开发工作。在设计中采用“自下而上”的…