aboutsummaryrefslogtreecommitdiff
path: root/src/main/rust/ui.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/rust/ui.rs')
-rw-r--r--src/main/rust/ui.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/main/rust/ui.rs b/src/main/rust/ui.rs
new file mode 100644
index 0000000..2f69cea
--- /dev/null
+++ b/src/main/rust/ui.rs
@@ -0,0 +1,85 @@
+use crate::{app::App, ui};
+use ratatui::{
+ Frame,
+ buffer::Buffer,
+ layout::Rect,
+ style::Stylize,
+ symbols::border,
+ text::{Line, Text},
+ widgets::{Block, Paragraph, Widget},
+};
+
+/// Explicitly declare lifetime as App is a reference;
+/// Runtime is only instantiated for render
+struct Runtime<'a> {
+ app: &'a App,
+}
+
+pub fn draw(frame: &mut Frame, app: &App) {
+ let run = ui::Runtime { app };
+ frame.render_widget(&run, frame.area());
+}
+
+impl<'a> Widget for &Runtime<'a> {
+ fn render(self, area: Rect, buf: &mut Buffer) {
+ let title = Line::from(" Counter App Tutorial ".bold());
+ let instructions = Line::from(vec![
+ " Decrement ".into(),
+ "<Left>".blue().bold(),
+ " Increment ".into(),
+ "<Right>".blue().bold(),
+ " Quit ".into(),
+ "<Q> ".blue().bold(),
+ ]);
+ let block = Block::bordered()
+ .title(title.centered())
+ .title_bottom(instructions.centered())
+ .border_set(border::THICK);
+
+ let counter_text = Text::from(vec![Line::from(vec![
+ "Value: ".into(),
+ self.app.display_counter().yellow(),
+ ])]);
+
+ Paragraph::new(counter_text)
+ .centered()
+ .block(block)
+ .render(area, buf);
+ }
+}
+
+#[cfg(test)]
+mod tests {
+
+ use super::*;
+ use ratatui::style::Style;
+
+ #[test]
+ fn render() {
+ let mut app = App::default();
+ assert!(app.init_context().is_ok());
+ let runtime = Runtime { app: &app };
+
+ let mut buf = Buffer::empty(Rect::new(0, 0, 50, 4));
+
+ runtime.render(buf.area, &mut buf);
+
+ let mut expected = Buffer::with_lines(vec![
+ "┏━━━━━━━━━━━━━ Counter App Tutorial ━━━━━━━━━━━━━┓",
+ "┃ Value: 0 ┃",
+ "┃ ┃",
+ "┗━ Decrement <Left> Increment <Right> Quit <Q> ━━┛",
+ ]);
+ let title_style = Style::new().bold();
+ let counter_style = Style::new().yellow();
+ let key_style = Style::new().blue().bold();
+
+ expected.set_style(Rect::new(14, 0, 22, 1), title_style);
+ expected.set_style(Rect::new(28, 1, 1, 1), counter_style);
+ expected.set_style(Rect::new(13, 3, 6, 1), key_style);
+ expected.set_style(Rect::new(30, 3, 7, 1), key_style);
+ expected.set_style(Rect::new(43, 3, 4, 1), key_style);
+
+ assert_eq!(buf, expected);
+ }
+}