WIP widgets struct -> trait work
This commit is contained in:
parent
1960123e3f
commit
b39fa32674
|
@ -121,12 +121,12 @@ impl SectionWidth {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub struct Widget {
|
||||
pub struct Section {
|
||||
want_width: SectionWidth,
|
||||
per_line: Vec<Token>,
|
||||
}
|
||||
|
||||
impl PartialEq for Widget {
|
||||
impl PartialEq for Section {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.want_width == other.want_width
|
||||
&& self.per_line.len() == other.per_line.len()
|
||||
|
@ -137,7 +137,7 @@ impl PartialEq for Widget {
|
|||
}
|
||||
}
|
||||
|
||||
impl Widget {
|
||||
impl Section {
|
||||
pub fn new(
|
||||
width: SectionWidth,
|
||||
tokens_per_line: Vec<Token>,
|
||||
|
@ -155,7 +155,7 @@ impl Widget {
|
|||
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub enum Instruction {
|
||||
FixedHeight(Box<Instruction>, usize, Vec<Widget>),
|
||||
FixedHeight(Box<Instruction>, usize, Vec<Section>),
|
||||
End,
|
||||
}
|
||||
|
||||
|
@ -260,15 +260,15 @@ impl Instruction {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Plan {
|
||||
FixedHeight(Box<Plan>, usize, Vec<Widget>),
|
||||
Fill(Box<Plan>, Vec<Widget>),
|
||||
FixedHeight(Box<Plan>, usize, Vec<Section>),
|
||||
Fill(Box<Plan>, Vec<Section>),
|
||||
End,
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ impl Plan {
|
|||
Self::End
|
||||
}
|
||||
|
||||
fn fit_check(widgets: &Vec<Widget>) {
|
||||
fn fit_check(widgets: &Vec<Section>) {
|
||||
if widgets
|
||||
.into_iter()
|
||||
.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::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::Fill(Box::new(self), widgets)
|
||||
}
|
||||
|
@ -368,19 +368,19 @@ impl Plan {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn test_widgets() -> (Widget, Widget, Widget) {
|
||||
fn test_widgets() -> (Section, Section, Section) {
|
||||
(
|
||||
Widget::new(
|
||||
Section::new(
|
||||
SectionWidth::Third,
|
||||
vec![Token::text("hello").centered()],
|
||||
),
|
||||
Widget::new(
|
||||
Section::new(
|
||||
SectionWidth::Third,
|
||||
vec![Token::text("hello")
|
||||
.pad_char('*', 16)
|
||||
.bg(Color::RED)],
|
||||
),
|
||||
Widget::new(
|
||||
Section::new(
|
||||
SectionWidth::Third,
|
||||
vec![Token::text("hello").limited(16).padded(20)],
|
||||
),
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
use crate::component::Cursed;
|
||||
use component::{Plan, Widget};
|
||||
use component::{Plan, Section};
|
||||
use event::Event;
|
||||
use std::{
|
||||
io::{Stdout, Write},
|
||||
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 token::Token;
|
||||
|
||||
|
@ -12,16 +21,45 @@ extern crate termion;
|
|||
mod component;
|
||||
mod theme;
|
||||
mod token;
|
||||
mod widget;
|
||||
|
||||
pub struct Display {
|
||||
// needs to hold the termion display
|
||||
screen: RawTerminal<Stdout>,
|
||||
screen: MouseTerminal<RawTerminal<Stdout>>,
|
||||
}
|
||||
|
||||
impl Display {
|
||||
pub fn new() -> Result<Self, anyhow::Error> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -3,5 +3,6 @@ use kkdisp::Display;
|
|||
fn main() {
|
||||
// let disp = Display::new();
|
||||
// let widget_idk = Widget::new()
|
||||
Display::test();
|
||||
// Display::new();
|
||||
Display::testing_loop_show_input();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue