mod actions;
+mod area;
mod keys;
mod layout;
mod map;
mod selector;
pub use actions::*;
+pub use area::*;
pub use keys::*;
pub use layout::*;
pub use map::*;
pub use point::*;
pub use selector::*;
-use crossterm::{cursor, execute, queue, style, terminal};
+use crossterm::{
+ cursor::{Hide, MoveTo},
+ execute, queue,
+ style::{Print, SetAttributes, SetColors},
+ terminal,
+};
use eyre::Result;
use std::{
io::{stdout, Write},
pub fn draw_frame<T>(map: &mut impl Map<T>, offset: Point) -> Result<()> {
let (char_on, char_off) = map.characters();
- let (fg_on, fg_off) = map.fg_colors();
- let (bg_on, bg_off) = map.bg_colors();
+ let on_colors = map.on_colors();
+ let off_colors = map.off_colors();
let (style_on, style_off) = map.styles();
for x in 1..(map.x_size() - 1) {
if map.try_point(point) {
queue!(
stdout(),
- cursor::Hide,
- cursor::MoveTo(x_off, y_off),
- style::SetAttribute(style_on),
- style::SetForegroundColor(fg_on),
- style::SetBackgroundColor(bg_on),
- style::Print(char_on)
+ Hide,
+ MoveTo(x_off, y_off),
+ SetAttributes(style_on),
+ SetColors(on_colors),
+ Print(char_on)
)?;
} else {
queue!(
stdout(),
- cursor::Hide,
- cursor::MoveTo(x_off, y_off),
- style::SetAttribute(style_off),
- style::SetForegroundColor(fg_off),
- style::SetBackgroundColor(bg_off),
- style::Print(char_off)
+ Hide,
+ MoveTo(x_off, y_off),
+ SetAttributes(style_off),
+ SetColors(off_colors),
+ Print(char_off)
)?;
}
}
--- /dev/null
+use crossterm::{
+ cursor::{Hide, MoveTo},
+ queue,
+ style::{
+ Color::{Black, White},
+ Colors, SetColors,
+ },
+};
+use eyre::Result;
+
+use super::*;
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Area {
+ pub origin: Point,
+ pub max: Point,
+ pub colors: Option<Colors>,
+}
+
+impl From<(Point, Point)> for Area {
+ fn from(value: (Point, Point)) -> Self {
+ Self {
+ origin: value.0,
+ max: value.1,
+ colors: None,
+ }
+ }
+}
+
+impl Area {
+ pub fn new(x_zero: usize, y_zero: usize, x_max: usize, y_max: usize) -> Self {
+ Self {
+ origin: Point::new(x_zero, y_zero),
+ max: Point::new(x_max, y_max),
+ colors: None,
+ }
+ }
+
+ pub fn set_colors(&mut self, colors: Colors) {
+ self.colors = Some(colors);
+ }
+
+ pub fn to_u16(&self) -> Result<((u16, u16), (u16, u16))> {
+ Ok((
+ (self.origin.x.try_into()?, self.origin.y.try_into()?),
+ (self.max.x.try_into()?, self.max.y.try_into()?),
+ ))
+ }
+
+ pub fn outline_area(&self) -> Result<()> {
+ let colors = self.colors.unwrap_or(Colors::new(White, Black));
+ let ((x_zero, y_zero), (x_max, y_max)) = self.to_u16()?;
+
+ for y in y_zero..=y_max {
+ queue!(
+ stdout(),
+ Hide,
+ MoveTo(x_zero, y),
+ SetColors(colors),
+ Print("┃"),
+ MoveTo(x_max, y),
+ SetColors(colors),
+ Print("┃")
+ )?;
+ }
+
+ for x in x_zero..=x_max {
+ queue!(
+ stdout(),
+ Hide,
+ MoveTo(x, y_zero),
+ SetColors(colors),
+ Print("━"),
+ MoveTo(x, y_max),
+ SetColors(colors),
+ Print("━")
+ )?;
+ }
+
+ for ((x, y), c) in [
+ (x_zero, y_zero),
+ (x_max, y_zero),
+ (x_zero, y_max),
+ (x_max, y_max),
+ ]
+ .iter()
+ .zip(['┏', '┓', '┗', '┛'].iter())
+ {
+ queue!(stdout(), MoveTo(*x, *y), SetColors(colors), Print(c))?;
+ }
+
+ Ok(())
+ }
+}
use super::*;
-pub struct Area {
- pub origin: Point,
- pub max: Point,
-}
-
+#[derive(Clone, Debug)]
pub struct Layout {
pub screen: Area,
pub cells: Area,
pub mask: Area,
pub channels: Area,
+ pub transport: Area,
}
impl Layout {
pub fn build() -> Result<Self> {
let (col, row) = terminal::size()?;
+
let col: usize = col.into();
let row: usize = row.into();
- let screen = Area {
- origin: Point::new(0, 0),
- max: Point::new(col, row),
- };
-
- let cells = Area {
- origin: Point::new(1, 1),
- max: Point::new(col / 2 - 5, row / 2 - 2),
- };
-
- let mask = Area {
- origin: Point::new(col / 2 + 5, 1),
- max: Point::new(col - 2, row / 2 - 2),
- };
-
- let channels = Area {
- origin: Point::new(1, row / 2 + 2),
- max: Point::new(col - 2, row - 2),
- };
+ let screen = Area::new(0, 0, col, row);
+ let cells = Area::new(1, 1, col / 2 - 5, row / 2 - 2);
+ let mask = Area::new(col / 2 + 5, 1, col - 2, row / 2 - 2);
+ let channels = Area::new(1, row / 2 + 2, col - 2, row - 2);
+ let transport = Area::new(col / 2 - 4, 4, col / 2 + 4, 8);
Ok(Self {
screen,
cells,
mask,
channels,
+ transport,
})
}
+
+ pub fn draw_outlines(&self) -> Result<()> {
+ self.cells.outline_area()?;
+ self.mask.outline_area()?;
+ self.channels.outline_area()?;
+ self.transport.outline_area()?;
+ Ok(())
+ }
}