about summary refs log tree commit diff
path: root/src/display
diff options
context:
space:
mode:
authorGriffin Smith <root@gws.fyi>2019-08-04T00·26-0400
committerGriffin Smith <root@gws.fyi>2019-08-04T00·31-0400
commite2d2f011c6373894b3cdcfbdb98fbc783504561a (patch)
treea10ab475547d5496484c1ca89a079b32ca90706f /src/display
parent48fb3f6624b95e9b18a5ff0a814573445c6bc2ab (diff)
Add method for writing option menus to viewport
Add a method for writing single-choice menus to the viewport, within a
box. Unused for now.
Diffstat (limited to 'src/display')
-rw-r--r--src/display/draw_box.rs22
-rw-r--r--src/display/viewport.rs74
2 files changed, 74 insertions, 22 deletions
diff --git a/src/display/draw_box.rs b/src/display/draw_box.rs
index 1b3958cefca8..e4d34a7acda9 100644
--- a/src/display/draw_box.rs
+++ b/src/display/draw_box.rs
@@ -1,5 +1,6 @@
 use crate::display::utils::clone_times;
 use crate::display::utils::times;
+use crate::types::pos;
 use crate::types::BoundingBox;
 use crate::types::Dimensions;
 use crate::types::Neighbors;
@@ -215,12 +216,21 @@ pub fn draw_box<W: Write>(
     bbox: BoundingBox,
     style: BoxStyle,
 ) -> io::Result<()> {
-    write!(
-        out,
-        "{}{}",
-        bbox.position.cursor_goto(),
-        make_box(style, bbox.dimensions)
-    )
+    let box_str = make_box(style, bbox.dimensions);
+    if bbox.position.x == 0 {
+        write!(out, "{}{}", bbox.position.cursor_goto(), box_str)?;
+    } else {
+        for (i, line) in box_str.split("\n\r").enumerate() {
+            debug!("line: {:?}!", line);
+            write!(
+                out,
+                "{}{}",
+                (bbox.position + pos(0, i as i16)).cursor_goto(),
+                line
+            )?;
+        }
+    }
+    Ok(())
 }
 
 #[cfg(test)]
diff --git a/src/display/viewport.rs b/src/display/viewport.rs
index 9d17bc87dcff..c44316cdaad5 100644
--- a/src/display/viewport.rs
+++ b/src/display/viewport.rs
@@ -3,6 +3,7 @@ use super::DrawWithNeighbors;
 use crate::display::draw_box::draw_box;
 use crate::display::utils::clone_times;
 use crate::entities::entity::Entity;
+use crate::types::menu::MenuInfo;
 use crate::types::Neighbors;
 use crate::types::{pos, BoundingBox, Direction, Position, Positioned};
 use std::fmt::{self, Debug};
@@ -192,6 +193,41 @@ impl<W: Write> Viewport<W> {
         self.cursor_state = CursorState::Game;
         Ok(())
     }
+
+    pub fn write_menu(&mut self, menu: &MenuInfo) -> io::Result<()> {
+        let menu_dims = menu.dimensions();
+
+        // TODO: check if the menu is too big
+
+        let menu_position = self.game.position + pos(1, 1);
+
+        let menu_box = BoundingBox {
+            dimensions: menu_dims,
+            position: menu_position,
+        };
+
+        debug!("writing menu at: {:?}", menu_box);
+
+        draw_box(self, menu_box, BoxStyle::Thin)?;
+
+        write!(
+            self,
+            "{}{}",
+            (menu_position + pos(2, 2)).cursor_goto(),
+            menu.prompt
+        )?;
+
+        for (idx, option) in menu.options.iter().enumerate() {
+            write!(
+                self,
+                "{}{}",
+                (menu_position + pos(2, 4 + idx as i16)).cursor_goto(),
+                option
+            )?;
+        }
+
+        Ok(())
+    }
 }
 
 impl<W> Positioned for Viewport<W> {
@@ -218,7 +254,6 @@ impl<W: Write> Write for Viewport<W> {
 mod tests {
     use super::*;
     use crate::types::Dimensions;
-    // use proptest::prelude::*;
 
     #[test]
     fn test_visible() {
@@ -243,19 +278,26 @@ mod tests {
         .visible(&Position { x: 1, y: 1 }));
     }
 
-    // proptest! {
-    //     #[test]
-    //     fn nothing_is_visible_in_viewport_off_screen(pos: Position, outer: BoundingBox) {
-    //         let invisible_viewport = Viewport {
-    //             outer,
-    //             inner: BoundingBox {
-    //                 position: Position {x: -(outer.dimensions.w as i16), y: -(outer.dimensions.h as i16)},
-    //                 dimensions: outer.dimensions,
-    //             },
-    //             out: ()
-    //         };
-
-    //         assert!(!invisible_viewport.visible(&pos));
-    //     }
-    // }
+    #[test]
+    fn test_write_menu() {
+        let buf: Vec<u8> = Vec::new();
+
+        let mut viewport = Viewport::new(
+            BoundingBox::at_origin(Dimensions::default()),
+            BoundingBox::at_origin(Dimensions::default()),
+            buf,
+        );
+
+        let menu = MenuInfo::new(
+            "Test menu".to_string(),
+            vec!["option 1".to_string(), "option 2".to_string()],
+        );
+
+        viewport.write_menu(&menu).unwrap();
+
+        let res = std::str::from_utf8(&viewport.out).unwrap();
+        assert!(res.contains("Test menu"));
+        assert!(res.contains("option 1"));
+        assert!(res.contains("option 2"));
+    }
 }