diff --git a/src/components.rs b/src/components.rs index b5729c9..0aa9185 100644 --- a/src/components.rs +++ b/src/components.rs @@ -21,42 +21,35 @@ pub fn div() -> Component { if let Some(v) = this.binds.get(&k.kind) { match v.as_str() { "up" => { - this.set_child(closest_component( - &this.children, - this.child, - crate::utils::Direction::Up, - )); + this.child = + closest_component(&this.children, this.child, crate::utils::Direction::Up); } "down" => { - this.set_child(closest_component( + this.child = closest_component( &this.children, this.child, crate::utils::Direction::Down, - )); + ); } "left" => { - this.set_child(closest_component( + this.child = closest_component( &this.children, this.child, crate::utils::Direction::Left, - )); + ); } "right" => { - this.set_child(closest_component( + this.child = closest_component( &this.children, this.child, crate::utils::Direction::Right, - )); + ); } - _ => { - if let Some(child) = this.get_child() { - return (child.update)(child, k); - } - } + _ => {} } } else { if let Some(child) = this.get_child() { @@ -69,9 +62,15 @@ pub fn div() -> Component { fn render(this: &mut Component) -> String { let mut frame: Vec = create_frame!(this.width, this.height); - for (i, c) in &mut this.children.iter_mut().enumerate() { - c.style.is_active = this.style.is_active && i == this.child; - render_to_frame(&mut frame, c); + for (i, child) in &mut this.children.iter_mut().enumerate() { + if child.width == 0 { + child.width = this.width; + } + if child.height == 0 { + child.height = this.height; + } + child.style.is_active = this.style.is_active && i == this.child; + render_to_frame(&mut frame, child); } frame.join("\n") } @@ -107,16 +106,17 @@ pub fn text() -> Component { pub fn button() -> Component { let mut component = Component::new(); - component.style.clicked_fg = crate::style::Color::Red; - component.style.hover_fg = crate::style::Color::Green; + component.binds = HashMap::from([(key::KeyKind::Enter, String::from("click"))]); fn update(this: &mut Component, k: key::Key) -> UpdateResponse { - if k.kind == KeyKind::Enter { - if this.toggle { - this.clicked = !this.clicked; - (this.on_click)(this); - } else { - return UpdateResponse::Tick(vec![1, 100]); + if let Some(v) = this.binds.get(&k.kind) { + if v == "click" { + if this.toggle { + this.clicked = !this.clicked; + (this.on_click)(this); + } else { + return UpdateResponse::Tick(vec![1, 100]); + } } } UpdateResponse::None @@ -144,3 +144,78 @@ pub fn button() -> Component { component.tick = tick; component } + +pub fn tab() -> Component { + let mut component = Component::new(); + + component.binds = HashMap::from([ + (key::KeyKind::Tab, String::from("next")), + (key::KeyKind::ShiftTab, String::from("previous")), + ]); + + component.style.clicked_fg = crate::style::Color::Red; + + fn update(this: &mut Component, k: key::Key) -> UpdateResponse { + if let Some(v) = this.binds.get(&k.kind) { + match v.as_str() { + "next" => { + if this.child + 1 < this.children.len() { + this.child += 1; + } else { + this.child = 0; + } + } + "previous" => { + if this.child == 0 { + this.child = this.children.len() - 1; + } else { + this.child -= 1; + } + } + _ => {} + } + } else { + if let Some(child) = this.get_child() { + return (child.update)(child, k); + } else { + } + } + UpdateResponse::None + } + + fn render(this: &mut Component) -> String { + let mut frame: Vec = create_frame!(this.width, this.height - 1); + let w = this.width; + let h = this.height; + if let Some(child) = this.get_child() { + if child.width == 0 { + child.width = w; + } + if child.height == 0 { + child.height = h; + } + child.style.is_active = true; + render_to_frame(&mut frame, child); + } + let mut v: String = " ".repeat((this.width / 2) - this.children.len()); + for (i, _) in (&this.children).into_iter().enumerate() { + if i == this.child { + v += this.style.write_clicked("*").as_str() + } else { + v += this.style.write("*").as_str() + } + } + format!("{}\n{}", v, frame.join("\n")) + } + + fn tick(this: &mut Component, i: usize) { + if let Some(child) = this.get_child() { + return (child.tick)(child, i); + } + } + + component.update = update; + component.tick = tick; + component.render = render; + component +} diff --git a/src/key.rs b/src/key.rs index 0931e70..b4c131e 100644 --- a/src/key.rs +++ b/src/key.rs @@ -3,6 +3,8 @@ use std::io::{self, Read}; #[derive(Debug, Clone, Hash, Eq, PartialEq)] pub enum KeyKind { Enter, + Tab, + ShiftTab, Escape, Up, Down, @@ -19,17 +21,21 @@ pub struct Key { impl Key { pub fn new(k: String) -> Key { - let kind = match k.as_str() { - "\r" => KeyKind::Enter, - "\x1b" => KeyKind::Escape, - "\x1b[A" => KeyKind::Up, - "\x1b[B" => KeyKind::Down, - "\x1b[C" => KeyKind::Right, - "\x1b[D" => KeyKind::Left, + Key { + raw: k.clone(), + kind: match k.as_str() { + "\r" => KeyKind::Enter, + "\t" => KeyKind::Tab, + "\x1b[Z" => KeyKind::ShiftTab, + "\x1b" => KeyKind::Escape, + "\x1b[A" => KeyKind::Up, + "\x1b[B" => KeyKind::Down, + "\x1b[C" => KeyKind::Right, + "\x1b[D" => KeyKind::Left, - _ => KeyKind::Char(k.clone()), - }; - Key { raw: k, kind } + _ => KeyKind::Char(k.clone()), + }, + } } } diff --git a/src/lib.rs b/src/lib.rs index e303a85..5c3b2b0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,18 +51,6 @@ impl Component { pub fn get_child(&mut self) -> Option<&mut Component> { self.children.get_mut(self.child) } - - pub fn set_child(&mut self, idx: usize) { - if let Some(child) = self.children.get_mut(idx) { - self.child = idx; - if child.width == 0 { - child.width = self.width; - } - if child.height == 0 { - child.height = self.height; - } - } - } } #[derive(Debug, Clone, PartialEq)] diff --git a/src/main.rs b/src/main.rs index b5743a2..c25bc94 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,9 +16,14 @@ fn onclick(c: &mut Component) { fn app_elem() -> Component { oml!( - div { - button("click me"; toggle = false, on_click = onclick) - button("click me"; toggle = false, y = 2, on_click = onclick) + tab { + div { + text("Hello, World!";) + } + + div { + button("click me"; toggle = false, on_click = onclick) + } } ) } diff --git a/src/utils.rs b/src/utils.rs index 302a0b9..2881510 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -64,7 +64,9 @@ fn merge_line(frame_: &str, line_: &str, x: usize) -> String { if let Some(v) = lm.get(&(i - x)) { res.push_str(v); } - if line[i - x] != '\n' { + if line[i - x] == '\n' { + res.push(frame[i]); + } else { res.push(line[i - x]); } } else {