热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

0065TuiCanvas示例

环境Time2022-08-17Rust1.63.0Tui0.18.0前言说明参考:https:github.comfdehautui-rsblobmasterexamplesca

环境



  • Time 2022-08-17

  • Rust 1.63.0

  • Tui 0.18.0


前言


说明

参考:https://github.com/fdehau/tui-rs/blob/master/examples/canvas.rs


目标

使用 tui-rs 显示 Canvas。


定义应用

struct App {
x: f64,
y: f64,
ball: Rectangle,
playground: layout::Rect,
vx: f64,
vy: f64,
dir_x: bool,
dir_y: bool,
}
impl App {
fn new() -> App {
App {
x: 0.0,
y: 0.0,
ball: Rectangle {
x: 10.0,
y: 30.0,
width: 10.0,
height: 10.0,
color: Color::Yellow,
},
playground: layout::Rect::new(10, 10, 100, 100),
vx: 1.0,
vy: 1.0,
dir_x: true,
dir_y: true,
}
}
fn on_tick(&mut self) {
if self.ball.x || self.ball.x + self.ball.width > self.playground.right() as f64
{
self.dir_x = !self.dir_x;
}
if self.ball.y || self.ball.y + self.ball.height > self.playground.bottom() as f64
{
self.dir_y = !self.dir_y;
}
if self.dir_x {
self.ball.x += self.vx;
} else {
self.ball.x -= self.vx;
}
if self.dir_y {
self.ball.y += self.vy;
} else {
self.ball.y -= self.vy
}
}
}

ui

let chunks = Layout::default()
.direction(layout::Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(frame.size());
let canvas = Canvas::default()
.block(Block::default().borders(Borders::ALL).title("世界地图"))
.paint(|context| {
context.draw(&Map {
color: Color::White,
resolution: MapResolution::High,
});
context.print(
app.x,
-app.y,
text::Span::styled("这里", Style::default().fg(Color::Yellow)),
);
})
.x_bounds([-180.0, 180.0])
.y_bounds([-90.0, 90.0]);
frame.render_widget(canvas, chunks[0]);
let canvas = Canvas::default()
.block(Block::default().borders(Borders::ALL).title("Pong"))
.paint(|context| {
context.draw(&app.ball);
})
.x_bounds([10.0, 110.0])
.y_bounds([10.0, 110.0]);
frame.render_widget(canvas, chunks[1]);

效果展示

Canvas


总结

使用 tui-rs 渲染 Canvas。


附录


源码

use anyhow::{Context, Result};
use crossterm::{event, terminal, ExecutableCommand};
use layout::{Constraint, Layout};
use tui::backend::{Backend, CrosstermBackend};
use tui::style::{Color, Style};
use tui::{layout, text, widgets, Frame, Terminal};
use widgets::canvas::{Canvas, Map, MapResolution, Rectangle};
use widgets::{Block, Borders};
pub fn main() -> Result<()> {
terminal::enable_raw_mode()?;
let mut backend = CrosstermBackend::new(std::io::stdout());
backend
.execute(terminal::EnterAlternateScreen)?
.execute(terminal::Clear(terminal::ClearType::All))?
.hide_cursor()?;
let mut terminal = tui::Terminal::new(backend)?;
run(&mut terminal)?;
terminal::disable_raw_mode()?;
terminal
.backend_mut()
.execute(terminal::Clear(terminal::ClearType::All))?
.execute(terminal::LeaveAlternateScreen)?
.show_cursor()
.context("重置控制台失败")
}
struct App {
x: f64,
y: f64,
ball: Rectangle,
playground: layout::Rect,
vx: f64,
vy: f64,
dir_x: bool,
dir_y: bool,
}
impl App {
fn new() -> App {
App {
x: 0.0,
y: 0.0,
ball: Rectangle {
x: 10.0,
y: 30.0,
width: 10.0,
height: 10.0,
color: Color::Yellow,
},
playground: layout::Rect::new(10, 10, 100, 100),
vx: 1.0,
vy: 1.0,
dir_x: true,
dir_y: true,
}
}
fn on_tick(&mut self) {
if self.ball.x || self.ball.x + self.ball.width > self.playground.right() as f64
{
self.dir_x = !self.dir_x;
}
if self.ball.y || self.ball.y + self.ball.height > self.playground.bottom() as f64
{
self.dir_y = !self.dir_y;
}
if self.dir_x {
self.ball.x += self.vx;
} else {
self.ball.x -= self.vx;
}
if self.dir_y {
self.ball.y += self.vy;
} else {
self.ball.y -= self.vy
}
}
}
fn run(terminal: &mut Terminal) -> Result<()> {
let timeout = std::time::Duration::from_millis(500);
let mut app = App::new();
loop {
terminal.draw(|frame| ui(frame, &mut app))?;
if event::poll(timeout)? {
if let event::Event::Key(key) = event::read()? {
use event::KeyCode::{self, Char, Esc};
match key.code {
Char('q') | Char('Q') | Esc => return Ok(()),
KeyCode::Down => app.y += 1.0,
KeyCode::Up => app.y -= 1.0,
KeyCode::Right => app.x += 1.0,
KeyCode::Left => app.x -= 1.0,
_ => {}
}
}
}
app.on_tick();
}
}
fn ui(frame: &mut Frame, app: &mut App) {
let chunks = Layout::default()
.direction(layout::Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(frame.size());
let canvas = Canvas::default()
.block(Block::default().borders(Borders::ALL).title("世界地图"))
.paint(|context| {
context.draw(&Map {
color: Color::White,
resolution: MapResolution::High,
});
context.print(
app.x,
-app.y,
text::Span::styled("这里", Style::default().fg(Color::Yellow)),
);
})
.x_bounds([-180.0, 180.0])
.y_bounds([-90.0, 90.0]);
frame.render_widget(canvas, chunks[0]);
let canvas = Canvas::default()
.block(Block::default().borders(Borders::ALL).title("Pong"))
.paint(|context| {
context.draw(&app.ball);
})
.x_bounds([10.0, 110.0])
.y_bounds([10.0, 110.0]);
frame.render_widget(canvas, chunks[1]);
}


推荐阅读
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • 微软推出Windows Terminal Preview v0.10
    微软近期发布了Windows Terminal Preview v0.10,用户可以在微软商店或GitHub上获取这一更新。该版本在2月份发布的v0.9基础上,新增了鼠标输入和复制Pane等功能。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • Ubuntu 22.04 安装搜狗输入法详细指南及常见问题解决方案
    本文将详细介绍如何在 Ubuntu 22.04 上安装搜狗输入法,并提供常见问题的解决方法。包括下载安装包、更新源、安装依赖项等步骤。 ... [详细]
  • 微服务优雅上下线的最佳实践
    本文介绍了微服务上下线的正确姿势,避免使用 kill -9 等粗暴手段,确保服务的稳定性和可靠性。 ... [详细]
  • 在 Mac 上配置 NDK
    本文详细介绍了如何在 Mac 上配置 Android NDK,包括设置环境变量和解决常见问题的方法。 ... [详细]
  • C语言中全部可用的数学函数有哪些?2.longlabs(longn);求长整型数的绝对值。3.doublefabs(doublex);求实数的绝对值。4.doublefloor(d ... [详细]
  • 思科IOS XE与ISE集成实现TACACS认证配置
    本文详细介绍了如何在思科IOS XE设备上配置TACACS认证,并通过ISE(Identity Services Engine)进行用户管理和授权。配置包括网络拓扑、设备设置和ISE端的具体步骤。 ... [详细]
  • 在 Ubuntu 中遇到 Samba 服务器故障时,尝试卸载并重新安装 Samba 发现配置文件未重新生成。本文介绍了解决该问题的方法。 ... [详细]
  • 本文将详细介绍如何在Mac上安装Jupyter Notebook,并提供一些常见的问题解决方法。通过这些步骤,您将能够顺利地在Mac上运行Jupyter Notebook。 ... [详细]
  • 本文详细介绍了在MySQL中如何高效利用EXPLAIN命令进行查询优化。通过实例解析和步骤说明,文章旨在帮助读者深入理解EXPLAIN命令的工作原理及其在性能调优中的应用,内容通俗易懂且结构清晰,适合各水平的数据库管理员和技术人员参考学习。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
author-avatar
Phoenix-Valefor
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有