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看起来也还可以呀。。。像素懒得调了
请添加图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 Rust 编写一个 3D 查看器,可以使用以下步骤: 1. 确定所需的3D引擎库。Rust 中有多个3D引擎库可供选择,例如 wgpu、glium、piston等。在这里,我们以 wgpu 为例。 2. 创建一个 Rust 项目,并使用 Cargo 管理依赖。在项目中添加 wgpu 依赖。 3. 编写代码来加载 3D 模型。这可以通过使用第三方库,例如 assimp-rs 来实现。 4. 编写代码来渲染 3D 模型。可以使用 wgpu 提供的 API 来实现。 以下是一个简单的示例代码,该代码使用 wgpu 和 assimp-rs 实现了一个简单的 3D 模型查看器: ```rust use std::path::Path; use wgpu::{BackendBit, Device, Instance, Queue, Surface}; use assimp::import::Importer; use assimp::scene::Scene; async fn run() { // 初始化 wgpu let instance = Instance::new(BackendBit::PRIMARY); let surface = unsafe { instance.create_surface(window) }; let adapter = instance .request_adapter(&RequestAdapterOptions { power_preference: PowerPreference::Default, compatible_surface: Some(&surface), }) .await .unwrap(); let (device, queue) = adapter .request_device( &DeviceDescriptor { features: Default::default(), limits: Default::default(), shader_validation: true, }, None, ) .await .unwrap(); // 加载 3D 模型 let importer = Importer::new(); let path = Path::new("path/to/your/model"); let scene = importer.read_file(path).unwrap(); // 渲染 3D 模型 // ... } fn main() { env_logger::init(); // 创建事件循环 let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); let mut state = AppState::new(&window); // 运行事件循环 let event_loop_proxy = event_loop.create_proxy(); let event_loop_runner = event_loop.run(event_loop_proxy, &mut state); smol::block_on(run()); } ``` 这段代码中,我们首先初始化了 wgpu,并加载了一个 3D 模型。然后,我们可以使用 wgpu 提供的 API 来渲染 3D 模型,例如创建顶点缓冲区、着色器程序、渲染管道等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值