Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace tui_react::Terminal with tui::Terminal #246

Merged
merged 2 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
384 changes: 195 additions & 189 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ include = ["src/**/*", "Cargo.*", "LICENSE", "README.md", "CHANGELOG.md", "!**/t

[features]
default = ["tui-crossplatform", "trash-move"]
tui-crossplatform = ["crosstermion/tui-react-crossterm", "tui", "tui-react", "open", "unicode-segmentation", "unicode-width"]

tui-crossplatform = ["crosstermion/tui-crossterm", "tui", "tui-react", "open", "unicode-segmentation", "unicode-width"]
trash-move = ["trash"]

[dependencies]
Expand Down
64 changes: 58 additions & 6 deletions src/interactive/app/eventloop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ use dua::{
WalkResult,
};
use std::path::PathBuf;
use tui::backend::Backend;
use tui_react::Terminal;
use tui::{backend::Backend, buffer::Buffer, layout::Rect, widgets::Widget, Terminal};

use super::state::{AppState, Cursor};
use super::tree_view::TreeView;
Expand Down Expand Up @@ -569,6 +568,55 @@ enum Refresh {
Selected,
}

/// A [`Widget`] that renders by calling a function.
///
/// The `FunctionWidget` struct holds a function that renders into a portion of
/// a [`Buffer`] designated by a [`Rect`].
///
/// This widget can be used to create custom UI elements that are defined by a
/// rendering function. and allows for rendering functions that do not implement
/// the [`Widget`] trait.
struct FunctionWidget<F>
where
F: FnOnce(Rect, &mut Buffer),
{
render: F,
}

impl<F> FunctionWidget<F>
where
F: FnOnce(Rect, &mut Buffer),
{
/// Creates a new [`FunctionWidget`] with the given rendering function.
///
/// The rendering function must have the signature `FnOnce(Rect, &mut
/// Buffer)`, where:
/// - [`Rect`] represents the available space for rendering.
/// - [`Buffer`] is the buffer to write the rendered content to.
///
/// The `FunctionWidget` can then be used to render the provided function in
/// a user interface.
fn new(function: F) -> FunctionWidget<F>
where
F: FnOnce(Rect, &mut Buffer),
{
FunctionWidget { render: function }
}
}

/// Implements the [`Widget`] trait for [`FunctionWidget`].
///
/// The implementation simply calls the provided render function with the given
/// `Rect` and `Buffer`.
impl<F> Widget for FunctionWidget<F>
where
F: FnOnce(Rect, &mut Buffer),
{
fn render(self, area: Rect, buf: &mut Buffer) {
(self.render)(area, buf);
}
}

pub fn draw_window<B>(
window: &mut MainWindow,
props: MainWindowProps<'_>,
Expand All @@ -578,10 +626,14 @@ pub fn draw_window<B>(
where
B: Backend,
{
let area = terminal.pre_render()?;
window.render(props, area, terminal, cursor);
terminal.post_render()?;

terminal.draw(|frame| {
frame.render_widget(
FunctionWidget::new(|area, buf| {
window.render(props, area, buf, cursor);
}),
frame.size(),
);
})?;
Ok(())
}

Expand Down
3 changes: 1 addition & 2 deletions src/interactive/app/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use crate::interactive::{
use crosstermion::input::Key;
use dua::traverse::TreeIndex;
use std::{fs, io, path::PathBuf};
use tui::backend::Backend;
use tui_react::Terminal;
use tui::{backend::Backend, Terminal};

use super::state::{AppState, FocussedPane::*};

Expand Down
3 changes: 1 addition & 2 deletions src/interactive/app/terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
traverse::{Traversal, TraversalStats},
ByteFormat, WalkOptions, WalkResult,
};
use tui::prelude::Backend;
use tui_react::Terminal;
use tui::{backend::Backend, Terminal};

use crate::interactive::widgets::MainWindow;

Expand All @@ -18,7 +17,7 @@
/// State and methods representing the interactive disk usage analyser for the terminal
pub struct TerminalApp {
pub traversal: Traversal,
pub stats: TraversalStats,

Check warning on line 20 in src/interactive/app/terminal.rs

View workflow job for this annotation

GitHub Actions / Windows (nightly)

field `stats` is never read
pub display: DisplayOptions,
pub state: AppState,
pub window: MainWindow,
Expand Down
3 changes: 1 addition & 2 deletions src/interactive/app/tests/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
io::ErrorKind,
path::{Path, PathBuf},
};
use tui::backend::TestBackend;
use tui_react::Terminal;
use tui::{backend::TestBackend, Terminal};

use crate::interactive::{app::tests::FIXTURE_PATH, terminal::TerminalApp};

Expand Down Expand Up @@ -215,7 +214,7 @@
Terminal::new(TestBackend::new(40, 20))
}

pub fn initialized_app_and_terminal_from_paths(

Check warning on line 217 in src/interactive/app/tests/utils.rs

View workflow job for this annotation

GitHub Actions / Windows (nightly)

function `initialized_app_and_terminal_from_paths` is never used
fixture_paths: &[PathBuf],
) -> Result<(Terminal<TestBackend>, TerminalApp), Error> {
fn to_path_buf(p: &Path) -> PathBuf {
Expand Down
26 changes: 11 additions & 15 deletions src/interactive/widgets/glob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ use crosstermion::input::Key;
use dua::traverse::{Tree, TreeIndex};
use petgraph::Direction;
use std::borrow::Borrow;
use tui::backend::Backend;
use tui::prelude::Buffer;
use tui::{
buffer::Buffer,
layout::Rect,
style::Style,
text::{Line, Span, Text},
widgets::{Block, Borders, Paragraph, Widget},
};
use tui_react::util::{block_width, rect};
use tui_react::{draw_text_nowrap_fn, Terminal};
use tui_react::{
draw_text_nowrap_fn,
util::{block_width, rect},
};
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;

Expand Down Expand Up @@ -100,15 +101,13 @@ impl GlobPane {
new_cursor_pos.clamp(0, self.input.graphemes(true).count())
}

pub fn render<B>(
pub fn render(
&mut self,
props: impl Borrow<GlobPaneProps>,
area: Rect,
terminal: &mut Terminal<B>,
buffer: &mut Buffer,
cursor: &mut Cursor,
) where
B: Backend,
{
) {
let GlobPaneProps {
border_style,
has_focus,
Expand All @@ -120,18 +119,15 @@ impl GlobPane {
.border_style(*border_style)
.borders(Borders::ALL);
let inner_block_area = block.inner(area);
block.render(area, terminal.current_buffer_mut());
block.render(area, buffer);

let spans = vec![Span::from(&self.input)];
Paragraph::new(Text::from(Line::from(spans)))
.style(Style::default())
.render(
margin_left_right(inner_block_area, 1),
terminal.current_buffer_mut(),
);
.render(margin_left_right(inner_block_area, 1), buffer);

if *has_focus {
draw_top_right_help(area, title, terminal.current_buffer_mut());
draw_top_right_help(area, title, buffer);

cursor.show = true;
cursor.x = inner_block_area.x
Expand Down
24 changes: 10 additions & 14 deletions src/interactive/widgets/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ use crate::interactive::{
DisplayOptions,
};
use std::borrow::Borrow;
use tui::backend::Backend;
use tui::buffer::Buffer;
use tui::{
layout::{Constraint, Direction, Layout, Rect},
style::Modifier,
style::{Color, Style},
};
use tui_react::Terminal;
use Constraint::*;
use FocussedPane::*;

Expand All @@ -36,15 +35,13 @@ pub struct MainWindow {
}

impl MainWindow {
pub fn render<'a, B>(
pub fn render<'a>(
&mut self,
props: impl Borrow<MainWindowProps<'a>>,
area: Rect,
terminal: &mut Terminal<B>,
buffer: &mut Buffer,
cursor: &mut Cursor,
) where
B: Backend,
{
) {
let MainWindowProps {
current_path,
entries_traversed,
Expand All @@ -59,7 +56,7 @@ impl MainWindow {
let (header_area, content_area, footer_area) = main_window_layout(area);

let header_bg_color = header_background_color(self.is_anything_marked(), state.focussed);
Header.render(header_bg_color, header_area, terminal.current_buffer_mut());
Header.render(header_bg_color, header_area, buffer);

let (entries_area, help_pane, mark_pane) = {
let (left_pane, right_pane) = content_layout(content_area);
Expand Down Expand Up @@ -90,15 +87,15 @@ impl MainWindow {
border_style: mark_style,
format: display.byte_format,
};
pane.render(props, mark_area, terminal.current_buffer_mut());
pane.render(props, mark_area, buffer);
}

if let Some((help_area, pane)) = help_pane {
let props = HelpPaneProps {
border_style: help_style,
has_focus: matches!(state.focussed, Help),
};
pane.render(props, help_area, terminal.current_buffer_mut());
pane.render(props, help_area, buffer);
}

let marked = self.mark_pane.as_ref().map(|p| p.marked());
Expand All @@ -113,15 +110,14 @@ impl MainWindow {
sort_mode: state.sorting,
show_columns: &state.show_columns,
};
self.entries_pane
.render(props, entries_area, terminal.current_buffer_mut());
self.entries_pane.render(props, entries_area, buffer);

if let Some((glob_area, pane)) = glob_pane {
let props = GlobPaneProps {
border_style: glob_style,
has_focus: matches!(state.focussed, Glob),
};
pane.render(props, glob_area, terminal, cursor);
pane.render(props, glob_area, buffer, cursor);
}

Footer.render(
Expand All @@ -135,7 +131,7 @@ impl MainWindow {
sort_mode: state.sorting,
},
footer_area,
terminal.current_buffer_mut(),
buffer,
);
}

Expand Down
Loading