WIP widgets struct -> trait work

This commit is contained in:
emilis 2023-01-20 14:51:36 +00:00
parent 1960123e3f
commit b39fa32674
4 changed files with 153 additions and 19 deletions

View File

@ -121,12 +121,12 @@ impl SectionWidth {
} }
#[derive(Debug, Clone, Eq)] #[derive(Debug, Clone, Eq)]
pub struct Widget { pub struct Section {
want_width: SectionWidth, want_width: SectionWidth,
per_line: Vec<Token>, per_line: Vec<Token>,
} }
impl PartialEq for Widget { impl PartialEq for Section {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.want_width == other.want_width self.want_width == other.want_width
&& self.per_line.len() == other.per_line.len() && self.per_line.len() == other.per_line.len()
@ -137,7 +137,7 @@ impl PartialEq for Widget {
} }
} }
impl Widget { impl Section {
pub fn new( pub fn new(
width: SectionWidth, width: SectionWidth,
tokens_per_line: Vec<Token>, tokens_per_line: Vec<Token>,
@ -155,7 +155,7 @@ impl Widget {
#[derive(Debug, Clone, Eq)] #[derive(Debug, Clone, Eq)]
pub enum Instruction { pub enum Instruction {
FixedHeight(Box<Instruction>, usize, Vec<Widget>), FixedHeight(Box<Instruction>, usize, Vec<Section>),
End, End,
} }
@ -260,15 +260,15 @@ impl Instruction {
Self::End Self::End
} }
pub fn fixed(self, height: usize, widgets: Vec<Widget>) -> Self { pub fn fixed(self, height: usize, widgets: Vec<Section>) -> Self {
Self::FixedHeight(Box::new(self), height, widgets) Self::FixedHeight(Box::new(self), height, widgets)
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Plan { pub enum Plan {
FixedHeight(Box<Plan>, usize, Vec<Widget>), FixedHeight(Box<Plan>, usize, Vec<Section>),
Fill(Box<Plan>, Vec<Widget>), Fill(Box<Plan>, Vec<Section>),
End, End,
} }
@ -277,7 +277,7 @@ impl Plan {
Self::End Self::End
} }
fn fit_check(widgets: &Vec<Widget>) { fn fit_check(widgets: &Vec<Section>) {
if widgets if widgets
.into_iter() .into_iter()
.map(|wd| wd.want_width.abs_size(100)) .map(|wd| wd.want_width.abs_size(100))
@ -341,12 +341,12 @@ impl Plan {
} }
} }
pub fn fixed(self, height: usize, widgets: Vec<Widget>) -> Self { pub fn fixed(self, height: usize, widgets: Vec<Section>) -> Self {
Self::fit_check(&widgets); Self::fit_check(&widgets);
Self::FixedHeight(Box::new(self), height, widgets) Self::FixedHeight(Box::new(self), height, widgets)
} }
pub fn fill(self, widgets: Vec<Widget>) -> Self { pub fn fill(self, widgets: Vec<Section>) -> Self {
Self::fit_check(&widgets); Self::fit_check(&widgets);
Self::Fill(Box::new(self), widgets) Self::Fill(Box::new(self), widgets)
} }
@ -368,19 +368,19 @@ impl Plan {
mod tests { mod tests {
use super::*; use super::*;
fn test_widgets() -> (Widget, Widget, Widget) { fn test_widgets() -> (Section, Section, Section) {
( (
Widget::new( Section::new(
SectionWidth::Third, SectionWidth::Third,
vec![Token::text("hello").centered()], vec![Token::text("hello").centered()],
), ),
Widget::new( Section::new(
SectionWidth::Third, SectionWidth::Third,
vec![Token::text("hello") vec![Token::text("hello")
.pad_char('*', 16) .pad_char('*', 16)
.bg(Color::RED)], .bg(Color::RED)],
), ),
Widget::new( Section::new(
SectionWidth::Third, SectionWidth::Third,
vec![Token::text("hello").limited(16).padded(20)], vec![Token::text("hello").limited(16).padded(20)],
), ),

View File

@ -1,10 +1,19 @@
use crate::component::Cursed; use crate::component::Cursed;
use component::{Plan, Widget}; use component::{Plan, Section};
use event::Event;
use std::{ use std::{
io::{Stdout, Write}, io::{Stdout, Write},
time::Duration, time::Duration,
}; };
use termion::raw::{IntoRawMode, RawTerminal}; use termion::{
clear,
input::{MouseTerminal, TermRead},
};
use termion::{
cursor,
raw::{IntoRawMode, RawTerminal},
screen::{AlternateScreen, IntoAlternateScreen},
};
use theme::{Color, ColorSet}; use theme::{Color, ColorSet};
use token::Token; use token::Token;
@ -12,16 +21,45 @@ extern crate termion;
mod component; mod component;
mod theme; mod theme;
mod token; mod token;
mod widget;
pub struct Display { pub struct Display {
// needs to hold the termion display // needs to hold the termion display
screen: RawTerminal<Stdout>, screen: MouseTerminal<RawTerminal<Stdout>>,
} }
impl Display { impl Display {
pub fn new() -> Result<Self, anyhow::Error> { pub fn new() -> Result<Self, anyhow::Error> {
Ok(Self { Ok(Self {
screen: std::io::stdout().into_raw_mode()?, screen: MouseTerminal::from(
std::io::stdout().into_raw_mode()?,
),
}) })
} }
pub fn testing_loop_show_input() -> ! {
let mut scr = MouseTerminal::from(
std::io::stdout()
.into_alternate_screen()
.unwrap()
.into_raw_mode()
.unwrap(),
);
write!(scr, "{}", clear::All).unwrap();
scr.flush().unwrap();
let inp = std::io::stdin();
let mut evs = inp.events();
loop {
let ev = evs.next().unwrap().unwrap();
write!(
scr,
"{clear}{oo}{:#?}",
ev,
oo = cursor::Goto(1, 1),
clear = clear::All
)
.unwrap();
scr.flush().unwrap();
}
}
} }

95
kkdisp/src/widget.rs Normal file
View File

@ -0,0 +1,95 @@
use termion::event::MouseEvent;
use crate::token::Token;
type Result<T> = std::result::Result<T, anyhow::Error>;
pub trait Widget {
fn width(&self, max: usize) -> usize;
fn line(&self, line: usize) -> Option<&Token>;
fn on_event(
&mut self,
event: termion::event::Event,
) -> Result<()>;
}
pub enum WidgetWidth {
Percent(u8),
Absolute(usize),
}
impl WidgetWidth {
pub fn absolute(&self, budget: usize) -> usize {
match self {
Self::Percent(p) => {
// budget = 100%
// absolute = p%
// absolute = (p * budget) / 100
(*p as usize * budget) / 100
}
Self::Absolute(a) => *a,
}
}
}
pub struct ScrollableDisplay {
lines: Vec<Token>,
scrolled_offset: usize,
width: WidgetWidth,
}
impl ScrollableDisplay {
pub fn new(lines: Vec<Token>, width: WidgetWidth) -> Self {
Self {
lines,
width,
scrolled_offset: 0,
}
}
}
impl Widget for ScrollableDisplay {
fn on_event(
&mut self,
event: termion::event::Event,
) -> Result<()> {
let moving_value = match event {
termion::event::Event::Key(_) => todo!(),
termion::event::Event::Mouse(mus) => {
if let MouseEvent::Press(mus, _, _) = mus {
match mus {
termion::event::MouseButton::WheelUp => {
(self.lines.len() - 1)
.min(self.scrolled_offset + 1)
}
termion::event::MouseButton::WheelDown => {
if self.scrolled_offset == 0 {
0
} else {
self.scrolled_offset - 1
}
}
_ => 0,
}
} else {
0
}
}
termion::event::Event::Unsupported(_) => 0,
};
if moving_value == 0 {
return Ok(());
}
self.scrolled_offset = moving_value;
Ok(())
}
#[inline(always)]
fn width(&self, max: usize) -> usize {
self.width.absolute(max)
}
fn line(&self, line: usize) -> Option<&Token> {
self.lines.get(line + self.scrolled_offset)
}
}

View File

@ -3,5 +3,6 @@ use kkdisp::Display;
fn main() { fn main() {
// let disp = Display::new(); // let disp = Display::new();
// let widget_idk = Widget::new() // let widget_idk = Widget::new()
Display::test(); // Display::new();
Display::testing_loop_show_input();
} }