Compare commits

...

2 Commits

Author SHA1 Message Date
scoobybejesus e983fb2234 Replaced deprecated tui with ratatui and updated to current version. 2023-10-23 13:36:28 -04:00
scoobybejesus 823f83d5c6 Refactor some ui while upgrading tui to latest version. 2023-10-23 13:26:51 -04:00
5 changed files with 332 additions and 112 deletions

245
Cargo.lock generated
View File

@ -24,6 +24,12 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]] [[package]]
name = "android-tzdata" name = "android-tzdata"
version = "0.1.1" version = "0.1.1"
@ -248,6 +254,31 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "crossterm"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
dependencies = [
"bitflags 2.4.1",
"crossterm_winapi",
"libc",
"mio",
"parking_lot",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "crptls" name = "crptls"
version = "0.2.2" version = "0.2.2"
@ -263,18 +294,18 @@ dependencies = [
[[package]] [[package]]
name = "cryptools" name = "cryptools"
version = "0.12.4" version = "0.12.6"
dependencies = [ dependencies = [
"chrono", "chrono",
"crptls", "crptls",
"csv", "csv",
"dotenv", "dotenv",
"ratatui",
"rust_decimal", "rust_decimal",
"rust_decimal_macros", "rust_decimal_macros",
"rustyline", "rustyline",
"structopt", "structopt",
"termion 2.0.1", "termion",
"tui",
] ]
[[package]] [[package]]
@ -391,6 +422,16 @@ dependencies = [
"ahash 0.8.3", "ahash 0.8.3",
] ]
[[package]]
name = "hashbrown"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
dependencies = [
"ahash 0.8.3",
"allocator-api2",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.1" version = "0.3.1"
@ -400,6 +441,12 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.17" version = "0.1.17"
@ -442,10 +489,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "itertools" name = "indoc"
version = "0.8.2" version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
[[package]]
name = "itertools"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
dependencies = [ dependencies = [
"either", "either",
] ]
@ -477,6 +530,16 @@ version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.11" version = "0.4.11"
@ -486,12 +549,33 @@ dependencies = [
"cfg-if 0.1.10", "cfg-if 0.1.10",
] ]
[[package]]
name = "lru"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60"
dependencies = [
"hashbrown 0.14.2",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.3.4" version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "mio"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys",
]
[[package]] [[package]]
name = "nibble_vec" name = "nibble_vec"
version = "0.1.0" version = "0.1.0"
@ -533,6 +617,35 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [
"cfg-if 1.0.0",
"libc",
"redox_syscall 0.4.1",
"smallvec",
"windows-targets",
]
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]] [[package]]
name = "powerfmt" name = "powerfmt"
version = "0.2.0" version = "0.2.0"
@ -656,6 +769,25 @@ dependencies = [
"getrandom", "getrandom",
] ]
[[package]]
name = "ratatui"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ebc917cfb527a566c37ecb94c7e3fd098353516fb4eb6bea17015ade0182425"
dependencies = [
"bitflags 2.4.1",
"cassowary",
"crossterm",
"indoc",
"itertools",
"lru",
"paste",
"strum",
"termion",
"unicode-segmentation",
"unicode-width",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.1.57" version = "0.1.57"
@ -671,6 +803,15 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
] ]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "redox_termios" name = "redox_termios"
version = "0.1.1" version = "0.1.1"
@ -756,6 +897,12 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]] [[package]]
name = "rustyline" name = "rustyline"
version = "12.0.0" version = "12.0.0"
@ -828,6 +975,36 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "signal-hook"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-mio"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
dependencies = [
"libc",
"mio",
"signal-hook",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "simdutf8" name = "simdutf8"
version = "0.1.4" version = "0.1.4"
@ -868,12 +1045,34 @@ version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107"
dependencies = [ dependencies = [
"heck", "heck 0.3.1",
"proc-macro2 0.4.30", "proc-macro2 0.4.30",
"quote 0.6.13", "quote 0.6.13",
"syn 0.15.44", "syn 0.15.44",
] ]
[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
"heck 0.4.1",
"proc-macro2 1.0.69",
"quote 1.0.33",
"rustversion",
"syn 2.0.38",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "0.15.44" version = "0.15.44"
@ -913,18 +1112,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "termion"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905"
dependencies = [
"libc",
"numtoa",
"redox_syscall 0.1.57",
"redox_termios",
]
[[package]] [[package]]
name = "termion" name = "termion"
version = "2.0.1" version = "2.0.1"
@ -988,22 +1175,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "tui"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b871b61f4c4b81e630215cd12e0ec29953d4545898e21a9e023b7520a74a9f9"
dependencies = [
"bitflags 1.3.2",
"cassowary",
"either",
"itertools",
"log",
"termion 1.5.5",
"unicode-segmentation",
"unicode-width",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.12" version = "1.0.12"
@ -1012,9 +1183,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.7.1" version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cryptools" name = "cryptools"
version = "0.12.4" version = "0.12.6"
authors = ["scoobybejesus <scoobybejesus@users.noreply.github.com>"] authors = ["scoobybejesus <scoobybejesus@users.noreply.github.com>"]
edition = "2021" edition = "2021"
description = "Command-line utility for processing cryptocurrency transactions into 'lots' and 'movements'." description = "Command-line utility for processing cryptocurrency transactions into 'lots' and 'movements'."
@ -10,7 +10,7 @@ description = "Command-line utility for processing cryptocurrency transactions i
# but it is optional because Windows doesn't support it. # but it is optional because Windows doesn't support it.
default = ["print_menu"] default = ["print_menu"]
print_menu = ["tui", "termion"] print_menu = ["ratatui", "termion"]
[[bin]] [[bin]]
name = "cryptools" name = "cryptools"
@ -26,7 +26,7 @@ rust_decimal_macros = "1.32.0"
chrono = { version = "0.4.31", features = ["serde"] } chrono = { version = "0.4.31", features = ["serde"] }
structopt = "0.2.10" structopt = "0.2.10"
rustyline = "12.0.0" rustyline = "12.0.0"
tui = { version = "0.8", optional = true, features = ['termion'] } ratatui = { version = "0.24.0", optional = true, features = ['termion'] }
termion = { version = "2.0.1", optional = true } termion = { version = "2.0.1", optional = true }
dotenv = "0.15.0" dotenv = "0.15.0"

View File

@ -7,6 +7,7 @@ use std::collections::HashMap;
use crptls::transaction::{Transaction, ActionRecord}; use crptls::transaction::{Transaction, ActionRecord};
use crptls::account::{Account, RawAccount}; use crptls::account::{Account, RawAccount};
use crptls::core_functions::ImportProcessParameters; use crptls::core_functions::ImportProcessParameters;
use ratatui::widgets::ListState;
use crate::export::{export_csv, export_je, export_txt}; use crate::export::{export_csv, export_je, export_txt};
@ -24,36 +25,51 @@ pub (crate) const REPORTS: [&'static str; 11] = [
"11. TXT: Bookkeeping journal entries", "11. TXT: Bookkeeping journal entries",
]; ];
pub struct ListState<I> { pub struct StatefulList<I> {
pub items: Vec<I>, pub items: Vec<I>,
pub selected: usize, pub state: ListState,
} }
impl<I> ListState<I> { impl<T> StatefulList<T> {
fn new(items: Vec<I>) -> ListState<I> { fn new(items: Vec<T>) -> StatefulList<T> {
ListState { items, selected: 0 } StatefulList { items, state: ListState::default() }
} }
fn select_previous(&mut self) { fn select_previous(&mut self) {
let i = match self.state.selected() {
if self.selected > 0 { Some(i) => {
self.selected -= 1; if i == 0 {
self.items.len() - 1
} else {
i - 1
} }
} }
None => 0,
};
self.state.select(Some(i));
}
fn select_next(&mut self) { fn select_next(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.items.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.state.select(Some(i));
}
if self.selected < self.items.len() - 1 {
self.selected += 1
}
}
} }
pub struct PrintWindow<'a> { pub struct PrintWindow<'a> {
pub title: &'a str, pub title: &'a str,
pub should_quit: bool, pub should_quit: bool,
pub tasks: ListState<&'a str>, pub tasks: StatefulList<&'a str>,
pub to_print_by_idx: Vec<usize>, pub to_print_by_idx: Vec<usize>,
pub to_print_by_title: Vec<&'a str>, pub to_print_by_title: Vec<&'a str>,
} }
@ -61,10 +77,13 @@ pub struct PrintWindow<'a> {
impl<'a> PrintWindow<'a> { impl<'a> PrintWindow<'a> {
pub fn new(title: &'a str) -> PrintWindow<'a> { pub fn new(title: &'a str) -> PrintWindow<'a> {
let mut tasks = StatefulList::new(REPORTS.to_vec());
tasks.state.select(Some(0));
PrintWindow { PrintWindow {
title, title,
should_quit: false, should_quit: false,
tasks: ListState::new(REPORTS.to_vec()), tasks,
to_print_by_idx: Vec::with_capacity(REPORTS.len()), to_print_by_idx: Vec::with_capacity(REPORTS.len()),
to_print_by_title: Vec::with_capacity(REPORTS.len()), to_print_by_title: Vec::with_capacity(REPORTS.len()),
} }
@ -78,7 +97,7 @@ impl<'a> PrintWindow<'a> {
self.tasks.select_next(); self.tasks.select_next();
} }
pub fn on_key(&mut self, c: char) { pub fn on_key(&mut self, c: char) -> Result<(), Box<dyn Error>> {
match c { match c {
@ -90,7 +109,7 @@ impl<'a> PrintWindow<'a> {
self.should_quit = true; self.should_quit = true;
} }
'x' => { 'x' => {
let selected = self.tasks.selected; let selected = self.tasks.state.selected().unwrap();
if self.to_print_by_idx.contains(&selected) {} else { if self.to_print_by_idx.contains(&selected) {} else {
self.to_print_by_idx.push(selected); self.to_print_by_idx.push(selected);
self.to_print_by_title.push(self.tasks.items[selected]) self.to_print_by_title.push(self.tasks.items[selected])
@ -99,7 +118,7 @@ impl<'a> PrintWindow<'a> {
self.tasks.select_next(); self.tasks.select_next();
} }
'd' => { 'd' => {
let selected_idx = self.tasks.selected; let selected_idx = self.tasks.state.selected().unwrap();
self.to_print_by_idx.retain(|&x| x != selected_idx ); self.to_print_by_idx.retain(|&x| x != selected_idx );
let selected_str = self.tasks.items[selected_idx]; let selected_str = self.tasks.items[selected_idx];
self.to_print_by_title.retain(|&x| x != selected_str ); self.to_print_by_title.retain(|&x| x != selected_str );
@ -107,6 +126,7 @@ impl<'a> PrintWindow<'a> {
} }
_ => {} _ => {}
} }
Ok(())
} }
fn change_vecs_to_chrono_order(vec: &mut Vec<usize>, strvec: &mut Vec<&str>) { fn change_vecs_to_chrono_order(vec: &mut Vec<usize>, strvec: &mut Vec<&str>) {

View File

@ -6,8 +6,8 @@ use std::time::Duration;
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use tui::Terminal; use ratatui::Terminal;
use tui::backend::TermionBackend; use ratatui::backend::TermionBackend;
use termion::raw::IntoRawMode; use termion::raw::IntoRawMode;
use termion::screen::IntoAlternateScreen; use termion::screen::IntoAlternateScreen;
use termion::input::MouseTerminal; use termion::input::MouseTerminal;
@ -46,14 +46,14 @@ pub (crate) fn print_menu_tui(
loop { loop {
ui::draw(&mut terminal, &app)?; ui::draw(&mut terminal, &mut app)?;
if let Event::Input(key) = events.next()? { if let Event::Input(key) = events.next()? {
match key { match key {
Key::Char(c) => { Key::Char(c) => {
app.on_key(c); app.on_key(c)?;
} }
Key::Up => { Key::Up => {
app.on_up(); app.on_up();

View File

@ -1,35 +1,57 @@
// Copyright (c) 2017-2023, scoobybejesus // Copyright (c) 2017-2023, scoobybejesus
// Redistributions must include the license: https://github.com/scoobybejesus/cryptools/blob/master/LEGAL.txt // Redistributions must include the license: https://github.com/scoobybejesus/cryptools/blob/master/LEGAL.txt
use std::io; use std::error::Error;
use ::tui::Terminal; use ::ratatui::Terminal;
use ::tui::style::{Color, Modifier, Style}; use ::ratatui::style::{Color, Modifier, Style};
use ::tui::widgets::{Widget, Block, Borders, SelectableList, Text, Paragraph, List}; use ::ratatui::text::{Text, Span, Line};
use ::tui::layout::{Layout, Constraint, Direction}; use ratatui::widgets::{Wrap, ListItem};
use ::tui::backend::Backend; use ::ratatui::widgets::{Block, Borders, Paragraph, List};
use ::ratatui::layout::{Layout, Constraint, Direction};
use ::ratatui::backend::Backend;
use crate::mytui::app::{PrintWindow, REPORTS}; use crate::mytui::app::{PrintWindow, REPORTS};
pub fn draw<B: Backend>(terminal: &mut Terminal<B>, app: &PrintWindow) -> Result<(), io::Error> { pub fn draw<B: Backend>(terminal: &mut Terminal<B>, app: &mut PrintWindow) -> Result<(), Box<dyn Error>> {
terminal.draw(|mut f| { terminal.draw(|f| {
let instructions = [ let instructions = vec![
Text::raw("\nPress '"), Line::from(vec![Span::raw("")]),
Text::styled("x", Style::default().fg(Color::Cyan).modifier(Modifier::BOLD)),
Text::raw("' to add the selected report to the list of reports to print/export.\n"), Line::from(vec![
Text::raw("\nPress '"), Span::raw(" Press '"),
Text::styled("d", Style::default().fg(Color::Yellow).modifier(Modifier::BOLD)), Span::styled("x", Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)),
Text::raw("' to delete the selected report from the list of reports to print/export.\n"), Span::raw("' to add the selected report to the list of reports to print/export."),
Text::raw("\nPress '"), ]),
Text::styled("p", Style::default().fg(Color::Green).modifier(Modifier::BOLD)),
Text::raw("' to print/export the selected reports.\n"), Line::from(vec![Span::raw("")]),
Text::raw("\nPress '"),
Text::styled("q", Style::default().fg(Color::Red).modifier(Modifier::BOLD)), Line::from(vec![
Text::raw("' to quit without printing.\n\n"), Span::raw(" Press '"),
Span::styled("d", Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)),
Span::raw("' to delete the selected report from the list of reports to print/export."),
]),
Line::from(vec![Span::raw("")]),
Line::from(vec![
Span::raw(" Press '"),
Span::styled("p", Style::default().fg(Color::Green).add_modifier(Modifier::BOLD)),
Span::raw("' to print/export the selected reports."),
]),
Line::from(vec![Span::raw("")]),
Line::from(vec![
Span::raw(" Press '"),
Span::styled("q", Style::default().fg(Color::Red).add_modifier(Modifier::BOLD)),
Span::raw("' to quit without printing."),
]),
]; ];
let rpts_to_prnt = app.to_print_by_title.iter().map(|&rpt_to_prnt| { let rpts_to_prnt = app.to_print_by_title.iter().map(|&rpt_to_prnt| {
Text::styled( Text::styled(
format!("{}", rpt_to_prnt), format!("{}", rpt_to_prnt),
@ -40,53 +62,60 @@ pub fn draw<B: Backend>(terminal: &mut Terminal<B>, app: &PrintWindow) -> Result
let top_level_chunks = Layout::default() let top_level_chunks = Layout::default()
.constraints([ .constraints([
Constraint::Length(1), Constraint::Length(1),
Constraint::Length(2 + (instructions.len() as u16 / 3 * 2)), // 2 for title "Instructions", plus 3 TEXT array elements/instruction Constraint::Length(instructions.len() as u16 + 2),
Constraint::Length(REPORTS.len() as u16 + 2), Constraint::Length(REPORTS.len() as u16 + 2),
Constraint::Length(rpts_to_prnt.len() as u16 + 2), Constraint::Length(rpts_to_prnt.len() as u16 + 2),
Constraint::Length(1), Constraint::Length(1),
].as_ref()) ].as_ref())
.split(f.size()); .split(f.size());
Paragraph::new(instructions.iter()) let pg1 = Paragraph::new(instructions)
.block( .block(Block::default()
Block::default()
.borders(Borders::NONE) .borders(Borders::NONE)
.title("Instructions") .title(Span::styled(
.title_style(Style::default().fg(Color::Blue).modifier(Modifier::BOLD).modifier(Modifier::UNDERLINED)), "Instructions",
Style::default().fg(Color::LightMagenta).add_modifier(Modifier::BOLD).add_modifier(Modifier::UNDERLINED)
))
) )
.wrap(true) .wrap(Wrap {trim: false});
.render(&mut f, top_level_chunks[1]); f.render_widget(pg1, top_level_chunks[1]);
let level_2_chunks = Layout::default() let level_2_chunks = Layout::default()
.constraints([Constraint::Percentage(10), Constraint::Percentage(80),Constraint::Percentage(10),].as_ref()) .constraints([Constraint::Percentage(10), Constraint::Percentage(80),Constraint::Percentage(10),].as_ref())
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.split(top_level_chunks[2]); .split(top_level_chunks[2]);
SelectableList::default() let report_list_items: Vec<_> = app.tasks.items.iter().map(|i| ListItem::new(*i)).collect();
.block(
Block::default() let items = List::new(report_list_items)
.block(Block::default()
.borders(Borders::ALL) .borders(Borders::ALL)
.title("Reports available for exporting") .title(Span::styled(
.title_style(Style::default().fg(Color::White).modifier(Modifier::BOLD).modifier(Modifier::UNDERLINED)) "Reports available for exporting",
Style::default().fg(Color::White).add_modifier(Modifier::BOLD).add_modifier(Modifier::UNDERLINED)
))
) )
.items(&app.tasks.items) .highlight_style(Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD))
.select(Some(app.tasks.selected)) .highlight_symbol(">");
.highlight_style(Style::default().fg(Color::Yellow).modifier(Modifier::BOLD)) f.render_stateful_widget(items, level_2_chunks[1], &mut app.tasks.state);
.highlight_symbol(">")
.render(&mut f, level_2_chunks[1]);
let level_2_chunks = Layout::default() let level_2_chunks = Layout::default()
.constraints([Constraint::Percentage(10), Constraint::Percentage(80),Constraint::Percentage(10),].as_ref()) .constraints([Constraint::Percentage(10), Constraint::Percentage(80),Constraint::Percentage(10),].as_ref())
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.split(top_level_chunks[3]); .split(top_level_chunks[3]);
List::new(rpts_to_prnt) let rpts_to_prnt: Vec<_> = app.to_print_by_title.iter().map(|i| ListItem::new(*i)).collect();
.block(
Block::default() let to_print = List::new(rpts_to_prnt)
.block(Block::default()
.borders(Borders::ALL) .borders(Borders::ALL)
.title("Reports to be exported") .title(Span::styled(
.title_style(Style::default().fg(Color::LightYellow).modifier(Modifier::BOLD).modifier(Modifier::UNDERLINED)) "Reports to be exported",
) Style::default().fg(Color::LightYellow).add_modifier(Modifier::BOLD).add_modifier(Modifier::UNDERLINED)
.render(&mut f, level_2_chunks[1]); ))
}) );
f.render_widget(to_print, level_2_chunks[1]);
})?;
Ok(())
} }