Added color resetting after widget
This commit is contained in:
parent
ec6998ff30
commit
1960123e3f
|
@ -1,10 +1,12 @@
|
||||||
|
use termion::raw::RawTerminal;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
theme::{Color, ColorSet},
|
theme::{Color, ColorSet},
|
||||||
token::Token,
|
token::Token,
|
||||||
};
|
};
|
||||||
use std::iter::Extend;
|
use std::io::{Stdout, Write};
|
||||||
|
|
||||||
#[derive(Eq, Debug, Clone)]
|
#[derive(Eq, Clone, Debug)]
|
||||||
pub enum Component {
|
pub enum Component {
|
||||||
NextLine,
|
NextLine,
|
||||||
X(usize),
|
X(usize),
|
||||||
|
@ -14,24 +16,57 @@ pub enum Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component {
|
impl Component {
|
||||||
fn make_for_line(
|
fn debug(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Component::NextLine => "NextLine".to_string(),
|
||||||
|
Component::X(x) => format!("X({})", x),
|
||||||
|
Component::String(s) => format!("\"{}\"", s),
|
||||||
|
Component::Fg(c) => format!("FG({:#?})", c)
|
||||||
|
.replace('\n', "")
|
||||||
|
.replace(' ', ""),
|
||||||
|
Component::Bg(c) => format!("BG({:#?})", c)
|
||||||
|
.replace('\n', "")
|
||||||
|
.replace(' ', ""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Cursed {
|
||||||
|
fn scene(
|
||||||
|
&mut self,
|
||||||
comp: Vec<Component>,
|
comp: Vec<Component>,
|
||||||
line: usize,
|
) -> Result<(), anyhow::Error>;
|
||||||
offset: usize,
|
}
|
||||||
) -> String {
|
|
||||||
comp.into_iter()
|
impl Cursed for RawTerminal<Stdout> {
|
||||||
|
fn scene(
|
||||||
|
&mut self,
|
||||||
|
comp: Vec<Component>,
|
||||||
|
) -> Result<(), anyhow::Error> {
|
||||||
|
let mut line = 1;
|
||||||
|
let screen_str = comp
|
||||||
|
.into_iter()
|
||||||
.map(|c| match c {
|
.map(|c| match c {
|
||||||
Component::X(x) => termion::cursor::Goto(
|
Component::NextLine => {
|
||||||
(x + offset) as u16,
|
line += 1;
|
||||||
line as u16,
|
String::from("\r\n")
|
||||||
)
|
}
|
||||||
.into(),
|
Component::X(x) => {
|
||||||
|
termion::cursor::Goto((x + 1) as u16, line).into()
|
||||||
|
}
|
||||||
Component::String(s) => s,
|
Component::String(s) => s,
|
||||||
Component::Fg(c) => c.fg(),
|
Component::Fg(c) => c.fg(),
|
||||||
Component::Bg(c) => c.bg(),
|
Component::Bg(c) => c.bg(),
|
||||||
Component::NextLine => "\r\n".into(),
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect::<String>();
|
||||||
|
write!(
|
||||||
|
self,
|
||||||
|
"{clear}{start}{scene}",
|
||||||
|
clear = termion::clear::All,
|
||||||
|
start = termion::cursor::Goto(1, 1),
|
||||||
|
scene = screen_str,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +198,7 @@ impl Instruction {
|
||||||
self,
|
self,
|
||||||
line_width: usize,
|
line_width: usize,
|
||||||
height_left: usize,
|
height_left: usize,
|
||||||
|
color_reset: ColorSet,
|
||||||
) -> Vec<Component> {
|
) -> Vec<Component> {
|
||||||
if height_left == 0 {
|
if height_left == 0 {
|
||||||
return vec![];
|
return vec![];
|
||||||
|
@ -198,18 +234,21 @@ impl Instruction {
|
||||||
result.push(Component::X(offset));
|
result.push(Component::X(offset));
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
|
.push(Component::Fg(color_reset.fg));
|
||||||
|
result
|
||||||
|
.push(Component::Bg(color_reset.bg));
|
||||||
|
result
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.chain(vec![Component::NextLine])
|
.chain(vec![Component::NextLine])
|
||||||
.collect::<Vec<Component>>()
|
.collect::<Vec<Component>>()
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.chain(
|
.chain(next.into_components(
|
||||||
next.into_components(
|
|
||||||
line_width,
|
line_width,
|
||||||
height_left - lines,
|
height_left - lines,
|
||||||
),
|
color_reset,
|
||||||
)
|
))
|
||||||
.collect(),
|
.collect(),
|
||||||
Instruction::End => (0..height_left)
|
Instruction::End => (0..height_left)
|
||||||
.map(|_| Component::NextLine)
|
.map(|_| Component::NextLine)
|
||||||
|
@ -243,7 +282,7 @@ impl Plan {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|wd| wd.want_width.abs_size(100))
|
.map(|wd| wd.want_width.abs_size(100))
|
||||||
.sum::<usize>()
|
.sum::<usize>()
|
||||||
>= 100
|
> 100
|
||||||
{
|
{
|
||||||
panic!("widgets do not fit screen")
|
panic!("widgets do not fit screen")
|
||||||
}
|
}
|
||||||
|
@ -302,10 +341,6 @@ impl Plan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line(self, widgets: Vec<Widget>) -> Self {
|
|
||||||
self.fixed(1, widgets)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fixed(self, height: usize, widgets: Vec<Widget>) -> Self {
|
pub fn fixed(self, height: usize, widgets: Vec<Widget>) -> Self {
|
||||||
Self::fit_check(&widgets);
|
Self::fit_check(&widgets);
|
||||||
Self::FixedHeight(Box::new(self), height, widgets)
|
Self::FixedHeight(Box::new(self), height, widgets)
|
||||||
|
@ -316,14 +351,17 @@ impl Plan {
|
||||||
Self::Fill(Box::new(self), widgets)
|
Self::Fill(Box::new(self), widgets)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn make_line(&self, term_width: u16, )
|
pub fn make(
|
||||||
|
self,
|
||||||
// pub fn make(
|
base_colors: ColorSet,
|
||||||
// &self,
|
(term_width, term_height): (usize, usize),
|
||||||
// (term_width, term_height): (u16, u16),
|
) -> Vec<Component> {
|
||||||
// ) -> String {
|
self.to_instruction_set(term_height - 1).into_components(
|
||||||
|
term_width,
|
||||||
// }
|
term_height - 1,
|
||||||
|
base_colors,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -353,6 +391,10 @@ mod tests {
|
||||||
fn test_instructions_to_components() {
|
fn test_instructions_to_components() {
|
||||||
const WIDTH: usize = 120;
|
const WIDTH: usize = 120;
|
||||||
const HEIGHT: usize = 40;
|
const HEIGHT: usize = 40;
|
||||||
|
const BASE_COLOR: ColorSet = ColorSet {
|
||||||
|
fg: Color::WHITE,
|
||||||
|
bg: Color::BLACK,
|
||||||
|
};
|
||||||
let (w1, w2, w3) = test_widgets();
|
let (w1, w2, w3) = test_widgets();
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
|
@ -367,7 +409,11 @@ mod tests {
|
||||||
.clone()
|
.clone()
|
||||||
.with_width(WIDTH / 3)
|
.with_width(WIDTH / 3)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(vec![Component::X(WIDTH / 3)])
|
.chain(vec![
|
||||||
|
Component::X(WIDTH / 3),
|
||||||
|
Component::Fg(BASE_COLOR.fg),
|
||||||
|
Component::Bg(BASE_COLOR.bg),
|
||||||
|
])
|
||||||
.chain(
|
.chain(
|
||||||
w2.clone()
|
w2.clone()
|
||||||
.get_line(0)
|
.get_line(0)
|
||||||
|
@ -375,7 +421,11 @@ mod tests {
|
||||||
.clone()
|
.clone()
|
||||||
.with_width(WIDTH / 3),
|
.with_width(WIDTH / 3),
|
||||||
)
|
)
|
||||||
.chain(vec![Component::X((WIDTH / 3) * 2)])
|
.chain(vec![
|
||||||
|
Component::X((WIDTH / 3) * 2),
|
||||||
|
Component::Fg(BASE_COLOR.fg),
|
||||||
|
Component::Bg(BASE_COLOR.bg),
|
||||||
|
])
|
||||||
.chain(
|
.chain(
|
||||||
w3.clone()
|
w3.clone()
|
||||||
.get_line(0)
|
.get_line(0)
|
||||||
|
@ -383,13 +433,23 @@ mod tests {
|
||||||
.clone()
|
.clone()
|
||||||
.with_width(WIDTH / 3),
|
.with_width(WIDTH / 3),
|
||||||
)
|
)
|
||||||
.chain(vec![Component::NextLine])
|
.chain(vec![
|
||||||
|
Component::Fg(BASE_COLOR.fg),
|
||||||
|
Component::Bg(BASE_COLOR.bg),
|
||||||
|
Component::NextLine,
|
||||||
|
])
|
||||||
.chain(
|
.chain(
|
||||||
(1..30)
|
(1..30)
|
||||||
.map(|_| {
|
.map(|_| {
|
||||||
vec![
|
vec![
|
||||||
Component::X(WIDTH / 3),
|
Component::X(WIDTH / 3),
|
||||||
|
Component::Fg(BASE_COLOR.fg),
|
||||||
|
Component::Bg(BASE_COLOR.bg),
|
||||||
Component::X((WIDTH / 3) * 2),
|
Component::X((WIDTH / 3) * 2),
|
||||||
|
Component::Fg(BASE_COLOR.fg),
|
||||||
|
Component::Bg(BASE_COLOR.bg),
|
||||||
|
Component::Fg(BASE_COLOR.fg),
|
||||||
|
Component::Bg(BASE_COLOR.bg),
|
||||||
Component::NextLine,
|
Component::NextLine,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -415,6 +475,8 @@ mod tests {
|
||||||
.map(|_| {
|
.map(|_| {
|
||||||
vec![
|
vec![
|
||||||
Component::X(WIDTH / 3),
|
Component::X(WIDTH / 3),
|
||||||
|
Component::Fg(BASE_COLOR.fg),
|
||||||
|
Component::Bg(BASE_COLOR.bg),
|
||||||
Component::NextLine,
|
Component::NextLine,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -429,17 +491,37 @@ mod tests {
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.for_each(|(name, instruction, expected)| {
|
.for_each(|(name, instruction, expected)| {
|
||||||
let actual = instruction.into_components(WIDTH, HEIGHT);
|
let actual = instruction
|
||||||
|
.into_components(WIDTH, HEIGHT, BASE_COLOR);
|
||||||
|
let diff = actual
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.zip(expected.clone())
|
||||||
|
.enumerate()
|
||||||
|
// .filter(|(i, (left, right))| left != right)
|
||||||
|
.map(|(i, (act, exp))| {
|
||||||
|
format!(
|
||||||
|
"{}{}: {} || {}",
|
||||||
|
if act != exp { "## " } else { "" },
|
||||||
|
i,
|
||||||
|
exp.debug(),
|
||||||
|
act.debug(),
|
||||||
|
)
|
||||||
|
.replace('\n', " ")
|
||||||
|
})
|
||||||
|
.collect::<Vec<String>>();
|
||||||
assert!(
|
assert!(
|
||||||
expected == actual,
|
expected == actual,
|
||||||
"<{}>:
|
"<{}>:
|
||||||
expected({}):\n{:#?}
|
expected({})
|
||||||
actual({}):\n{:#?}",
|
actual({})
|
||||||
|
diff:\n{:#?}",
|
||||||
name,
|
name,
|
||||||
expected.len(),
|
expected.len(),
|
||||||
expected,
|
|
||||||
actual.len(),
|
actual.len(),
|
||||||
actual,
|
diff,
|
||||||
|
// expected,
|
||||||
|
// actual
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
use std::io::{Stdout, Write};
|
use crate::component::Cursed;
|
||||||
|
use component::{Plan, Widget};
|
||||||
|
use std::{
|
||||||
|
io::{Stdout, Write},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
use termion::raw::{IntoRawMode, RawTerminal};
|
use termion::raw::{IntoRawMode, RawTerminal};
|
||||||
|
use theme::{Color, ColorSet};
|
||||||
|
use token::Token;
|
||||||
|
|
||||||
extern crate termion;
|
extern crate termion;
|
||||||
mod component;
|
mod component;
|
||||||
|
@ -18,18 +25,3 @@ impl Display {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(left: usize, right: usize) -> usize {
|
|
||||||
left + right
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub struct Color(u8, u8, u8);
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
pub const BLACK: Color = Color(0, 0, 0);
|
pub const BLACK: Color = Color(0, 0, 0);
|
||||||
|
pub const WHITE: Color = Color(255, 255, 255);
|
||||||
pub const RED: Color = Color(255, 0, 0);
|
pub const RED: Color = Color(255, 0, 0);
|
||||||
pub const GREEN: Color = Color(0, 255, 0);
|
pub const GREEN: Color = Color(0, 255, 0);
|
||||||
pub const BLUE: Color = Color(0, 0, 255);
|
pub const BLUE: Color = Color(0, 0, 255);
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
use kkdisp::Display;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
// let disp = Display::new();
|
||||||
|
// let widget_idk = Widget::new()
|
||||||
|
Display::test();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue