This commit is contained in:
237
Cargo.lock
generated
237
Cargo.lock
generated
@@ -2,18 +2,52 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||
|
||||
[[package]]
|
||||
name = "cassowary"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
|
||||
|
||||
[[package]]
|
||||
name = "castaway"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "compact_str"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
|
||||
dependencies = [
|
||||
"castaway",
|
||||
"cfg-if",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.27.0"
|
||||
@@ -39,6 +73,65 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.177"
|
||||
@@ -60,6 +153,15 @@ version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.12.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
@@ -95,6 +197,50 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui"
|
||||
version = "0.26.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f44c9e68fd46eda15c646fbb85e1040b657a58cdc8c98db1d97a55930d991eef"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cassowary",
|
||||
"compact_str",
|
||||
"crossterm",
|
||||
"itertools 0.12.1",
|
||||
"lru",
|
||||
"paste",
|
||||
"stability",
|
||||
"strum",
|
||||
"unicode-segmentation",
|
||||
"unicode-truncate",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
@@ -104,6 +250,18 @@ dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@@ -151,8 +309,87 @@ name = "ssh-tui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossterm",
|
||||
"ratatui",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stability"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-truncate"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
|
||||
dependencies = [
|
||||
"itertools 0.13.0",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
|
||||
@@ -5,7 +5,8 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
crossterm = "0.27"
|
||||
ratatui = "0.26"
|
||||
|
||||
[[bin]]
|
||||
name = "ssh-tui"
|
||||
path = "main.rs"
|
||||
path = "src/main.rs"
|
||||
32
main.rs
32
main.rs
@@ -1,32 +0,0 @@
|
||||
use crossterm::{
|
||||
event::{self, DisableMouseCapture, EnableMouseCapture, Event},
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use std::io::{self};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
enable_raw_mode()?;
|
||||
let mut stdout = io::stdout();
|
||||
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
|
||||
|
||||
execute!(
|
||||
stdout,
|
||||
crossterm::terminal::Clear(crossterm::terminal::ClearType::All)
|
||||
)?;
|
||||
execute!(stdout, crossterm::cursor::MoveTo(0, 0))?;
|
||||
println!("Wellcome to dcorral.com!");
|
||||
execute!(stdout, crossterm::cursor::MoveTo(0, 1))?;
|
||||
println!("Press any key to exit.");
|
||||
|
||||
loop {
|
||||
if let Event::Key(_) = event::read()? {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
disable_raw_mode()?;
|
||||
execute!(stdout, LeaveAlternateScreen, DisableMouseCapture)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
41
src/app.rs
Normal file
41
src/app.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use crate::theme::Theme;
|
||||
|
||||
pub const NUM_BOXES: usize = 4;
|
||||
|
||||
pub struct App {
|
||||
pub focus: usize,
|
||||
pub theme: Theme,
|
||||
pub show_help: bool,
|
||||
pub show_welcome: bool,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
focus: 0,
|
||||
theme: Theme::gruvbox_dark(),
|
||||
show_help: false,
|
||||
show_welcome: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_left(&mut self) {
|
||||
self.focus = (self.focus + 3) % NUM_BOXES;
|
||||
}
|
||||
|
||||
pub fn move_right(&mut self) {
|
||||
self.focus = (self.focus + 1) % NUM_BOXES;
|
||||
}
|
||||
|
||||
pub fn move_down(&mut self) {
|
||||
if self.focus < 2 {
|
||||
self.focus += 2;
|
||||
} else {
|
||||
self.focus -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_up(&mut self) {
|
||||
self.move_down(); // symmetric
|
||||
}
|
||||
}
|
||||
35
src/input.rs
Normal file
35
src/input.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use crossterm::event::{Event, KeyCode};
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
pub fn handle_input(app: &mut App, event: Event) -> bool {
|
||||
if app.show_welcome {
|
||||
if let Event::Key(_) = event {
|
||||
app.show_welcome = false;
|
||||
}
|
||||
} else if app.show_help {
|
||||
if let Event::Key(key) = event {
|
||||
match key.code {
|
||||
KeyCode::Char('q')
|
||||
| KeyCode::Esc
|
||||
| KeyCode::Char('?')
|
||||
| KeyCode::Enter
|
||||
| KeyCode::Backspace => app.show_help = false,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Event::Key(key) = event {
|
||||
match key.code {
|
||||
KeyCode::Char('h') | KeyCode::Left => app.move_left(),
|
||||
KeyCode::Char('l') | KeyCode::Right => app.move_right(),
|
||||
KeyCode::Char('j') | KeyCode::Down => app.move_down(),
|
||||
KeyCode::Char('k') | KeyCode::Up => app.move_up(),
|
||||
KeyCode::Char('?') => app.show_help = true,
|
||||
KeyCode::Char('q') | KeyCode::Esc => return false,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
49
src/main.rs
Normal file
49
src/main.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
mod app;
|
||||
mod input;
|
||||
mod theme;
|
||||
mod ui;
|
||||
|
||||
use crossterm::{
|
||||
event, execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use ratatui::{backend::CrosstermBackend, Terminal};
|
||||
use std::io::stdout;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
enable_raw_mode()?;
|
||||
let (width, height) = crossterm::terminal::size()?;
|
||||
if width < 15 || height < 15 {
|
||||
disable_raw_mode()?;
|
||||
println!("Your console is too small.");
|
||||
return Ok(());
|
||||
}
|
||||
let mut stdout = stdout();
|
||||
execute!(stdout, EnterAlternateScreen)?;
|
||||
let backend = CrosstermBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
|
||||
let mut app = app::App::new();
|
||||
let mut blink_counter = 0;
|
||||
|
||||
loop {
|
||||
let blink = (blink_counter / 3) % 2 == 0;
|
||||
terminal.draw(|f| ui::draw(f, &app, blink))?;
|
||||
blink_counter += 1;
|
||||
let timeout = if app.show_welcome {
|
||||
std::time::Duration::from_millis(70)
|
||||
} else {
|
||||
std::time::Duration::from_millis(60)
|
||||
};
|
||||
if event::poll(timeout)? {
|
||||
let event = event::read()?;
|
||||
if !input::handle_input(&mut app, event) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disable_raw_mode()?;
|
||||
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
|
||||
Ok(())
|
||||
}
|
||||
32
src/theme.rs
Normal file
32
src/theme.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use ratatui::style::Color;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Theme {
|
||||
pub bg: Color,
|
||||
pub fg: Color,
|
||||
pub red: Color,
|
||||
pub green: Color,
|
||||
pub yellow: Color,
|
||||
pub blue: Color,
|
||||
pub purple: Color,
|
||||
pub aqua: Color,
|
||||
pub orange: Color,
|
||||
pub gray: Color,
|
||||
}
|
||||
|
||||
impl Theme {
|
||||
pub fn gruvbox_dark() -> Self {
|
||||
Self {
|
||||
bg: Color::Rgb(40, 40, 40),
|
||||
fg: Color::Rgb(235, 219, 178),
|
||||
red: Color::Rgb(204, 36, 29),
|
||||
green: Color::Rgb(152, 151, 26),
|
||||
yellow: Color::Rgb(215, 153, 33),
|
||||
blue: Color::Rgb(69, 133, 136),
|
||||
purple: Color::Rgb(177, 98, 134),
|
||||
aqua: Color::Rgb(104, 157, 106),
|
||||
orange: Color::Rgb(214, 93, 14),
|
||||
gray: Color::Rgb(146, 131, 116),
|
||||
}
|
||||
}
|
||||
}
|
||||
108
src/ui.rs
Normal file
108
src/ui.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
use ratatui::{
|
||||
layout::{Alignment, Constraint, Direction, Layout},
|
||||
style::Style,
|
||||
text::{Line, Span},
|
||||
widgets::{Block, Borders, Paragraph},
|
||||
Frame,
|
||||
};
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
pub fn draw(f: &mut Frame, app: &App, blink: bool) {
|
||||
let bg_block = Block::default().style(Style::default().bg(app.theme.bg));
|
||||
f.render_widget(bg_block, f.size());
|
||||
|
||||
if app.show_welcome {
|
||||
let fg = app.theme.fg;
|
||||
let accent_fg = if blink { app.theme.blue } else { app.theme.bg };
|
||||
let size = f.size();
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Percentage(40),
|
||||
Constraint::Percentage(20),
|
||||
Constraint::Percentage(40),
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(size);
|
||||
let welcome_text = Paragraph::new(vec![
|
||||
Line::from(vec![
|
||||
Span::styled("Welcome to ", Style::default().fg(fg).bg(app.theme.bg)),
|
||||
Span::styled(
|
||||
"dcorral.com",
|
||||
Style::default().fg(app.theme.orange).bg(app.theme.bg),
|
||||
),
|
||||
Span::styled("!", Style::default().fg(fg).bg(app.theme.bg)),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled("press ", Style::default().fg(fg).bg(app.theme.bg)),
|
||||
Span::styled("any key", Style::default().fg(accent_fg).bg(app.theme.bg)),
|
||||
Span::styled(" to continue", Style::default().fg(fg).bg(app.theme.bg)),
|
||||
]),
|
||||
])
|
||||
.alignment(Alignment::Center);
|
||||
f.render_widget(welcome_text, chunks[1]);
|
||||
} else if app.show_help {
|
||||
let help_content = "Navigation:\n\
|
||||
h / ←: Move left\n\
|
||||
l / →: Move right\n\
|
||||
j / ↓: Move down\n\
|
||||
k / ↑: Move up\n\
|
||||
? : Show help\n\
|
||||
q / Esc: Quit";
|
||||
let help_text = Paragraph::new(help_content)
|
||||
.alignment(ratatui::layout::Alignment::Center)
|
||||
.style(Style::default().fg(app.theme.fg).bg(app.theme.bg));
|
||||
f.render_widget(help_text, f.size());
|
||||
} else {
|
||||
let size = f.size();
|
||||
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Min(1), Constraint::Length(1)].as_ref())
|
||||
.split(size);
|
||||
|
||||
let box_area = chunks[0];
|
||||
|
||||
let box_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||
.split(box_area);
|
||||
|
||||
let top_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||
.split(box_chunks[0]);
|
||||
|
||||
let bottom_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||
.split(box_chunks[1]);
|
||||
|
||||
let areas = [
|
||||
top_chunks[0],
|
||||
top_chunks[1],
|
||||
bottom_chunks[0],
|
||||
bottom_chunks[1],
|
||||
];
|
||||
|
||||
for (i, area) in areas.iter().enumerate() {
|
||||
let (bg, fg) = if app.focus == i {
|
||||
(app.theme.blue, app.theme.bg)
|
||||
} else {
|
||||
(app.theme.bg, app.theme.fg)
|
||||
};
|
||||
let block = Block::default()
|
||||
.title(format!("Box {}", i))
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().bg(bg).fg(fg));
|
||||
f.render_widget(block, *area);
|
||||
}
|
||||
|
||||
let help_text = Paragraph::new("Use hjkl or arrows to navigate, ? for help, q to quit")
|
||||
.style(Style::default().fg(app.theme.fg).bg(app.theme.bg));
|
||||
f.render_widget(help_text, chunks[1]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user