mirror of
https://github.com/itsjunetime/tdf.git
synced 2026-06-02 08:01:47 -04:00
Implement help page and delay receiving area to hopefully improve first-page performance a bit
This commit is contained in:
+17
-9
@@ -71,14 +71,6 @@ pub fn start_rendering(
|
|||||||
receiver: Receiver<RenderNotif>,
|
receiver: Receiver<RenderNotif>,
|
||||||
size: WindowSize
|
size: WindowSize
|
||||||
) -> Result<(), SendError<Result<RenderInfo, RenderError>>> {
|
) -> Result<(), SendError<Result<RenderInfo, RenderError>>> {
|
||||||
// first, wait 'til we get told what the current starting area is so that we can set it to
|
|
||||||
// know what to render to
|
|
||||||
let mut area = loop {
|
|
||||||
if let RenderNotif::Area(r) = receiver.recv().unwrap() {
|
|
||||||
break r;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// We want this outside of 'reload so that if the doc reloads, the search term that somebody
|
// We want this outside of 'reload so that if the doc reloads, the search term that somebody
|
||||||
// set will still get highlighted in the reloaded doc
|
// set will still get highlighted in the reloaded doc
|
||||||
let mut search_term = None;
|
let mut search_term = None;
|
||||||
@@ -90,6 +82,7 @@ pub fn start_rendering(
|
|||||||
|
|
||||||
let mut stored_doc = None;
|
let mut stored_doc = None;
|
||||||
let mut invert = false;
|
let mut invert = false;
|
||||||
|
let mut preserved_area = None;
|
||||||
|
|
||||||
'reload: loop {
|
'reload: loop {
|
||||||
let doc = match Document::open(path) {
|
let doc = match Document::open(path) {
|
||||||
@@ -143,6 +136,21 @@ pub fn start_rendering(
|
|||||||
fill_default::<PrevRender>(&mut rendered, n_pages);
|
fill_default::<PrevRender>(&mut rendered, n_pages);
|
||||||
let mut start_point = 0;
|
let mut start_point = 0;
|
||||||
|
|
||||||
|
// next, we gotta wait 'til we get told what the current starting area is so that we can
|
||||||
|
// set it to know what to render to
|
||||||
|
let area = match preserved_area {
|
||||||
|
Some(a) => a,
|
||||||
|
None => {
|
||||||
|
let new_area = loop {
|
||||||
|
if let RenderNotif::Area(r) = receiver.recv().unwrap() {
|
||||||
|
break r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
preserved_area = Some(new_area);
|
||||||
|
new_area
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// This is kinda a weird way of doing this, but if we get a notification that the area
|
// This is kinda a weird way of doing this, but if we get a notification that the area
|
||||||
// changed, we want to start re-rending all of the pages, but we don't want to reload the
|
// changed, we want to start re-rending all of the pages, but we don't want to reload the
|
||||||
// document. If there was a mechanism to say 'start this for-loop over' then I would do
|
// document. If there was a mechanism to say 'start this for-loop over' then I would do
|
||||||
@@ -164,7 +172,7 @@ pub fn start_rendering(
|
|||||||
RenderNotif::Area(new_area) => {
|
RenderNotif::Area(new_area) => {
|
||||||
let bigger =
|
let bigger =
|
||||||
new_area.width > area.width || new_area.height > area.height;
|
new_area.width > area.width || new_area.height > area.height;
|
||||||
area = new_area;
|
preserved_area = Some(new_area);
|
||||||
// we only want to re-render pages if the new area is greater than the old
|
// we only want to re-render pages if the new area is greater than the old
|
||||||
// one, 'cause then we might need sharper images to make it all look good.
|
// one, 'cause then we might need sharper images to make it all look good.
|
||||||
// If the new area is smaller, then the same high-quality-rendered images
|
// If the new area is smaller, then the same high-quality-rendered images
|
||||||
|
|||||||
+90
-11
@@ -16,8 +16,9 @@ use ratatui::{
|
|||||||
Frame,
|
Frame,
|
||||||
layout::{Constraint, Flex, Layout, Rect},
|
layout::{Constraint, Flex, Layout, Rect},
|
||||||
style::{Color, Style},
|
style::{Color, Style},
|
||||||
text::Span,
|
symbols::border,
|
||||||
widgets::{Block, Borders, Padding}
|
text::{Span, Text},
|
||||||
|
widgets::{Block, Borders, Clear, Padding}
|
||||||
};
|
};
|
||||||
use ratatui_image::{Image, protocol::Protocol};
|
use ratatui_image::{Image, protocol::Protocol};
|
||||||
|
|
||||||
@@ -32,7 +33,8 @@ pub struct Tui {
|
|||||||
// jumping to a specific page
|
// jumping to a specific page
|
||||||
prev_msg: Option<BottomMessage>,
|
prev_msg: Option<BottomMessage>,
|
||||||
rendered: Vec<RenderedInfo>,
|
rendered: Vec<RenderedInfo>,
|
||||||
page_constraints: PageConstraints
|
page_constraints: PageConstraints,
|
||||||
|
showing_help_msg: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
@@ -86,7 +88,8 @@ impl Tui {
|
|||||||
bottom_msg: BottomMessage::Help,
|
bottom_msg: BottomMessage::Help,
|
||||||
last_render: LastRender::default(),
|
last_render: LastRender::default(),
|
||||||
rendered: vec![],
|
rendered: vec![],
|
||||||
page_constraints: PageConstraints { max_wide, r_to_l }
|
page_constraints: PageConstraints { max_wide, r_to_l },
|
||||||
|
showing_help_msg: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +107,11 @@ impl Tui {
|
|||||||
|
|
||||||
// TODO: Make a way to fill the width of the screen with one page and scroll down to view it
|
// TODO: Make a way to fill the width of the screen with one page and scroll down to view it
|
||||||
pub fn render(&mut self, frame: &mut Frame<'_>, main_area: &[Rect]) {
|
pub fn render(&mut self, frame: &mut Frame<'_>, main_area: &[Rect]) {
|
||||||
|
if self.showing_help_msg {
|
||||||
|
self.render_help_msg(frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let top_block = Block::new()
|
let top_block = Block::new()
|
||||||
.padding(Padding {
|
.padding(Padding {
|
||||||
right: 2,
|
right: 2,
|
||||||
@@ -161,10 +169,7 @@ impl Tui {
|
|||||||
frame.render_widget(rendered_span, bottom_layout[1]);
|
frame.render_widget(rendered_span, bottom_layout[1]);
|
||||||
|
|
||||||
let (msg_str, color): (Cow<'_, str>, _) = match self.bottom_msg {
|
let (msg_str, color): (Cow<'_, str>, _) = match self.bottom_msg {
|
||||||
BottomMessage::Help => (
|
BottomMessage::Help => ("?: Show help page".into(), Color::Blue),
|
||||||
"/: Search, g: Go To Page, n: Next Search Result, N: Previous Search Result".into(),
|
|
||||||
Color::Blue
|
|
||||||
),
|
|
||||||
BottomMessage::Error(ref e) => (e.as_str().into(), Color::Red),
|
BottomMessage::Error(ref e) => (e.as_str().into(), Color::Red),
|
||||||
BottomMessage::Input(ref input_state) => (
|
BottomMessage::Input(ref input_state) => (
|
||||||
match input_state {
|
match input_state {
|
||||||
@@ -415,6 +420,10 @@ impl Tui {
|
|||||||
Some(InputAction::Redraw)
|
Some(InputAction::Redraw)
|
||||||
}
|
}
|
||||||
'i' => Some(InputAction::Invert),
|
'i' => Some(InputAction::Invert),
|
||||||
|
'?' => {
|
||||||
|
self.showing_help_msg = true;
|
||||||
|
Some(InputAction::Redraw)
|
||||||
|
}
|
||||||
'n' if self.page < self.rendered.len() - 1 => {
|
'n' if self.page < self.rendered.len() - 1 => {
|
||||||
// TODO: If we can't find one, then maybe like block until we've verified
|
// TODO: If we can't find one, then maybe like block until we've verified
|
||||||
// all the pages have been checked?
|
// all the pages have been checked?
|
||||||
@@ -486,8 +495,8 @@ impl Tui {
|
|||||||
KeyCode::Down => self.change_page(PageChange::Next, ChangeAmount::WholeScreen),
|
KeyCode::Down => self.change_page(PageChange::Next, ChangeAmount::WholeScreen),
|
||||||
KeyCode::Left => self.change_page(PageChange::Prev, ChangeAmount::Single),
|
KeyCode::Left => self.change_page(PageChange::Prev, ChangeAmount::Single),
|
||||||
KeyCode::Up => self.change_page(PageChange::Prev, ChangeAmount::WholeScreen),
|
KeyCode::Up => self.change_page(PageChange::Prev, ChangeAmount::WholeScreen),
|
||||||
KeyCode::Esc => match self.bottom_msg {
|
KeyCode::Esc => match (self.showing_help_msg, &self.bottom_msg) {
|
||||||
BottomMessage::Help => Some(InputAction::QuitApp),
|
(false, BottomMessage::Help) => Some(InputAction::QuitApp),
|
||||||
_ => {
|
_ => {
|
||||||
// When we hit escape, we just want to pop off the current message and
|
// When we hit escape, we just want to pop off the current message and
|
||||||
// show the underlying one.
|
// show the underlying one.
|
||||||
@@ -598,11 +607,81 @@ impl Tui {
|
|||||||
self.prev_msg = None;
|
self.prev_msg = None;
|
||||||
self.bottom_msg = BottomMessage::default();
|
self.bottom_msg = BottomMessage::default();
|
||||||
}
|
}
|
||||||
MessageSetting::Pop => self.bottom_msg = self.prev_msg.take().unwrap_or_default()
|
MessageSetting::Pop =>
|
||||||
|
if self.showing_help_msg {
|
||||||
|
self.last_render.rect = Rect::default();
|
||||||
|
self.showing_help_msg = false;
|
||||||
|
} else {
|
||||||
|
self.bottom_msg = self.prev_msg.take().unwrap_or_default();
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_help_msg(&self, frame: &mut Frame<'_>) {
|
||||||
|
let frame_area = frame.area();
|
||||||
|
frame.render_widget(Clear, frame_area);
|
||||||
|
|
||||||
|
let block = Block::new()
|
||||||
|
.title("Help")
|
||||||
|
.padding(Padding::proportional(1))
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.border_set(border::ROUNDED)
|
||||||
|
.border_style(Color::Blue);
|
||||||
|
|
||||||
|
let help_span = Text::raw(HELP_PAGE);
|
||||||
|
|
||||||
|
let max_w: u16 = HELP_PAGE
|
||||||
|
.lines()
|
||||||
|
.map(str::len)
|
||||||
|
.max()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.try_into()
|
||||||
|
.expect("Every help text line must be shorter than u16::MAX");
|
||||||
|
|
||||||
|
let layout = Layout::horizontal([
|
||||||
|
Constraint::Fill(1),
|
||||||
|
Constraint::Length(max_w + 6),
|
||||||
|
Constraint::Fill(1)
|
||||||
|
])
|
||||||
|
.split(frame_area);
|
||||||
|
|
||||||
|
let block_area = Layout::vertical([
|
||||||
|
Constraint::Fill(1),
|
||||||
|
Constraint::Length(u16::try_from(HELP_PAGE.lines().count()).unwrap() + 4),
|
||||||
|
Constraint::Fill(1)
|
||||||
|
])
|
||||||
|
.split(layout[1]);
|
||||||
|
|
||||||
|
let block_inner = block.inner(block_area[1]);
|
||||||
|
|
||||||
|
frame.render_widget(block, block_area[1]);
|
||||||
|
frame.render_widget(help_span, block_inner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HELP_PAGE: &str = "\
|
||||||
|
l, h, left, right:
|
||||||
|
Go forward/backwards a single page
|
||||||
|
j, k, down, up:
|
||||||
|
Go forwards/backwards a screen's worth of pages
|
||||||
|
q, esc:
|
||||||
|
Quit
|
||||||
|
g:
|
||||||
|
Go to specific page (type numbers after 'g')
|
||||||
|
/:
|
||||||
|
Search
|
||||||
|
n, N:
|
||||||
|
Next/Previous search result
|
||||||
|
i:
|
||||||
|
Invert colors
|
||||||
|
f:
|
||||||
|
Remove borders/fullscreen
|
||||||
|
?:
|
||||||
|
Show this page
|
||||||
|
ctrl+z:
|
||||||
|
Suspend & background tdf \
|
||||||
|
";
|
||||||
|
|
||||||
pub enum InputAction {
|
pub enum InputAction {
|
||||||
Redraw,
|
Redraw,
|
||||||
JumpingToPage(usize),
|
JumpingToPage(usize),
|
||||||
|
|||||||
Reference in New Issue
Block a user