refactor(state): ui-effects

This commit is contained in:
Aram Drevekenin
2020-05-16 18:59:21 +02:00
parent 693af37c16
commit 40b9902a5e
84 changed files with 1140 additions and 462 deletions

View File

@@ -6,7 +6,7 @@ use ::tui::backend::Backend;
use crate::{EventBus, Event};
use crate::state::files::{Folder, FileOrFolder};
use crate::ui::Display;
use crate::state::Board;
use crate::state::{Board, UiEffects};
use crate::state::files::FileTree;
#[derive(Clone, Copy)]
@@ -20,30 +20,31 @@ pub struct App <B>
where B: Backend
{
pub is_running: bool,
pub board: Board,
pub file_tree: FileTree,
pub display: Arc<Mutex<Display<B>>>,
pub loaded: bool, // TODO: better
pub ui_mode: UiMode,
pub event_bus: Arc<Mutex<EventBus>>,
board: Board,
file_tree: FileTree,
display: Display<B>,
event_bus: Arc<Mutex<EventBus>>,
ui_effects: UiEffects,
}
impl <B>App <B>
where B: Backend
{
pub fn new (terminal_backend: B, path_in_filesystem: PathBuf, event_bus: Arc<Mutex<EventBus>>) -> Self {
let display = Arc::new(Mutex::new(Display::new(terminal_backend)));
let display = Display::new(terminal_backend);
let board = Board::new(&Folder::new(&path_in_filesystem));
let base_folder = Folder::new(&path_in_filesystem); // TODO: better
let file_tree = FileTree::new(base_folder, path_in_filesystem);
let ui_effects = UiEffects::new();
App {
is_running: true,
board,
file_tree,
loaded: false,
display,
ui_mode: UiMode::Loading,
event_bus,
ui_effects,
}
}
pub fn render_and_update_board (&mut self) {
@@ -51,27 +52,31 @@ where B: Backend
self.board.change_files(&current_folder); // TODO: rename to change_tiles
self.render();
}
pub fn render (&mut self) {
let path_should_blink = false;
self.display.lock().unwrap().render(&mut self.file_tree, &mut self.board, &self.ui_mode, path_should_blink);
pub fn toggle_scanning_visual_indicator(&mut self) {
self.ui_effects.toggle_scanning_visual_indicator();
}
pub fn render_blinking_path(&mut self) {
let path_should_blink = true;
self.display.lock().unwrap().render(&mut self.file_tree, &mut self.board, &self.ui_mode, path_should_blink);
pub fn render (&mut self) {
self.display.render(&mut self.file_tree, &mut self.board, &self.ui_mode, &self.ui_effects);
}
pub fn set_frame_around_current_path(&mut self) {
self.ui_effects.frame_around_current_path = true;
}
pub fn remove_frame_around_current_path(&mut self) {
self.ui_effects.frame_around_current_path = false;
}
pub fn set_frame_around_space_freed(&mut self) {
self.ui_effects.frame_around_space_freed = true;
}
pub fn remove_frame_around_space_freed(&mut self) {
self.ui_effects.frame_around_space_freed = false;
}
pub fn set_path_to_red(&mut self) {
self.display.lock().unwrap().set_path_to_red();
self.ui_effects.current_path_is_red = true;
}
pub fn reset_path_color(&mut self) {
self.display.lock().unwrap().reset_path_color();
}
pub fn stop_blinking_path(&mut self) {
let path_should_blink = false;
let mut display = self.display.lock().unwrap();
display.render(&mut self.file_tree, &mut self.board, &self.ui_mode, path_should_blink);
pub fn reset_current_path_color(&mut self) {
self.ui_effects.current_path_is_red = false;
}
pub fn start_ui(&mut self) {
self.loaded = true;
self.ui_mode = UiMode::Normal;
self.render_and_update_board();
}
@@ -165,5 +170,6 @@ where B: Backend
self.board.reset_selected_index();
self.ui_mode = UiMode::Normal;
self.render_and_update_board();
self.event_bus.lock().unwrap().publish(Event::FileDeleted);
}
}

View File

@@ -1,9 +1,9 @@
use ::std::sync::{Arc, Weak, Mutex};
use ::std::{thread, time};
use ::std::time;
use ::tui::backend::Backend;
use ::std::thread::park_timeout;
use crate::app::{App, UiMode};
use crate::app::App;
pub struct Blinker <B>
where B: Backend + 'static + Send
@@ -28,19 +28,27 @@ where B: Backend + 'static + Send
let app = self.app.clone();
move || {
if let Some(app) = app.upgrade() {
app.lock().unwrap().render_blinking_path();
let mut app = app.lock().unwrap();
app.set_frame_around_current_path();
app.render();
}
park_timeout(time::Duration::from_millis(50));
if let Some(app) = app.upgrade() {
app.lock().unwrap().stop_blinking_path();
let mut app = app.lock().unwrap();
app.remove_frame_around_current_path();
app.render();
}
park_timeout(time::Duration::from_millis(50));
if let Some(app) = app.upgrade() {
app.lock().unwrap().render_blinking_path();
let mut app = app.lock().unwrap();
app.set_frame_around_current_path();
app.render();
}
park_timeout(time::Duration::from_millis(100));
if let Some(app) = app.upgrade() {
app.lock().unwrap().stop_blinking_path();
let mut app = app.lock().unwrap();
app.remove_frame_around_current_path();
app.render();
}
}
})
@@ -55,22 +63,59 @@ where B: Backend + 'static + Send
if let Some(app) = app.upgrade() {
let mut app = app.lock().unwrap();
app.set_path_to_red();
app.render_blinking_path();
app.set_frame_around_current_path();
app.render();
}
park_timeout(time::Duration::from_millis(50));
if let Some(app) = app.upgrade() {
let mut app = app.lock().unwrap();
app.stop_blinking_path();
app.remove_frame_around_current_path();
app.render();
}
park_timeout(time::Duration::from_millis(50));
if let Some(app) = app.upgrade() {
app.lock().unwrap().render_blinking_path();
let mut app = app.lock().unwrap();
app.set_frame_around_current_path();
app.render();
}
park_timeout(time::Duration::from_millis(100));
if let Some(app) = app.upgrade() {
let mut app = app.lock().unwrap();
app.reset_path_color();
app.stop_blinking_path();
app.reset_current_path_color();
app.remove_frame_around_current_path();
app.render();
}
}
})
}
pub fn blink_space_freed(&self) -> Box<dyn Fn() + Send + Sync>
where B: Backend + 'static + Send
{
Box::new({
let app = self.app.clone();
move || {
if let Some(app) = app.upgrade() {
let mut app = app.lock().unwrap();
app.set_frame_around_space_freed();
app.render();
}
park_timeout(time::Duration::from_millis(50));
if let Some(app) = app.upgrade() {
let mut app = app.lock().unwrap();
app.remove_frame_around_space_freed();
app.render();
}
park_timeout(time::Duration::from_millis(50));
if let Some(app) = app.upgrade() {
let mut app = app.lock().unwrap();
app.set_frame_around_space_freed();
app.render();
}
park_timeout(time::Duration::from_millis(100));
if let Some(app) = app.upgrade() {
let mut app = app.lock().unwrap();
app.remove_frame_around_space_freed();
app.render();
}
}
})

View File

@@ -14,6 +14,7 @@ use tokio::{
pub enum Event {
PathChange,
PathError,
FileDeleted,
}
impl Eq for Event {}

View File

@@ -71,6 +71,7 @@ where
let mut event_bus = event_bus.lock().unwrap();
event_bus.subscribe(Event::PathChange, blinker.blink_path_green());
event_bus.subscribe(Event::PathError, blinker.blink_path_red());
event_bus.subscribe(Event::FileDeleted, blinker.blink_space_freed());
}
let (on_sigwinch, cleanup) = sigwinch();
@@ -137,9 +138,10 @@ where
loop {
{
let mut app = app.lock().unwrap();
if app.loaded {
if let UiMode::Normal = app.ui_mode {
break;
}
app.toggle_scanning_visual_indicator();
app.render_and_update_board();
}
park_timeout(time::Duration::from_millis(100));

View File

@@ -1,4 +1,6 @@
pub mod files;
pub mod tiles;
pub mod ui_effects;
pub use tiles::*;
pub use ui_effects::*;

20
src/state/ui_effects.rs Normal file
View File

@@ -0,0 +1,20 @@
pub struct UiEffects {
pub frame_around_current_path: bool,
pub frame_around_space_freed: bool,
pub current_path_is_red: bool,
pub scanning_visual_indicator: bool,
}
impl UiEffects {
pub fn new () -> Self {
Self {
frame_around_current_path: false,
frame_around_space_freed: false,
current_path_is_red: false,
scanning_visual_indicator: false,
}
}
pub fn toggle_scanning_visual_indicator(&mut self) {
self.scanning_visual_indicator = !self.scanning_visual_indicator;
}
}

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌────────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/cannot_move_into_small_files (2.4M) │ /tmp/bandwhich_tests/cannot_move_into_small_files (2.4M) ││ Space freed: 0
└────────────────────────────────────────────────────────────────┘└──────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/cannot_move_into_small_files (2.4M) │ /tmp/bandwhich_tests/cannot_move_into_small_files (2.4M) Space freed: 0
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[3]"
---
┌── ┐┌ ──
8.2K) /tmp/bandwhich_test /del t _file (8.2K) ││ Space freed: 4.1K
└── ┘└ ──
8.2K) /tmp/bandwhich_tests/delete_file (8. K) Space freed: 4.1K

View File

@@ -0,0 +1,55 @@
---
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[4]"
---
┌─────────────────────────┐
│ │
└─────────────────────────┘

View File

@@ -0,0 +1,55 @@
---
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[5]"
---

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/delete_file (12.3K) │ /tmp/bandwhich_tests/delete_file (12.3K) ││ Space freed: 0
└────────────────────────────────────────────────┘└──────────────────────┘
┌──────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/delete_file (12.3K) │ /tmp/bandwhich_tests/delete_file (12.3K) Space freed: 0
└──────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/delete_file_press_n (12.3K) │ /tmp/bandwhich_tests/delete_file_press_n (12.3K) ││ Space freed: 0
└────────────────────────────────────────────────────────┘└──────────────────────┘
┌──────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/delete_file_press_n (12.3K) │ /tmp/bandwhich_tests/delete_file_press_n (12.3K) Space freed: 0
└──────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[4]"
---
┌── ┐┌ ──
8.2K) /tmp/bandwhich_test /del t _folder (8.2K) ││ Space freed: 4.1K
└── ┘└ ──
8.2K) /tmp/bandwhich_tests/delete_folder (8. K) Space freed: 4.1K

View File

@@ -0,0 +1,55 @@
---
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[5]"
---
┌─────────────────────────┐
│ │
└─────────────────────────┘

View File

@@ -0,0 +1,55 @@
---
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[6]"
---

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌──────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/delete_folder (12.3K) │ /tmp/bandwhich_tests/delete_folder (12.3K) ││ Space freed: 0
└──────────────────────────────────────────────────┘└──────────────────────┘
┌────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/delete_folder (12.3K) │ /tmp/bandwhich_tests/delete_folder (12.3K) Space freed: 0
└────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -3,7 +3,7 @@ source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[4]"
---
/tmp/bandwhich_tests/delete_folder_sma l_wikndow (8 2
/tmp/bandwhich_tests .]folder_small_wikndow (8.2K)

View File

@@ -0,0 +1,55 @@
---
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[5]"
---

View File

@@ -0,0 +1,55 @@
---
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[6]"
---

View File

@@ -3,7 +3,7 @@ source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
/tmp/bandwhich_tests/delete_folder_small_wikndow (12.3K)
/tmp/bandwhich_test[..]older_small_wikndow (12.3K)
┌─────────────────────────────┬────────────────────────────┐
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[4]"
---
┌──── ┐┌ ──
/tmp/bandwhich_test /del t _folder_with_multiple_children (32.8K) /tmp bandwhich_tests/delet _folder_with_multip e_children (32.8K) ││ Space fr ed: 12.3K
└──── ┘└ ──
32 8 /tmp/bandwhich_test /del t _folder_with_multiple_children (32.8K) Space fr ed: 12.3K

View File

@@ -0,0 +1,55 @@
---
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[5]"
---
┌──────────────────────────┐
│ │
└──────────────────────────┘

View File

@@ -0,0 +1,55 @@
---
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[6]"
---

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌─────────────────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/delete_folder_with_multiple_children (45.1K) /tmp/bandwhich_tests/delete_folder_with_multiple_children (45.1K) ││ Space freed: 0
└─────────────────────────────────────────────────────────────────────────┘└──────────────────────┘
┌───────────────────────────────────────────────────────────────────────────────┐
│ Base: /tmp/bandwhich_tests/delete_folder_with_multiple_children (45.1K) /tmp/bandwhich_tests/delete_folder_with_multiple_children (45.1K) Space freed: 0
└───────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬───────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌──────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/eleven_files (458.8K) │ /tmp/bandwhich_tests/eleven_files (458.8K) ││ Space freed: 0
└──────────────────────────────────────────────────┘└──────────────────────┘
┌────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/eleven_files (458.8K) │ /tmp/bandwhich_tests/eleven_files (458.8K) Space freed: 0
└────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────┬────────────────────────────────────────┐
│ │ │ │
│ │ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[3]"
---
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[5]"
---
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌─────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/enter_folder (16.4K) │ /tmp/bandwhich_tests/enter_folder (16.4K) ││ Space freed: 0
└─────────────────────────────────────────────────┘└──────────────────────┘
┌───────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/enter_folder (16.4K) │ /tmp/bandwhich_tests/enter_folder (16.4K) Space freed: 0
└───────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[9]"
---
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[11]"
---
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[4]"
---
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[7]"
---
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌─────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/esc_to_go_up (12.3K) │ /tmp/bandwhich_tests/esc_to_go_up (12.3K) ││ Space freed: 0
└─────────────────────────────────────────────────┘└──────────────────────┘
┌───────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/esc_to_go_up (12.3K) │ /tmp/bandwhich_tests/esc_to_go_up (12.3K) Space freed: 0
└───────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌──────────────────────┐
/tmp/bandwhich_tests/medium_width (20.5K) Space freed: 0
└──────────────────────┘
/tmp/bandwhich_tests/medium_width (20.5K) Space freed: 0
┌─────────────────────────────────────────────────┬────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌──────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/minimum_tile_sides (1.2M) │ /tmp/bandwhich_tests/minimum_tile_sides (1.2M) ││ Space freed: 0
└──────────────────────────────────────────────────────┘└──────────────────────┘
┌────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/minimum_tile_sides (1.2M) │ /tmp/bandwhich_tests/minimum_tile_sides (1.2M) Space freed: 0
└────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────┬──────────────────────────────────────────────────┐
│ │ │ │
│ │ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[4]"
---
┌───────────────────────────────────────────────────────────────────────────────────────────────────
└───────────────────────────────────────────────────────────────────────────────────────────────────
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
└─────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[6]"
---
┌───────────────────────────────────────────────────────────────────────────────────────────────────
└───────────────────────────────────────────────────────────────────────────────────────────────────
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
└─────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌───────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/move_down_and_enter_folder (20.5K) │ /tmp/bandwhich_tests/move_down_and_enter_folder (20.5K) ││ Space freed: 0
└───────────────────────────────────────────────────────────────┘└──────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/move_down_and_enter_folder (20.5K) │ /tmp/bandwhich_tests/move_down_and_enter_folder (20.5K) Space freed: 0
└─────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[5]"
---
┌───────────────────────────────────────────────────────────────────────────────────────────────────
└───────────────────────────────────────────────────────────────────────────────────────────────────
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
└─────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[7]"
---
┌───────────────────────────────────────────────────────────────────────────────────────────────────
└───────────────────────────────────────────────────────────────────────────────────────────────────
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
└─────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌───────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/move_left_and_enter_folder (16.4K) │ /tmp/bandwhich_tests/move_left_and_enter_folder (16.4K) ││ Space freed: 0
└───────────────────────────────────────────────────────────────┘└──────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/move_left_and_enter_folder (16.4K) │ /tmp/bandwhich_tests/move_left_and_enter_folder (16.4K) Space freed: 0
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[4]"
---
┌──────────────────────────────────────────────────────────────────────────────────────────────────
└──────────────────────────────────────────────────────────────────────────────────────────────────
┌────────────────────────────────────────────────────────────────────────────────────────────┐
└────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[6]"
---
┌──────────────────────────────────────────────────────────────────────────────────────────────────
└──────────────────────────────────────────────────────────────────────────────────────────────────
┌────────────────────────────────────────────────────────────────────────────────────────────┐
└────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌────────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/move_right_and_enter_folder (12.3K) │ /tmp/bandwhich_tests/move_right_and_enter_folder (12.3K) ││ Space freed: 0
└────────────────────────────────────────────────────────────────┘└──────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/move_right_and_enter_folder (12.3K) │ /tmp/bandwhich_tests/move_right_and_enter_folder (12.3K) Space freed: 0
└──────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[5]"
---
┌─────────────────────────────────────────────────────────────────────────────────────────────────────
└─────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────────────────────────────────────────────────────┐
└───────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[7]"
---
┌─────────────────────────────────────────────────────────────────────────────────────────────────────
└─────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────────────────────────────────────────────────────┐
└───────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌─────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/move_up_and_enter_folder (24.6K) │ /tmp/bandwhich_tests/move_up_and_enter_folder (24.6K) ││ Space freed: 0
└─────────────────────────────────────────────────────────────┘└──────────────────────┘
┌───────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/move_up_and_enter_folder (24.6K) │ /tmp/bandwhich_tests/move_up_and_enter_folder (24.6K) Space freed: 0
└───────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/noop_when_entering_file (20.5K) │ /tmp/bandwhich_tests/noop_when_entering_file (20.5K) ││ Space freed: 0
└────────────────────────────────────────────────────────────┘└──────────────────────┘
┌──────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/noop_when_entering_file (20.5K) │ /tmp/bandwhich_tests/noop_when_entering_file (20.5K) Space freed: 0
└──────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌──────────────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/noop_when_moving_off_screen_edges (12.3K) /tmp/bandwhich_tests/noop_when_moving_off_screen_edges (12.3K) ││ Space freed: 0
└──────────────────────────────────────────────────────────────────────┘└──────────────────────┘
┌────────────────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/noop_when_moving_off_screen_edges (12.3K) /tmp/bandwhich_tests/noop_when_moving_off_screen_edges (12.3K) Space freed: 0
└────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[9]"
---
┌────────────────────────────────────────────────────────────────────────────────────────
└────────────────────────────────────────────────────────────────────────────────────────
┌──────────────────────────────────────────────────────────────────────────────────┐
└──────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[11]"
---
┌────────────────────────────────────────────────────────────────────────────────────────
└────────────────────────────────────────────────────────────────────────────────────────
┌──────────────────────────────────────────────────────────────────────────────────┐
└──────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[14]"
---
┌────────────────────────────────────────────────────────────────────────────────────────
/tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder (12.3K)
└────────────────────────────────────────────────────────────────────────────────────────
┌──────────────────────────────────────────────────────────────────────────────────┐
/tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder (12.3K)
└──────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[16]"
---
┌────────────────────────────────────────────────────────────────────────────────────────
└────────────────────────────────────────────────────────────────────────────────────────
┌──────────────────────────────────────────────────────────────────────────────────┐
└──────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -3,7 +3,7 @@ source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[3]"
---
/tmp/bandwhich_tests/noop_when pr ssing_esc_at_base folder/subfolder1 (4.1K)
/tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder/subfolder1 (4.1K)

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[4]"
---
┌────────────────────────────────────────────────────────────────────────────────────────
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ │
└────────────────────────────────────────────────────────────────────────────────────────
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[6]"
---
/tmp/bandwhich_tests/noop wh n_pressing_esc_at base_folder (12.3K)
┌────────────────────────────────────────────────────────────────────────────────┐
│ Base: /tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder (12.3K) │ /tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder (12.3K)
└────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[7]"
---
┌────────────────────────────────────────────────────────────────────────────────────────
└────────────────────────────────────────────────────────────────────────────────────────
┌──────────────────────────────────────────────────────────────────────────────────┐
└──────────────────────────────────────────────────────────────────────────────────┘

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌──────────────────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder (12.3K) /tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder (12.3K) ││ Space freed: 0
└──────────────────────────────────────────────────────────────────────────┘└──────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder (12.3K) /tmp/bandwhich_tests/noop_when_pressing_esc_at_base_folder (12.3K) Space freed: 0
└────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌──────────────────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/pressing_delete_with_no_selected_tile (12.3K) /tmp/bandwhich_tests/pressing_delete_with_no_selected_tile (12.3K) ││ Space freed: 0
└──────────────────────────────────────────────────────────────────────────┘└──────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/pressing_delete_with_no_selected_tile (12.3K) /tmp/bandwhich_tests/pressing_delete_with_no_selected_tile (12.3K) Space freed: 0
└────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌───────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/small_files (2.4M) │ /tmp/bandwhich_tests/small_files (2.4M) ││ Space freed: 0
└───────────────────────────────────────────────┘└──────────────────────┘
┌─────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/small_files (2.4M) │ /tmp/bandwhich_tests/small_files (2.4M) Space freed: 0
└─────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌───────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/small_files_non_square (10.0M) │ /tmp/bandwhich_tests/small_files_non_square (10.0M) ││ Space freed: 0
└───────────────────────────────────────────────────────────┘└──────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
Base: /tmp/bandwhich_tests/small_files_non_square (10.0M) │ /tmp/bandwhich_tests/small_files_non_square (10.0M) Space freed: 0
└─────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────┐
│ │ │
│ │ │

View File

@@ -2,9 +2,9 @@
source: src/tests/cases/ui.rs
expression: "&terminal_draw_events_mirror[0]"
---
┌───────────────────────────────────────────────────────────────────┐┌──────────────────────┐
/tmp/bandwhich_tests/two_large_files_one_small_file (20.5K) /tmp/bandwhich_tests/two_large_files_one_small_file (20.5K) ││ Space freed: 0
└───────────────────────────────────────────────────────────────────┘└──────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ Base: /tmp/bandwhich_tests/two_large_files_one_small_file (20.5K) /tmp/bandwhich_tests/two_large_files_one_small_file (20.5K) Space freed: 0
└─────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────┐
│ │ │
│ │ │

View File

@@ -1049,7 +1049,7 @@ fn delete_file() {
start(backend, keyboard_events, temp_dir_path.clone());
let terminal_draw_events_mirror = terminal_draw_events.lock().expect("could not acquire lock on terminal events");
let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor];
let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor];
assert_eq!(
&terminal_events.lock().expect("could not acquire lock on terminal_events")[..],
&expected_terminal_events[..]
@@ -1060,12 +1060,13 @@ fn delete_file() {
assert_eq!(std::fs::metadata(&file_3_path).is_ok(), true, "second different file was untouched");
std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder");
assert_eq!(terminal_draw_events_mirror.len(), 4);
assert_eq!(terminal_draw_events_mirror.len(), 6);
assert_snapshot!(&terminal_draw_events_mirror[0]);
assert_snapshot!(&terminal_draw_events_mirror[1]);
assert_snapshot!(&terminal_draw_events_mirror[2]);
assert_snapshot!(&terminal_draw_events_mirror[3]);
assert_snapshot!(&terminal_draw_events_mirror[4]);
assert_snapshot!(&terminal_draw_events_mirror[5]);
}
#[test]
@@ -1106,7 +1107,7 @@ fn delete_folder() {
start(backend, keyboard_events, temp_dir_path.clone());
let terminal_draw_events_mirror = terminal_draw_events.lock().expect("could not acquire lock on terminal events");
let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor];
let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor];
assert_eq!(
&terminal_events.lock().expect("could not acquire lock on terminal_events")[..],
&expected_terminal_events[..]
@@ -1117,12 +1118,14 @@ fn delete_folder() {
assert_eq!(std::fs::metadata(&file_3_path).is_ok(), true, "second different file was untouched");
std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder");
assert_eq!(terminal_draw_events_mirror.len(), 5);
assert_eq!(terminal_draw_events_mirror.len(), 7);
assert_snapshot!(&terminal_draw_events_mirror[0]);
assert_snapshot!(&terminal_draw_events_mirror[1]);
assert_snapshot!(&terminal_draw_events_mirror[2]);
assert_snapshot!(&terminal_draw_events_mirror[3]);
assert_snapshot!(&terminal_draw_events_mirror[4]);
assert_snapshot!(&terminal_draw_events_mirror[5]);
assert_snapshot!(&terminal_draw_events_mirror[6]);
}
#[test]
@@ -1164,7 +1167,7 @@ fn delete_folder_small_window () {
start(backend, keyboard_events, temp_dir_path.clone());
let terminal_draw_events_mirror = terminal_draw_events.lock().expect("could not acquire lock on terminal events");
let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor];
let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor];
assert_eq!(
&terminal_events.lock().expect("could not acquire lock on terminal_events")[..],
&expected_terminal_events[..]
@@ -1175,12 +1178,14 @@ fn delete_folder_small_window () {
assert_eq!(std::fs::metadata(&file_3_path).is_ok(), true, "second different file was untouched");
std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder");
assert_eq!(terminal_draw_events_mirror.len(), 5);
assert_eq!(terminal_draw_events_mirror.len(), 7);
assert_snapshot!(&terminal_draw_events_mirror[0]);
assert_snapshot!(&terminal_draw_events_mirror[1]);
assert_snapshot!(&terminal_draw_events_mirror[2]);
assert_snapshot!(&terminal_draw_events_mirror[3]);
assert_snapshot!(&terminal_draw_events_mirror[4]);
assert_snapshot!(&terminal_draw_events_mirror[5]);
assert_snapshot!(&terminal_draw_events_mirror[6]);
}
#[test]
@@ -1238,7 +1243,7 @@ fn delete_folder_with_multiple_children() {
start(backend, keyboard_events, temp_dir_path.clone());
let terminal_draw_events_mirror = terminal_draw_events.lock().expect("could not acquire lock on terminal events");
let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor];
let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor];
assert_eq!(
&terminal_events.lock().expect("could not acquire lock on terminal_events")[..],
&expected_terminal_events[..]
@@ -1252,12 +1257,14 @@ fn delete_folder_with_multiple_children() {
assert_eq!(std::fs::metadata(&file_5_path).is_err(), true, "internal file in folder deleted");
std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder");
assert_eq!(terminal_draw_events_mirror.len(), 5);
assert_eq!(terminal_draw_events_mirror.len(), 7);
assert_snapshot!(&terminal_draw_events_mirror[0]);
assert_snapshot!(&terminal_draw_events_mirror[1]);
assert_snapshot!(&terminal_draw_events_mirror[2]);
assert_snapshot!(&terminal_draw_events_mirror[3]);
assert_snapshot!(&terminal_draw_events_mirror[4]);
assert_snapshot!(&terminal_draw_events_mirror[5]);
assert_snapshot!(&terminal_draw_events_mirror[6]);
}
#[test]

View File

@@ -1,4 +1,3 @@
use ::tui::widgets::Widget;
use ::tui::Terminal;
use ::tui::backend::Backend;
@@ -7,15 +6,13 @@ use ::tui::layout::{Layout, Constraint, Direction};
use crate::state::files::FileTree;
use crate::ui::{TitleLine, BottomLine, MessageBox};
use crate::ui::RectangleGrid;
use crate::state::Board;
use crate::state::{UiEffects, Board};
use crate::UiMode;
pub struct Display <B>
where B: Backend
{
terminal: Terminal<B>,
scan_boolean: bool, // TODO: elsewhere - this is to determine whether "Sanning folder..." should be bold or not
pub path_should_be_red: bool, // TODO: elsewhere - this is to determine if the path title and optional box should be red (eg. pressing ESC at base folder)
terminal: Terminal<B>
}
impl <B> Display<B>
@@ -25,18 +22,9 @@ where B: Backend
let mut terminal = Terminal::new(terminal_backend).expect("failed to create terminal");
terminal.clear().expect("failed to clear terminal");
terminal.hide_cursor().expect("failed to hide cursor");
Display { terminal, scan_boolean: true, path_should_be_red: false }
Display { terminal }
}
pub fn set_path_to_red (&mut self) {
self.path_should_be_red = true;
}
pub fn reset_path_color (&mut self) {
self.path_should_be_red = false;
}
pub fn render (&mut self, file_tree: &mut FileTree, board: &mut Board, ui_mode: &UiMode, path_should_blink: bool) { // TODO: change name to render_ui
let path_should_be_red = self.path_should_be_red;
let scan_boolean = self.scan_boolean;
self.scan_boolean = !scan_boolean;
pub fn render (&mut self, file_tree: &mut FileTree, board: &mut Board, ui_mode: &UiMode, ui_effects: &UiEffects) {
self.terminal.draw(|mut f| {
let current_path = file_tree.get_current_path();
let current_path_size = file_tree.get_current_folder_size();
@@ -61,31 +49,31 @@ where B: Backend
let path_in_filesystem = &file_tree.path_in_filesystem;
match ui_mode {
UiMode::Loading => {
if path_should_blink {
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed, scan_boolean, path_should_be_red).set_path_blink(true).show_loading().render(&mut f, chunks[0])
} else {
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed, scan_boolean, path_should_be_red).set_path_blink(false).show_loading().render(&mut f, chunks[0]);
}
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed)
.scanning_should_be_bold(ui_effects.scanning_visual_indicator)
.frame_around_current_path(ui_effects.frame_around_current_path)
.current_path_is_red(ui_effects.current_path_is_red)
.show_loading()
.render(&mut f, chunks[0]);
RectangleGrid::new((&board.rectangles).to_vec()).render(&mut f, chunks[1]);
BottomLine::new().hide_delete().render(&mut f, chunks[2]);
},
UiMode::Normal => {
if path_should_blink {
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed, scan_boolean, path_should_be_red).set_path_blink(true).render(&mut f, chunks[0]);
} else {
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed, scan_boolean, path_should_be_red).set_path_blink(false).render(&mut f, chunks[0]);
}
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed)
.current_path_is_red(ui_effects.current_path_is_red)
.frame_around_current_path(ui_effects.frame_around_current_path)
.frame_around_space_freed(ui_effects.frame_around_space_freed)
.render(&mut f, chunks[0]);
RectangleGrid::new((&board.rectangles).to_vec()).render(&mut f, chunks[1]);
BottomLine::new().render(&mut f, chunks[2]);
}
UiMode::DeleteFile => {
let currently_selected_name = &board.currently_selected().expect("could not find currently selected file to delete").file_metadata.name;
let file_to_delete = file_tree.item_in_current_folder(&currently_selected_name).expect("could not find file to delete in current folder");
if path_should_blink {
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed, scan_boolean, path_should_be_red).set_path_blink(true).render(&mut f, chunks[0]);
} else {
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed, scan_boolean, path_should_be_red).set_path_blink(false).render(&mut f, chunks[0]);
}
TitleLine::new(&path_in_filesystem, base_path_size, &current_path, current_path_size, file_tree.space_freed)
.current_path_is_red(ui_effects.current_path_is_red)
.frame_around_current_path(ui_effects.frame_around_current_path)
.render(&mut f, chunks[0]);
RectangleGrid::new((&board.rectangles).to_vec()).render(&mut f, chunks[1]);
BottomLine::new().render(&mut f, chunks[2]);
MessageBox::new(file_to_delete, &current_path).render(&mut f, full_screen);

5
src/ui/format/mod.rs Normal file
View File

@@ -0,0 +1,5 @@
mod truncate_middle;
mod display_size;
pub use truncate_middle::*;
pub use display_size::*;

View File

@@ -0,0 +1,15 @@
pub fn truncate_middle(row: &str, max_length: u16) -> String {
if max_length < 6 {
String::from("") // TODO: make sure this never happens
} else if row.len() as u16 > max_length {
let first_slice = &row[0..(max_length as usize / 2) - 2];
let second_slice = &row[(row.len() - (max_length / 2) as usize + 2)..row.len()];
if max_length % 2 == 0 {
format!("{}[...]{}", first_slice, second_slice)
} else {
format!("{}[..]{}", first_slice, second_slice)
}
} else {
row.to_string()
}
}

View File

@@ -5,6 +5,7 @@ use tui::widgets::{Widget};
use std::path::PathBuf;
use crate::ui::{draw_symbol_with_style, boundaries};
use crate::ui::format::truncate_middle;
use crate::state::files::FileOrFolder;
pub struct MessageBox<'a> {
@@ -41,23 +42,6 @@ fn draw_rect_on_grid (buf: &mut Buffer, rect: Rect) {
}
}
// TODO: merge with identical function elsewhere
fn truncate_middle(row: &str, max_length: u16) -> String {
if max_length < 6 {
String::from("") // TODO: make sure this never happens
} else if row.len() as u16 > max_length {
let first_slice = &row[0..(max_length as usize / 2) - 2];
let second_slice = &row[(row.len() - (max_length / 2) as usize + 2)..row.len()];
if max_length % 2 == 0 {
format!("{}[...]{}", first_slice, second_slice)
} else {
format!("{}[..]{}", first_slice, second_slice)
}
} else {
row.to_string()
}
}
impl<'a> Widget for MessageBox<'a> {
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
let (width, height) = if area.width > 150 {

View File

@@ -1,14 +1,14 @@
pub mod rectangle_grid;
mod draw_symbol;
mod display_size;
mod title_line;
mod format;
mod title;
mod bottom_line;
mod message_box;
mod display;
pub use rectangle_grid::*;
pub use display_size::*;
pub use title_line::*;
pub use format::*;
pub use title::*;
pub use bottom_line::*;
pub use display::*;
pub use draw_symbol::*;

View File

@@ -4,7 +4,8 @@ use tui::style::{Style, Color, Modifier};
use tui::widgets::{Widget};
use crate::state::FileType;
use crate::ui::{draw_symbol, boundaries, DisplaySize, DisplaySizeRounded};
use crate::ui::{draw_symbol, boundaries};
use crate::ui::format::{DisplaySize, DisplaySizeRounded, truncate_middle};
use crate::state::FileRect;
pub const MINIMUM_HEIGHT: u16 = 2;
@@ -21,22 +22,6 @@ impl<'a> RectangleGrid {
}
}
fn truncate_middle(row: &str, max_length: u16) -> String {
if max_length < 6 {
String::from("") // TODO: make sure this never happens
} else if row.len() as u16 > max_length {
let first_slice = &row[0..(max_length as usize / 2) - 2];
let second_slice = &row[(row.len() - (max_length / 2) as usize + 2)..row.len()];
if max_length % 2 == 0 {
format!("{}[...]{}", first_slice, second_slice)
} else {
format!("{}[..]{}", first_slice, second_slice)
}
} else {
row.to_string()
}
}
fn truncate_size_line (size: &u64, percentage: &f64, max_length: &u16) -> String {
let display_size = DisplaySize(*size as f64);
let display_size_rounded = DisplaySizeRounded(*size as f64); // TODO: better

75
src/ui/title/base_path.rs Normal file
View File

@@ -0,0 +1,75 @@
use tui::layout::Rect;
use tui::style::{Style, Color, Modifier};
use ::tui::layout::Alignment;
use tui::widgets::{Widget};
use ::tui::terminal::Frame;
use ::tui::backend::Backend;
use std::path::PathBuf;
use ::tui::widgets::{Block, Borders, Paragraph, Text};
use crate::ui::format::{DisplaySize, truncate_middle};
pub struct BasePath {
path: String,
size: DisplaySize,
bold: bool,
loading: bool,
}
impl BasePath {
pub fn new (path: &PathBuf, size: u64) -> Self {
let size = DisplaySize(size as f64);
let path = path.clone().into_os_string().into_string().expect("could not convert os string to string");
BasePath {
path,
size,
bold: true,
loading: false,
}
}
pub fn bold(mut self, should_be_bold: bool) -> Self {
if !self.loading {
self.bold = true;
} else {
self.bold = should_be_bold;
}
self
}
pub fn loading(mut self, should_be_loading: bool) -> Self {
if !should_be_loading {
self.bold = true;
}
self.loading = should_be_loading;
self
}
pub fn len (&self) -> usize {
self.text(None).len()
}
fn text (&self, max_len: Option<u16>) -> String {
let size_string_len = &self.size.to_string().len() + 2; // 2 == two parentheses chars
let path_text = match max_len {
Some(len) => truncate_middle(&self.path, len - size_string_len as u16),
None => String::from(&self.path),
};
// TODO: truncate folder numes in full path a la fish
if self.loading {
format!("Scanning: {} ({})", path_text, &self.size)
} else {
format!("Base: {} ({})", path_text, &self.size)
}
}
pub fn render(&self, frame: &mut Frame<impl Backend>, rect: Rect) {
let text = self.text(Some(rect.width - 10)); // 10 so that text will not overflow
let text_display = if self.bold {
[ Text::styled(text, Style::default().fg(Color::Yellow).modifier(Modifier::BOLD)) ]
} else {
[ Text::styled(text, Style::default().fg(Color::Yellow)) ]
};
Paragraph::new(text_display.iter())
.block(Block::default().borders(Borders::ALL).border_style(Style::default().fg(Color::Yellow).modifier(Modifier::BOLD)))
.style(Style::default().fg(Color::Yellow))
.alignment(Alignment::Center)
.render(frame, rect);
}
}

View File

@@ -0,0 +1,78 @@
use ::tui::layout::Rect;
use ::tui::style::{Style, Color, Modifier};
use ::tui::layout::Alignment;
use ::tui::widgets::{Widget};
use ::tui::terminal::Frame;
use ::tui::backend::Backend;
use ::std::path::PathBuf;
use ::tui::widgets::{Block, Borders, Paragraph, Text};
use crate::ui::format::{DisplaySize, truncate_middle};
pub struct CurrentPath {
path: String,
size: DisplaySize,
frame: bool,
red: bool,
}
impl CurrentPath {
pub fn new (path: &PathBuf, size: u64) -> Self {
let size = DisplaySize(size as f64);
let path = path.clone().into_os_string().into_string().expect("could not convert os string to string");
CurrentPath {
path,
size,
frame: false,
red: false,
}
}
pub fn frame(mut self, should_have_frame: bool) -> Self {
self.frame = should_have_frame;
self
}
pub fn red(mut self, should_be_red: bool) -> Self {
self.red = should_be_red;
self
}
pub fn len (&self) -> usize {
self.text(None).len()
}
fn text (&self, max_len: Option<u16>) -> String {
let size_string_len = &self.size.to_string().len() + 2; // 2 == two parentheses chars
// TODO: truncate folder numes in full path a la fish
match max_len {
Some(len) => format!("{} ({})", truncate_middle(&self.path, len - size_string_len as u16), &self.size),
None => format!("{} ({})", &self.path, &self.size),
}
}
pub fn render(&self, frame: &mut Frame<impl Backend>, rect: Rect) {
let text = self.text(Some(rect.width - 10)); // 10 so that text will not overflow
let color = if self.red {
Color::Red
} else {
Color::Green
};
if self.frame {
let text_display = [
Text::styled(text, Style::default().fg(color).modifier(Modifier::BOLD))
];
Paragraph::new(text_display.iter())
.block(Block::default().borders(Borders::ALL).border_style(Style::default().fg(color).modifier(Modifier::BOLD)))
.style(Style::default().fg(color))
.alignment(Alignment::Center)
.render(frame, rect);
} else {
let text_display = [
Text::raw("\n"), // this isn't inside a block, so it needs a gentle push to be centered vertically
Text::styled(text, Style::default().fg(color).modifier(Modifier::BOLD))
];
Paragraph::new(text_display.iter())
.block(Block::default().borders(Borders::NONE))
.style(Style::default())
.alignment(Alignment::Center)
.render(frame, rect);
};
}
}

9
src/ui/title/mod.rs Normal file
View File

@@ -0,0 +1,9 @@
mod base_path;
mod current_path;
mod space_freed;
mod title_line;
pub use base_path::*;
pub use current_path::*;
pub use space_freed::*;
pub use title_line::*;

View File

@@ -0,0 +1,58 @@
use ::tui::layout::Rect;
use ::tui::style::{Style, Color, Modifier};
use ::tui::layout::Alignment;
use ::tui::widgets::{Widget};
use ::tui::terminal::Frame;
use ::tui::backend::Backend;
use ::tui::widgets::{Block, Borders, Paragraph, Text};
use crate::ui::DisplaySize;
pub struct SpaceFreed {
size: DisplaySize,
frame: bool,
}
impl SpaceFreed {
pub fn new (size: u64) -> Self {
let size = DisplaySize(size as f64);
SpaceFreed {
size,
frame: false,
}
}
pub fn frame(mut self, should_have_frame: bool) -> Self {
self.frame = should_have_frame;
self
}
pub fn len (&self) -> usize {
self.text().len()
}
fn text (&self) -> String {
format!("Space freed: {}", self.size)
}
pub fn render(&self, frame: &mut Frame<impl Backend>, rect: Rect) {
let text = self.text();
if self.frame {
let text_display = [
Text::styled(text, Style::default().fg(Color::Yellow).modifier(Modifier::BOLD))
];
Paragraph::new(text_display.iter())
.block(Block::default().borders(Borders::ALL).border_style(Style::default().fg(Color::Yellow).modifier(Modifier::BOLD)))
.style(Style::default().fg(Color::Yellow))
.alignment(Alignment::Center)
.render(frame, rect);
} else {
let text_display = [
Text::raw("\n"), // this isn't inside a block, so it needs a gentle push to be centered vertically
Text::styled(text, Style::default().fg(Color::Yellow).modifier(Modifier::BOLD))
];
Paragraph::new(text_display.iter())
.block(Block::default().borders(Borders::NONE))
.style(Style::default())
.alignment(Alignment::Center)
.render(frame, rect);
};
}
}

161
src/ui/title/title_line.rs Normal file
View File

@@ -0,0 +1,161 @@
use ::tui::layout::Rect;
use ::tui::terminal::Frame;
use ::tui::backend::Backend;
use ::tui::layout::{Layout, Constraint, Direction};
use ::std::path::PathBuf;
use crate::ui::title::BasePath;
use crate::ui::title::CurrentPath;
use crate::ui::title::SpaceFreed;
fn three_part_layout (first_part_len: u16, second_part_len: u16, third_part_len: u16, rect: Rect) -> (Option<Rect>, Option<Rect>, Option<Rect>) {
if first_part_len + second_part_len + third_part_len <= rect.width {
let remainder = rect.width - first_part_len - second_part_len - third_part_len;
let parts = Layout::default()
.direction(Direction::Horizontal)
.margin(0)
.constraints(
[
Constraint::Length(first_part_len),
Constraint::Length(second_part_len + remainder),
Constraint::Length(third_part_len),
].as_ref()
)
.split(rect);
(Some(parts[0]), Some(parts[1]), Some(parts[2]))
} else if second_part_len + third_part_len <= rect.width {
let remainder = rect.width - second_part_len - third_part_len;
let parts = Layout::default()
.direction(Direction::Horizontal)
.margin(0)
.constraints(
[
Constraint::Length(second_part_len + remainder),
Constraint::Length(third_part_len),
].as_ref()
)
.split(rect);
(Some(parts[0]), Some(parts[1]), None)
} else {
(Some(rect), None, None)
}
}
fn two_part_layout (first_part_len: u16, second_part_len: u16, rect: Rect) -> (Option<Rect>, Option<Rect>) {
if first_part_len + second_part_len <= rect.width {
let remainder = rect.width - first_part_len - second_part_len;
let parts = Layout::default()
.direction(Direction::Horizontal)
.margin(0)
.constraints(
[
Constraint::Length(first_part_len),
Constraint::Length(second_part_len + remainder),
].as_ref()
)
.split(rect);
(Some(parts[0]), Some(parts[1]))
} else {
(Some(rect), None)
}
}
pub struct TitleLine <'a> {
base_path: &'a PathBuf,
base_path_size: u64,
current_path: &'a PathBuf,
current_path_size: u64,
space_freed: u64,
show_loading: bool,
scanning_should_be_bold: bool,
frame_around_current_path: bool,
frame_around_space_freed: bool,
current_path_is_red: bool,
}
impl <'a>TitleLine<'a> {
pub fn new(base_path: &'a PathBuf, base_path_size: u64, current_path: &'a PathBuf, current_path_size: u64, space_freed: u64) -> Self {
Self {
base_path,
base_path_size,
current_path,
current_path_size,
space_freed,
scanning_should_be_bold: false,
show_loading: false,
frame_around_current_path: false,
frame_around_space_freed: false,
current_path_is_red: false,
}
}
pub fn show_loading(mut self) -> Self {
self.show_loading = true;
self
}
pub fn frame_around_current_path(mut self, frame_around_current_path: bool) -> Self {
self.frame_around_current_path = frame_around_current_path;
self
}
pub fn frame_around_space_freed(mut self, frame_around_space_freed: bool) -> Self {
self.frame_around_space_freed = frame_around_space_freed;
self
}
pub fn current_path_is_red(mut self, current_path_is_red: bool) -> Self {
self.current_path_is_red = current_path_is_red;
self
}
pub fn scanning_should_be_bold(mut self, scanning_should_be_bold: bool) -> Self {
self.scanning_should_be_bold = scanning_should_be_bold;
self
}
pub fn render(&self, frame: &mut Frame<impl Backend>, rect: Rect) {
let base_path = BasePath::new(&self.base_path, self.base_path_size)
.loading(self.show_loading)
.bold(self.scanning_should_be_bold);
let current_path = CurrentPath::new(&self.current_path, self.current_path_size)
.frame(self.frame_around_current_path)
.red(self.current_path_is_red);
let space_freed = SpaceFreed::new(self.space_freed)
.frame(self.frame_around_space_freed);
let min_current_path_len = current_path.len() as u16 + 10;
let min_base_path_len = base_path.len() as u16 + 10;
let min_space_freed_text_len = space_freed.len() as u16 + 10;
if self.show_loading {
let layout_parts = two_part_layout(min_base_path_len, min_current_path_len, rect);
match layout_parts {
(Some(left), Some(right)) => {
base_path.render(frame, left);
current_path.render(frame, right);
},
(Some(rect), None) => {
current_path.render(frame, rect);
},
_ => {
unreachable!("wrong order of layout parts");
}
}
} else {
let layout_parts = three_part_layout(min_base_path_len, min_current_path_len, min_space_freed_text_len, rect);
match layout_parts {
(Some(left), Some(middle), Some(right)) => {
base_path.render(frame, left);
current_path.render(frame, middle);
space_freed.render(frame, right);
},
(Some(left), Some(right), None) => {
current_path.render(frame, left);
space_freed.render(frame, right);
}
(Some(rect), None, None) => {
current_path.render(frame, rect);
}
_ => {
unreachable!("wrong order of layout parts");
}
}
}
}
}

View File

@@ -1,203 +0,0 @@
use tui::layout::Rect;
use tui::style::{Style, Color, Modifier};
use ::tui::layout::Alignment;
use tui::widgets::{Widget};
use ::tui::terminal::Frame;
use ::tui::backend::Backend;
use ::tui::layout::{Layout, Constraint, Direction};
use std::path::PathBuf;
use ::tui::widgets::{Block, Borders, Paragraph, Text};
use crate::ui::DisplaySize;
// TODO: merge with identical function elsewhere
fn truncate_middle(row: &str, max_length: u16) -> String {
if max_length < 6 {
String::from("") // TODO: make sure this never happens
} else if row.len() as u16 > max_length {
let first_slice = &row[0..(max_length as usize / 2) - 2];
let second_slice = &row[(row.len() - (max_length / 2) as usize + 2)..row.len()];
if max_length % 2 == 0 {
format!("{}[...]{}", first_slice, second_slice)
} else {
format!("{}[..]{}", first_slice, second_slice)
}
} else {
row.to_string()
}
}
// these have to be macros because Text isn't Sized
macro_rules! render_boxless_title {
( $text: ident, $frame: ident, $rect: ident ) => {{
Paragraph::new($text.iter())
.block(Block::default().borders(Borders::NONE))
.style(Style::default())
.alignment(Alignment::Center)
.render($frame, $rect);
}};
}
macro_rules! render_boxed_title {
( $text: ident, $frame: ident, $rect: ident, $color: ident ) => {{
Paragraph::new($text.iter())
.block(Block::default().borders(Borders::ALL).border_style(Style::default().fg($color).modifier(Modifier::BOLD)))
.style(Style::default().fg($color))
.alignment(Alignment::Center)
.render($frame, $rect);
}};
}
macro_rules! render_current_path {
( $text: ident, $frame: ident, $rect: ident, $path_should_blink: ident, $path_should_be_red: ident ) => {{
let color = if $path_should_be_red {
Color::Red
} else {
Color::Green
};
if $path_should_blink {
let current_path_display = [
Text::styled($text, Style::default().fg(color).modifier(Modifier::BOLD))
];
render_boxed_title!(current_path_display, $frame, $rect, color);
} else {
let current_path_display = [
Text::raw("\n"), // this isn't inside a block, so it needs a gentle push to be centered vertically
Text::styled($text, Style::default().fg(color).modifier(Modifier::BOLD))
];
render_boxless_title!(current_path_display, $frame, $rect);
};
}}
}
pub struct TitleLine {
base_path: String,
base_path_size: DisplaySize,
current_path: String,
current_path_size: DisplaySize,
space_freed: DisplaySize,
show_loading: bool,
scan_boolean: bool,
path_should_blink: bool,
path_should_be_red: bool,
}
impl TitleLine {
pub fn new(base_path: &PathBuf, base_path_size: u64, current_path: &PathBuf, current_path_size: u64, space_freed: u64, scan_boolean: bool, path_should_be_red: bool) -> Self {
let base_path = base_path.clone().into_os_string().into_string().expect("could not convert os string to string");
let current_path = current_path.clone().into_os_string().into_string().expect("could not convert os string to string");
let base_path_size = DisplaySize(base_path_size as f64);
let current_path_size = DisplaySize(current_path_size as f64);
let space_freed = DisplaySize(space_freed as f64);
Self { base_path, base_path_size, current_path, current_path_size, space_freed, scan_boolean, show_loading: false, path_should_blink: false, path_should_be_red }
}
pub fn show_loading(mut self) -> Self {
self.show_loading = true;
self
}
pub fn set_path_blink(mut self, path_should_blink: bool) -> Self {
self.path_should_blink = path_should_blink;
self
}
pub fn render(&self, frame: &mut Frame<impl Backend>, rect: Rect) {
let current_path_text = format!("{} ({})", &self.current_path, &self.current_path_size);
let path_should_blink = self.path_should_blink;
let path_should_be_red = self.path_should_be_red;
let box_border_color = Color::Yellow;
let base_path_text = format!("{} ({})", &self.base_path, &self.base_path_size);
let base_path_display = [
Text::styled(&base_path_text, Style::default().fg(Color::Yellow).modifier(Modifier::BOLD))
];
let space_freed_text = format!("Space freed: {}", &self.space_freed);
let space_freed_display = [
Text::styled(format!("Space freed: {}", &self.space_freed), Style::default().fg(Color::Yellow).modifier(Modifier::BOLD))
];
let loading_text = String::from("Scanning folder...");
let loading_display = if self.scan_boolean {
[
Text::styled(loading_text.clone(), Style::default().fg(Color::Yellow).modifier(Modifier::BOLD))
]
} else {
[
Text::styled(loading_text.clone(), Style::default().fg(Color::Yellow))
]
};
let min_current_path_len = current_path_text.len() as u16 + 10;
let min_base_path_len = base_path_text.len() as u16 + 10;
let min_space_freed_text_len = space_freed_text.len() as u16 + 10;
let min_loading_text_len = loading_text.len() as u16 + 10;
if self.show_loading {
if min_current_path_len + min_loading_text_len <= rect.width {
let remainder = rect.width - min_space_freed_text_len - min_current_path_len;
let parts = Layout::default()
.direction(Direction::Horizontal)
.margin(0)
.constraints(
[
Constraint::Length(min_current_path_len + remainder),
Constraint::Length(min_loading_text_len),
].as_ref()
)
.split(rect);
let (left, right) = (parts[0], parts[1]);
render_current_path!(current_path_text, frame, left, path_should_blink, path_should_be_red);
render_boxed_title!(loading_display, frame, right, box_border_color);
} else {
// TODO: merge with below final else
let current_path_size_len = &self.current_path_size.to_string().len() + 2; // 2 == two parentheses chars
// TODO: truncate folder numes in full path a la fish
let current_path_text = format!("{} ({})", truncate_middle(&self.current_path, rect.width - current_path_size_len as u16), &self.current_path_size);
render_current_path!(current_path_text, frame, rect, path_should_blink, path_should_be_red);
}
} else if min_current_path_len + min_base_path_len + min_space_freed_text_len <= rect.width {
let remainder = rect.width - min_space_freed_text_len - min_base_path_len - min_current_path_len;
let parts = Layout::default()
.direction(Direction::Horizontal)
.margin(0)
.constraints(
[
Constraint::Length(min_current_path_len + remainder),
Constraint::Length(min_base_path_len),
Constraint::Length(min_space_freed_text_len),
].as_ref()
)
.split(rect);
let (left, middle, right) = (parts[0], parts[1], parts[2]);
render_current_path!(current_path_text, frame, left, path_should_blink, path_should_be_red);
render_boxed_title!(base_path_display, frame, middle, box_border_color);
render_boxed_title!(space_freed_display, frame, right, box_border_color);
} else if min_current_path_len + min_space_freed_text_len <= rect.width {
let remainder = rect.width - min_space_freed_text_len - min_current_path_len;
let parts = Layout::default()
.direction(Direction::Horizontal)
.margin(0)
.constraints(
[
Constraint::Length(min_current_path_len + remainder),
Constraint::Length(min_space_freed_text_len),
].as_ref()
)
.split(rect);
let (left, right) = (parts[0], parts[1]);
render_current_path!(current_path_text, frame, left, path_should_blink, path_should_be_red);
render_boxed_title!(space_freed_display, frame, right, box_border_color);
} else {
let current_path_size_len = &self.current_path_size.to_string().len() + 2; // 2 == two parentheses chars
// TODO: truncate folder numes in full path a la fish
let current_path_text = format!("{} ({})", truncate_middle(&self.current_path, rect.width - current_path_size_len as u16), &self.current_path_size);
render_current_path!(current_path_text, frame, rect, path_should_blink, path_should_be_red);
}
}
}