Skip to content

Commit

Permalink
First moderately working step towards react-tui mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Thiel committed Jun 5, 2019
1 parent 705f4b8 commit 3f3fe77
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 76 deletions.
66 changes: 25 additions & 41 deletions src/interactive/app/eventloop.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::interactive::{
react::Terminal,
sorted_entries,
widgets::{DrawState, HelpPaneState, MainWindow},
widgets::{HelpPaneState, ReactMainWindow},
ByteVisualization, DisplayOptions, EntryDataBundle, SortMode,
};
use dua::{
Expand All @@ -13,7 +14,7 @@ use itertools::Itertools;
use petgraph::Direction;
use std::{io, path::PathBuf};
use termion::input::{Keys, TermReadEventsAndRaw};
use tui::{backend::Backend, widgets::Widget, Terminal};
use tui::backend::Backend;

#[derive(Copy, Clone)]
pub enum FocussedPane {
Expand Down Expand Up @@ -43,7 +44,7 @@ pub struct TerminalApp {
pub traversal: Traversal,
pub display: DisplayOptions,
pub state: AppState,
pub draw_state: DrawState,
pub window: ReactMainWindow,
}

enum CursorDirection {
Expand All @@ -58,24 +59,9 @@ impl TerminalApp {
where
B: Backend,
{
let Self {
traversal,
display,
state,
ref mut draw_state,
} = self;

terminal.draw(|mut f| {
let full_screen = f.size();
MainWindow {
traversal,
display: *display,
state: &state,
draw_state,
}
.render(&mut f, full_screen)
})?;

let mut window = self.window.clone(); // TODO: fix this - we shouldn't have to pass ourselves as props!
terminal.render(&mut window, &*self)?;
self.window = window;
Ok(())
}
pub fn process_events<B, R>(
Expand Down Expand Up @@ -205,8 +191,8 @@ impl TerminalApp {

fn scroll_help(&mut self, direction: CursorDirection) {
use CursorDirection::*;
let scroll = self.draw_state.help_scroll;
self.draw_state.help_scroll = match direction {
let scroll = self.window.draw_state.help_scroll; // TODO: don't do this - make it private when ready
self.window.draw_state.help_scroll = match direction {
Down => scroll.saturating_add(1),
Up => scroll.saturating_sub(1),
PageDown => scroll.saturating_add(10),
Expand Down Expand Up @@ -247,24 +233,22 @@ impl TerminalApp {
terminal.hide_cursor()?;
let mut display_options: DisplayOptions = options.clone().into();
display_options.byte_vis = ByteVisualization::Bar;
let mut window = ReactMainWindow::default();

let traversal = Traversal::from_walk(options, input, move |traversal| {
terminal.draw(|mut f| {
let full_screen = f.size();
let state = AppState {
root: traversal.root_index,
sorting: Default::default(),
message: Some("-> scanning <-".into()),
..Default::default()
};
MainWindow {
traversal,
display: display_options,
state: &state,
draw_state: &mut Default::default(),
}
.render(&mut f, full_screen)
})?;
Ok(())
let state = AppState {
root: traversal.root_index,
sorting: Default::default(),
message: Some("-> scanning <-".into()),
..Default::default()
};
let app = TerminalApp {
traversal: traversal.clone(), // TODO absolutely fix this! We should not rely on this anymore when done
display: display_options,
state,
window: Default::default(),
};
terminal.render(&mut window, &app).map_err(Into::into)
})?;

let sorting = Default::default();
Expand All @@ -282,7 +266,7 @@ impl TerminalApp {
},
display: display_options,
traversal,
draw_state: Default::default(),
window: Default::default(),
})
}
}
4 changes: 2 additions & 2 deletions src/interactive/app_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::interactive::{SortMode, TerminalApp};
use crate::interactive::{react::Terminal, SortMode, TerminalApp};
use dua::{
traverse::{EntryData, Tree, TreeIndex},
ByteFormat, Color, TraversalSorting, WalkOptions,
Expand All @@ -8,7 +8,7 @@ use petgraph::prelude::NodeIndex;
use pretty_assertions::assert_eq;
use std::{ffi::OsStr, ffi::OsString, fmt, path::Path, path::PathBuf};
use termion::input::TermRead;
use tui::{backend::TestBackend, Terminal};
use tui::backend::TestBackend;

const FIXTURE_PATH: &'static str = "tests/fixtures";

Expand Down
27 changes: 10 additions & 17 deletions src/interactive/react.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#[allow(unused)]
mod terminal {
use log::error;
use std::{borrow::Borrow, io};

use std::borrow::BorrowMut;
use tui::{backend::Backend, buffer::Buffer, layout::Rect, widgets::Widget};
use tui::{backend::Backend, buffer::Buffer, layout::Rect};

pub trait Component {
type Props;
Expand All @@ -17,7 +15,7 @@ mod terminal {
where
B: Backend,
{
backend: B,
pub backend: B,
buffers: [Buffer; 2],
current: usize,
hidden_cursor: bool,
Expand Down Expand Up @@ -57,14 +55,6 @@ mod terminal {
&mut self.buffers[self.current]
}

pub fn backend(&self) -> &B {
&self.backend
}

pub fn backend_mut(&mut self) -> &mut B {
&mut self.backend
}

pub fn reconcile_and_flush(&mut self) -> io::Result<()> {
let previous_buffer = &self.buffers[1 - self.current];
let current_buffer = &self.buffers[self.current];
Expand All @@ -90,7 +80,7 @@ mod terminal {

pub fn render<C>(
&mut self,
mut component: &mut C,
component: &mut C,
props: impl Borrow<C::Props>,
) -> io::Result<()>
where
Expand Down Expand Up @@ -121,12 +111,15 @@ mod terminal {
self.hidden_cursor = false;
Ok(())
}
#[allow(unused)]
pub fn get_cursor(&mut self) -> io::Result<(u16, u16)> {
self.backend.get_cursor()
}
#[allow(unused)]
pub fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {
self.backend.set_cursor(x, y)
}
#[allow(unused)]
pub fn clear(&mut self) -> io::Result<()> {
self.backend.clear()
}
Expand Down Expand Up @@ -157,14 +150,14 @@ mod terminal {
impl Component for StatefulComponent {
type Props = usize;

fn render(&mut self, props: impl Borrow<Self::Props>, area: Rect, buf: &mut Buffer) {
fn render(&mut self, props: impl Borrow<Self::Props>, _area: Rect, _buf: &mut Buffer) {
self.x += *props.borrow();
}
}

impl Component for StatelessComponent {
type Props = ComplexProps;
fn render(&mut self, props: impl Borrow<Self::Props>, area: Rect, buf: &mut Buffer) {
fn render(&mut self, _props: impl Borrow<Self::Props>, _area: Rect, _buf: &mut Buffer) {
// does not matter - we want to see it compiles essentially
}
}
Expand All @@ -174,11 +167,11 @@ mod terminal {
let mut term = Terminal::new(TestBackend::new(20, 20)).unwrap();
let mut c = StatefulComponent::default();

term.render(&mut c, 3usize);
term.render(&mut c, 3usize).ok();
assert_eq!(c.x, 3);

let mut c = StatelessComponent::default();
term.render(&mut c, ComplexProps::default());
term.render(&mut c, ComplexProps::default()).ok();
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/interactive/widgets/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use tui::{
widgets::{Block, Paragraph, Text, Widget},
};

#[derive(Default)]
#[derive(Default, Clone)] // TODO: remove Clone derive
pub struct ListState {
/// The index at which the list last started. Used for scrolling
pub start_index: usize,
Expand Down
28 changes: 16 additions & 12 deletions src/interactive/widgets/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::interactive::{
react::Component,
widgets::{Entries, Footer, Header, HelpPane, ListState},
AppState, DisplayOptions, FocussedPane,
FocussedPane, TerminalApp,
};
use dua::traverse::Traversal;
use std::borrow::Borrow;
use tui::style::{Color, Style};
use tui::{
buffer::Buffer,
Expand All @@ -13,22 +15,22 @@ use tui::{

/// The state that can be mutated while drawing
/// This is easiest compared to alternatives, but at least it's restricted to a subset of the state
#[derive(Default)]
#[derive(Default, Clone)] // TODO: remove Clone derive
pub struct DrawState {
entries_list: ListState,
pub help_scroll: u16,
}

pub struct MainWindow<'a, 'b, 'c> {
pub traversal: &'a Traversal,
pub display: DisplayOptions,
pub state: &'b AppState,
pub draw_state: &'c mut DrawState,
#[derive(Default, Clone)] // TODO: remove clone derive
pub struct ReactMainWindow {
pub draw_state: DrawState,
}

impl<'a, 'b, 'c> Widget for MainWindow<'a, 'b, 'c> {
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
let Self {
impl<'a, 'b> Component for ReactMainWindow {
type Props = TerminalApp;

fn render(&mut self, props: impl Borrow<TerminalApp>, area: Rect, buf: &mut Buffer) {
let TerminalApp {
traversal:
Traversal {
tree,
Expand All @@ -38,8 +40,10 @@ impl<'a, 'b, 'c> Widget for MainWindow<'a, 'b, 'c> {
},
display,
state,
ref mut draw_state,
} = self;
..
} = props.borrow();
let draw_state = &mut self.draw_state;

let regions = Layout::default()
.direction(Direction::Vertical)
.constraints(
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ extern crate failure;
extern crate failure_tools;
extern crate structopt;

use crate::interactive::TerminalApp;
use crate::interactive::{react::Terminal, TerminalApp};
use dua::{ByteFormat, Color, TraversalSorting};
use failure::{Error, ResultExt};
use failure_tools::ok_or_exit;
use std::{fs, io, io::Write, path::PathBuf, process};
use structopt::StructOpt;
use termion::{input::TermRead, raw::IntoRawMode, screen::AlternateScreen};
use tui::{backend::TermionBackend, Terminal};
use tui::backend::TermionBackend;

mod interactive;
mod options;
Expand Down
2 changes: 1 addition & 1 deletion src/traverse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct EntryData {
const REFRESH_RATE: Duration = Duration::from_millis(100);

/// The result of the previous filesystem traversal
#[derive(Default, Debug)]
#[derive(Default, Debug, Clone)] // TODO remove clone bound
pub struct Traversal {
/// A tree representing the entire filestem traversal
pub tree: Tree,
Expand Down

0 comments on commit 3f3fe77

Please sign in to comment.