diff --git a/src/components.rs b/src/components.rs index 5659501..923a990 100644 --- a/src/components.rs +++ b/src/components.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; use crate::{ create_frame, - key::{Key, KeyKind}, + key::KeyKind, utils::{closest_component, render_to_frame}, - Component, UpdateResponse, + Component, UpdateRequest, UpdateResponse, }; pub fn div() -> Component { @@ -17,8 +17,8 @@ pub fn div() -> Component { (KeyKind::Right, String::from("right")), ]); - fn update(this: &mut Component, k: Key) -> UpdateResponse { - if let Some(v) = this.binds.get(&k.kind) { + fn update(this: &mut Component, req: UpdateRequest) -> UpdateResponse { + if let Some(v) = this.binds.get(&req.key.kind) { match v.as_str() { "up" => { this.active_child = closest_component( @@ -54,13 +54,13 @@ pub fn div() -> Component { _ => { if let Some(child) = this.get_active_child() { - return (child.update)(child, k); + return (child.update)(child, req); } } } } else { if let Some(child) = this.get_active_child() { - return (child.update)(child, k); + return (child.update)(child, req); } } @@ -83,7 +83,7 @@ pub fn div() -> Component { pub fn text() -> Component { let mut component = Component::new(); - fn update(_: &mut Component, _: Key) -> UpdateResponse { + fn update(_: &mut Component, _: UpdateRequest) -> UpdateResponse { UpdateResponse::None } @@ -99,14 +99,15 @@ pub fn text() -> Component { pub fn button() -> Component { let mut component = Component::new(); - fn update(this: &mut Component, k: Key) -> UpdateResponse { - if k.kind == KeyKind::Enter { + fn update(this: &mut Component, req: UpdateRequest) -> UpdateResponse { + if req.key.kind == KeyKind::Enter { if this.toggle { this.clicked = !this.clicked; (this.on_click)(this); } else { this.clicked = true; (this.on_click)(this); + std::thread::sleep(std::time::Duration::from_millis(300)); this.clicked = false; (this.on_click)(this); } diff --git a/src/lib.rs b/src/lib.rs index 00b73a8..da6ea7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,10 +13,15 @@ pub enum UpdateResponse { None, } +pub struct UpdateRequest<'a> { + pub key: key::Key, + pub screen: &'a App, +} + #[derive(Debug, Clone, PartialEq)] pub struct Component { pub render: fn(&mut Component) -> String, - pub update: fn(&mut Component, key::Key) -> UpdateResponse, + pub update: fn(&mut Component, UpdateRequest) -> UpdateResponse, pub on_click: fn(&mut Component), pub x: usize, pub y: usize, @@ -51,18 +56,11 @@ impl Component { } pub fn get_active_child(&mut self) -> Option<&mut Component> { - if self.active_child < self.children.len() { - return self.children.get_mut(self.active_child); - } - None - } - - fn manhattan_distance(&self, other: &Component) -> usize { - self.x.abs_diff(other.x) + self.y.abs_diff(other.y) + self.children.get_mut(self.active_child) } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct App { component: Component, } @@ -104,8 +102,13 @@ impl App { crossterm::terminal::enable_raw_mode().unwrap(); loop { self.render(); - self.component.expr = "Hello".to_string(); - match (self.component.update)(&mut self.component, key::read_key()) { + match (self.component.update)( + &mut self.component, + UpdateRequest { + key: key::read_key(), + screen: self, // error: cannot borrow `*self` as immutable because it is also borrowed as mutable (IMPORTANT) + }, + ) { UpdateResponse::Exit => { crossterm::terminal::disable_raw_mode().unwrap(); utils::clear(); diff --git a/src/main.rs b/src/main.rs index 9280093..b5743a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,8 +17,8 @@ fn onclick(c: &mut Component) { fn app_elem() -> Component { oml!( div { - button("click me"; toggle = true, on_click = onclick) - button("click me"; toggle = true, y = 2, on_click = onclick) + button("click me"; toggle = false, on_click = onclick) + button("click me"; toggle = false, y = 2, on_click = onclick) } ) } diff --git a/src/utils.rs b/src/utils.rs index 345f897..4b33995 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -124,7 +124,7 @@ pub fn closest_component( Direction::Up => comp.y < current.y && comp.x == current.x, // Up Direction::Down => comp.y > current.y && comp.x == current.x, // Down }) - .min_by_key(|(_, comp)| current.manhattan_distance(comp)) // Find the closest component + .min_by_key(|(_, comp)| current.x.abs_diff(comp.x) + current.y.abs_diff(comp.y)) // Find the closest component .map(|(index, _)| index) // Return the index of the closest component .unwrap_or(current_index) // If no component is found, return the current index }