Skip to content

Commit

Permalink
add size constraints to rendering help window
Browse files Browse the repository at this point in the history
  • Loading branch information
radlinskii committed Nov 5, 2024
1 parent 66cd868 commit 2ded256
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 47 deletions.
87 changes: 55 additions & 32 deletions src/help_window.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::{Context, Result};
use ratatui::{
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Style},
widgets::{Block, Borders, Clear, Paragraph},
};

Expand All @@ -13,14 +13,21 @@ impl HelpWindow {
HelpWindow
}

pub fn render(&self, frame: &mut impl FrameWrapperInterface) -> Result<()> {
pub fn render(&self, frame: &mut impl FrameWrapperInterface) {
let frame_rect = frame.size();

if frame_rect.height < 3 {
frame.render_widget(Clear, frame_rect);
return;
}

let help_text = vec![
"",
" Navigation:",
" 's' - Start/resume the test",
" 's' - Start/resume the test",
" <Esc> - Pause the test",
" 'q' - Quit",
" '?' - Close this window",
" 'q' - Quit",
" '?' - Toggle this window",
"",
" Configuration:",
" --duration <seconds> - Set test duration",
Expand All @@ -31,18 +38,48 @@ impl HelpWindow {
"",
];

let longest_help_msg_len = help_text
.iter()
.map(|s| s.len())
.max()
.context("Unable to get the length of longest line from help window text")?;
let longest_help_msg_len = help_text.iter().map(|s| s.len()).max().unwrap();
let help_text_lines_count = help_text.len();

let area = Self::centered_rect(
// check if there is enough space vertically to display the help message
if frame_rect.height <= help_text_lines_count as u16 {
let paragraph =
Paragraph::new( "Terminal window is too short to display the help window\nresize the terminal or press \"?\" to return to the test")
.style(Style::default().fg(Color::Red).bg(Color::Black));

frame.render_widget(Clear, frame_rect);
frame.render_widget(paragraph, frame_rect);

return;
}

// check if there is enough space horizontally to display the help message
if frame_rect.width - 2 <= longest_help_msg_len as u16 {
let paragraph = Paragraph::new(
"Terminal window is too narrow\nto display the help window\nresize the terminal\nor press the \"?\" key\nto return to the test",
)
.style(Style::default().fg(Color::Red).bg(Color::Black));

frame.render_widget(Clear, frame_rect);
frame.render_widget(paragraph, frame_rect);

return;
}

// Create a clear overlay to dim the background
frame.render_widget(
Paragraph::new("")
.style(Style::default().bg(Color::Black).fg(Color::DarkGray))
.block(Block::default()),
frame_rect,
);

let area = Self::get_centered_rect(
longest_help_msg_len.try_into().unwrap(),
help_text_lines_count.try_into().unwrap(),
frame.size(),
);

// Clear the background area first.
frame.render_widget(Clear, area);

Expand All @@ -58,35 +95,21 @@ impl HelpWindow {
.constraints(constraints)
.split(inner_area);

// Render block
frame.render_widget(block, area);

// Render text paragraphs
for (i, &text) in help_text.iter().enumerate() {
let paragraph = Paragraph::new(text);
frame.render_widget(paragraph, chunks[i]);
}

Ok(())
}

fn centered_rect(window_width: u16, window_height: u16, r: Rect) -> Rect {
let popup_layout = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(0),
Constraint::Length(window_height + 2),
Constraint::Length(r.height - window_height - 2),
])
.split(r);

Layout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Length((r.width - window_width - 2) / 2),
Constraint::Length(window_width + 2),
Constraint::Length((r.width - window_width - 2) / 2),
])
.split(popup_layout[1])[1]
fn get_centered_rect(window_width: u16, window_height: u16, r: Rect) -> Rect {
let x = r.x + (r.width.saturating_sub(window_width + 2)) / 2;
let y = if r.height > window_height + 4 { 3 } else { 0 };

Rect::new(x, y, window_width + 2, window_height + 1)
}
}

// TODO: add tests
20 changes: 5 additions & 15 deletions src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use crate::expected_input::ExpectedInputInterface;
use crate::help_window::HelpWindow;
use crate::helpers::split_by_char_index;
use crate::test_results::{Stats, TestResults};
use ratatui::widgets::Block;
use ratatui::{
backend::Backend,
layout::{Alignment, Constraint, Direction, Layout, Rect},
Expand Down Expand Up @@ -153,7 +152,7 @@ impl Runner {
self.input_mode = InputMode::Editing;
}
KeyCode::Char('q') => {
// todo return canceled test error and handle it in main
// TODO: return canceled test error and handle it in main
return Ok(TestResults::new(
Stats::default(),
self.config.clone(),
Expand Down Expand Up @@ -251,17 +250,7 @@ impl Runner {

// Then render help window on top if needed
if self.show_help {
// Create a clear overlay to dim the background
let full_area = frame.size();
frame.render_widget(
Paragraph::new("")
.style(Style::default().bg(Color::Black).fg(Color::DarkGray))
.block(Block::default()),
full_area,
);

// Render the help window in the center
let _ = self.help_window.render(frame);
self.help_window.render(frame)
}
}

Expand Down Expand Up @@ -658,7 +647,7 @@ mod test {
vec![
vec![
("30 seconds left", Color::Yellow),
(" ", Color::Reset),
(" ", Color::Reset),
("press '<Esc>' to pause the test", Color::Yellow),
],
vec![
Expand All @@ -673,7 +662,8 @@ mod test {
);

test_runner(&mut runner, buffer, |frame, runner| {
runner.render(frame, 30);
let duration = 30;
runner.render(frame, duration);
});
}

Expand Down

0 comments on commit 2ded256

Please sign in to comment.