环境
- Time 2022-08-12
- Rust 1.63.0
- Tui 0.18.0
前言
说明
参考:https://github.com/fdehau/tui-rs/blob/master/examples/paragraph.rs
目标
使用 tui-rs
显示段落。
定义数据
const 山海经: &str = "南山经之首曰䧿山。其首曰招摇之山,临于西海之上。\
多桂多金玉。有草焉,其状如韭而青花,其名曰祝馀,食之不饥。\
有木焉,其状如榖而黑理,其花四照。其名曰迷榖,佩之不迷。\
有兽焉,其状如禺而白耳,伏行人走,其名曰狌狌,食之善走。\
丽麂之水出焉,而西流注于海,其中多育沛,佩之无瘕疾。\
又东三百里曰堂庭之山。多棪木,多白猿,多水玉,多黄金。\n";
定义滚动
struct App {
scroll: u16,
}
impl App {
fn new() -> App {
App { scroll: 0 }
}
fn on_tick(&mut self) {
self.scroll += 1;
self.scroll %= 10;
}
}
布局
let block = Block::default().style(Style::default().bg(Color::White).fg(Color::Black));
frame.render_widget(block, frame.size());
let chunks = layout::Layout::default()
.direction(layout::Direction::Vertical)
.margin(5)
.constraints([
layout::Constraint::Percentage(25),
layout::Constraint::Percentage(25),
layout::Constraint::Percentage(25),
layout::Constraint::Percentage(25),
])
.split(frame.size());
文本行
let text = vec![
text::Spans::from("又东四百里至于旄山之尾,其南有谷,曰育遗,多怪鸟,凯风自是出。"),
text::Spans::from(text::Span::styled(
"又东四百里,至于非山之首。其上多金玉,无水,其下多蝮虫。",
Style::default().fg(Color::Red),
)),
text::Spans::from(text::Span::styled(
"又东五百里曰阳夹之山。无草木,多水。",
Style::default().add_modifier(Modifier::CROSSED_OUT),
)),
text::Spans::from(text::Span::styled(
山海经,
Style::default().bg(Color::Green),
)),
text::Spans::from(text::Span::styled(
"又东五百里曰灌湘之山。上多木,无草,多怪鸟,无兽。",
Style::default()
.fg(Color::Green)
.add_modifier(Modifier::ITALIC),
)),
];
渲染
let create_block = |title| {
Block::default()
.borders(Borders::ALL)
.style(Style::default().bg(Color::White).fg(Color::Black))
.title(text::Span::styled(
title,
Style::default().add_modifier(Modifier::BOLD),
))
};
let paragraph = widgets::Paragraph::new(text.clone())
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(create_block("左对齐,不换行"))
.alignment(layout::Alignment::Left);
frame.render_widget(paragraph, chunks[0]);
let paragraph = widgets::Paragraph::new(text.clone())
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(create_block("左对齐,换行"))
.alignment(layout::Alignment::Left)
.wrap(widgets::Wrap { trim: true });
frame.render_widget(paragraph, chunks[1]);
let paragraph = widgets::Paragraph::new(text.clone())
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(create_block("居中,换行"))
.alignment(layout::Alignment::Center)
.wrap(widgets::Wrap { trim: true })
.scroll((app.scroll, 0));
frame.render_widget(paragraph, chunks[2]);
let paragraph = widgets::Paragraph::new(text)
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(create_block("右对齐,换行"))
.alignment(layout::Alignment::Right)
.wrap(widgets::Wrap { trim: true });
frame.render_widget(paragraph, chunks[3]);
效果展示
总结
使用 tui-rs
渲染段落。
附录
源码
use anyhow::{Context, Result};
use crossterm::{event, terminal, ExecutableCommand};
use style::{Color, Modifier, Style};
use tui::backend::{Backend, CrosstermBackend};
use tui::{layout, style, text, widgets, Frame, Terminal};
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("重置控制台失败")
}
fn run<B: Backend>(terminal: &mut Terminal<B>) -> Result<()> {
let timeout = std::time::Duration::from_millis(500);
let mut app = App::new();
loop {
terminal.draw(|frame| ui(frame, &app))?;
if event::poll(timeout)? {
if let event::Event::Key(key) = event::read()? {
use event::KeyCode::{Char, Esc};
match key.code {
Char('q') | Char('Q') | Esc => return Ok(()),
_ => {}
}
}
}
app.on_tick();
}
}
struct App {
scroll: u16,
}
impl App {
fn new() -> App {
App { scroll: 0 }
}
fn on_tick(&mut self) {
self.scroll += 1;
self.scroll %= 10;
}
}
const 山海经: &str = "南山经之首曰䧿山。其首曰招摇之山,临于西海之上。\
多桂多金玉。有草焉,其状如韭而青花,其名曰祝馀,食之不饥。\
有木焉,其状如榖而黑理,其花四照。其名曰迷榖,佩之不迷。\
有兽焉,其状如禺而白耳,伏行人走,其名曰狌狌,食之善走。\
丽麂之水出焉,而西流注于海,其中多育沛,佩之无瘕疾。\
又东三百里曰堂庭之山。多棪木,多白猿,多水玉,多黄金。\n";
fn ui<B: Backend>(frame: &mut Frame<B>, app: &App) {
let block = Block::default().style(Style::default().bg(Color::White).fg(Color::Black));
frame.render_widget(block, frame.size());
let chunks = layout::Layout::default()
.direction(layout::Direction::Vertical)
.margin(5)
.constraints([
layout::Constraint::Percentage(25),
layout::Constraint::Percentage(25),
layout::Constraint::Percentage(25),
layout::Constraint::Percentage(25),
])
.split(frame.size());
let text = vec![
text::Spans::from("又东四百里至于旄山之尾,其南有谷,曰育遗,多怪鸟,凯风自是出。"),
text::Spans::from(text::Span::styled(
"又东四百里,至于非山之首。其上多金玉,无水,其下多蝮虫。",
Style::default().fg(Color::Red),
)),
text::Spans::from(text::Span::styled(
"又东五百里曰阳夹之山。无草木,多水。",
Style::default().add_modifier(Modifier::CROSSED_OUT),
)),
text::Spans::from(text::Span::styled(
山海经,
Style::default().bg(Color::Green),
)),
text::Spans::from(text::Span::styled(
"又东五百里曰灌湘之山。上多木,无草,多怪鸟,无兽。",
Style::default()
.fg(Color::Green)
.add_modifier(Modifier::ITALIC),
)),
];
let create_block = |title| {
Block::default()
.borders(Borders::ALL)
.style(Style::default().bg(Color::White).fg(Color::Black))
.title(text::Span::styled(
title,
Style::default().add_modifier(Modifier::BOLD),
))
};
let paragraph = widgets::Paragraph::new(text.clone())
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(create_block("左对齐,不换行"))
.alignment(layout::Alignment::Left);
frame.render_widget(paragraph, chunks[0]);
let paragraph = widgets::Paragraph::new(text.clone())
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(create_block("左对齐,换行"))
.alignment(layout::Alignment::Left)
.wrap(widgets::Wrap { trim: true });
frame.render_widget(paragraph, chunks[1]);
let paragraph = widgets::Paragraph::new(text.clone())
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(create_block("居中,换行"))
.alignment(layout::Alignment::Center)
.wrap(widgets::Wrap { trim: true })
.scroll((app.scroll, 0));
frame.render_widget(paragraph, chunks[2]);
let paragraph = widgets::Paragraph::new(text)
.style(Style::default().bg(Color::White).fg(Color::Black))
.block(create_block("右对齐,换行"))
.alignment(layout::Alignment::Right)
.wrap(widgets::Wrap { trim: true });
frame.render_widget(paragraph, chunks[3]);
}
标签:default,Style,0058,示例,Color,text,Tui,let,block
From: https://www.cnblogs.com/jiangbo4444/p/16746232.html