chiark / gitweb /
Make a start on ActivityStates drawing themselves.
authorSimon Tatham <anakin@pobox.com>
Thu, 28 Dec 2023 08:30:09 +0000 (08:30 +0000)
committerSimon Tatham <anakin@pobox.com>
Thu, 28 Dec 2023 08:30:09 +0000 (08:30 +0000)
This begins to bring the pieces together: our Main Menu now has its
correct header line, although as yet nothing else.

src/menu.rs
src/tui.rs

index f6a6db8470fe4ab5cb60cff875c8dc698e22fdf6..14a7f1bd56b3310776b0897f88ddaa9dd381d822 100644 (file)
@@ -1,14 +1,29 @@
-use super::tui::{ActivityState, HandleEventResult, OurKey, OurKey::*};
+use super::coloured_string::ColouredString;
+use super::text::*;
+use super::tui::{
+    ActivityState, CursorPosition, HandleEventResult,
+    OurKey, OurKey::*
+};
 
 struct Menu {
+    title: Box<dyn TextFragment>,
 }
 
 pub fn main_menu() -> Box<dyn ActivityState> {
     Box::new(Menu{
+        title: FileHeader::new(
+            ColouredString::uniform("Mastodonochrome Main Menu", 'H')),
     })
 }
 
 impl ActivityState for Menu {
+    fn draw(&self, h: usize, w: usize)
+            -> (Vec<ColouredString>, CursorPosition) {
+        let mut lines = Vec::new();
+        lines.extend_from_slice(&self.title.render(w));
+        (lines, CursorPosition::End)
+    }
+
     fn handle_keypress(&mut self, key: OurKey) -> HandleEventResult {
         match key {
             Pr('b') => HandleEventResult::Beep,
index fc2c98fb359b3fa14c3a132db302305acdb01673..5aed7bfc0c04cf6c9400e9568e0ed4d108799d27 100644 (file)
@@ -231,7 +231,11 @@ impl Tui {
             self.terminal.draw(|frame| {
                 let area = frame.size();
                 let buf = frame.buffer_mut();
-                self.state.draw_frame(area, buf);
+                if let Some((y, x)) = self.state.draw_frame(area, buf) {
+                    if let (Ok(y), Ok(x)) = (y.try_into(), x.try_into()) {
+                        frame.set_cursor(x, y);
+                    }
+                }
             })?;
 
             match self.subthread_receiver.recv() {
@@ -269,7 +273,14 @@ impl Tui {
     }
 }
 
+pub enum CursorPosition {
+    None, // cursor is hidden
+    End, // cursor at the end of the last drawn line (quite common in this UI)
+    At(usize, usize), // (y,x)
+}
+
 pub trait ActivityState {
+    fn draw(&self, h: usize, w: usize) -> (Vec<ColouredString>, CursorPosition);
     fn handle_keypress(&mut self, key: OurKey) -> HandleEventResult;
 }
 
@@ -296,12 +307,23 @@ impl TuiLogicalState {
         }
     }
 
-    fn draw_frame(&self, _area: Rect, buf: &mut Buffer) {
+    fn draw_frame(&self, area: Rect, buf: &mut Buffer)
+                  -> Option<(usize, usize)> {
+        let (lines, cursorpos) = self.activity_state.draw(
+            area.height as usize, area.width as usize);
         buf.reset();
-        ratatui_set_string(buf, 2, 4, &ColouredString::general(
-            "#HelloWorld from Mastodonochrome",
-            "###########                     ",
-        ).slice());
+        let mut last_x = 0;
+        let mut last_y = 0;
+        for (y, line) in lines.iter().enumerate() {
+            ratatui_set_string(buf, y, 0, &line.slice());
+            last_y = y;
+            last_x = line.width();
+        }
+        match cursorpos {
+            CursorPosition::None => None,
+            CursorPosition::At(y, x) => Some((y, x)),
+            CursorPosition::End => Some((last_y, last_x)),
+        }
     }
 
     fn handle_keypress(&mut self, key: OurKey) -> HandleEventResult {