From 6d5abf277479e3b63d8d24248e039df3215d1305 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Fri, 8 Nov 2024 21:09:40 +0100 Subject: [PATCH] smol changes --- src/event.rs | 58 +++++++++++++++++++++++++++++++++++++++++++--- src/lib.rs | 1 - src/macros.rs | 28 ++++++++++++++++++++++ src/test/mod.rs | 12 ++++++---- src/ui/elements.rs | 41 +++++++++++--------------------- 5 files changed, 105 insertions(+), 35 deletions(-) diff --git a/src/event.rs b/src/event.rs index 257f58a..7ce5412 100644 --- a/src/event.rs +++ b/src/event.rs @@ -21,13 +21,58 @@ pub enum EventResponse { /// Indicates no response. None, /// Issues a single command. - Command(Command), /// Issues a list of commands. CommandList(Vec), - // Update the current element + /// Update the current element UpdateSelf(Box), - // Update a element by a id + /// Update a element by a id UpdateElementById(String, Box), + /// Multiple Responses + /// # DO NOT USE MANUALLY + Mul(Vec), +} + +impl EventResponse { + pub fn add_command(&mut self, command: Command) { + match self { + EventResponse::CommandList(commands) => { + commands.push(command); + } + EventResponse::Mul(responses) => { + for response in responses { + match response { + EventResponse::CommandList(commands) => { + commands.push(command.clone()); + return; + } + _ => {} + } + } + self.add_response(EventResponse::CommandList(vec![command.clone()])); + } + _ => {} + } + } + pub fn update_self(&mut self, elem: Box) { + self.add_response(Self::UpdateSelf(elem)); + } + pub fn update_element_by_id(&mut self, id: &str, elem: Box) { + self.add_response(Self::UpdateElementById(id.to_string(), elem)); + } + pub fn add_response(&mut self, response: EventResponse) { + match self { + EventResponse::Mul(responses) => { + responses.insert(0, response); + } + _ => *self = EventResponse::Mul(vec![response, self.clone()]), + } + } + pub fn execute(&self) -> Vec { + return match self { + EventResponse::Mul(v) => v.clone(), + _ => vec![self.clone()], + }; + } } /// Enum representing the possible responses from an element update. @@ -36,3 +81,10 @@ pub enum Event { Key(Key), State(usize), } + +/// A handler is a function that runs on a event of a element +/// +/// # Params +/// - &mut T: The element, +/// - &mut EventResponse: The event response +pub type Handler = std::sync::Arc>; diff --git a/src/lib.rs b/src/lib.rs index 3b910b8..2f6cbe5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -79,7 +79,6 @@ pub mod app { /// `true` if an `Exit` command is issued, signaling the application to terminate. fn update(elem: &mut Box, event: Event) -> bool { match elem.event(event) { - EventResponse::Command(command) => run_command(command, elem), EventResponse::CommandList(commands) => { for command in commands { if run_command(command, elem) { diff --git a/src/macros.rs b/src/macros.rs index 4804712..9fa3646 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -249,6 +249,9 @@ macro_rules! parse_rsx_param { ($elem:expr, $text:expr) => { $elem.text = format!($text); }; + ($elem:expr, $text:expr, $($inner:tt)*) => { + $elem.text = format!($text, $($inner)*); + }; // Empty ($elem:expr, ) => {}; @@ -395,3 +398,28 @@ macro_rules! write { ) }}; } + +#[macro_export] +macro_rules! execute_response { + ($self:expr, $res:expr) => { + for response in $res.execute() { + match response { + EventResponse::UpdateElementById(id, elem) => { + for old in &mut $self.children { + if old.get_id() == id { + *old = elem.clone(); + } + } + } + EventResponse::UpdateSelf(elem) => { + if let Some(child) = $self.get_child() { + *child = elem; + } + } + _ => { + return response; + } + } + } + }; +} \ No newline at end of file diff --git a/src/test/mod.rs b/src/test/mod.rs index c5d0d43..11cd08c 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -1,11 +1,15 @@ use crate::{self as osui, arc, rsx, rsx_elem, ui::*, Element, EventResponse}; pub fn app() -> Box { + let mut something = String::from("!"); rsx! { - button { on_click: arc!(move |btn: &mut Button| { - btn.event_response = EventResponse::UpdateElementById("my_id".to_string(), rsx_elem! { button { y: 2, id: "my_id", "updated!" } } ); - }), "click me" } + button { on_click: arc!(move |_btn: &mut Button, response: &mut EventResponse| { + something += "!"; + response.update_element_by_id("my_id", rsx_elem! { + text { id: "my_id", y: 2, "{something}" } + }); + }), style.clicked_background: Color::Green, "click me" } - button { id: "my_id", y: 2, "ok" } + text { id: "my_id", y: 2, "!" } } } diff --git a/src/ui/elements.rs b/src/ui/elements.rs index 8b77f92..1cd9080 100644 --- a/src/ui/elements.rs +++ b/src/ui/elements.rs @@ -5,7 +5,8 @@ use std::{ use crate::{ command, element, - event::{Command, Event}, + event::{Command, Event, Handler}, + execute_response, key::Key, render_to_frame, ui::{Color, Font}, @@ -36,16 +37,11 @@ element! { /// based on its interaction state, such as being "clicked". Button { /// A callback function executed when the button is clicked. use `arc!` to use function - pub on_click: Arc>, - pub event_response: EventResponse, + pub on_click: Handler>, } defaults { - on_click: Arc::new(Mutex::new(|_btn: &mut Button<'_>| {})), - event_response: command!( - Command::Render(2), - Command::Sleep(120) - ), + on_click: Arc::new(Mutex::new(|_btn: &mut Button<'_>, _: &mut EventResponse| {})), } fn render(&self, state: usize) -> String { @@ -61,10 +57,14 @@ element! { if k == Key::Enter { let mut btn = self.clone(); let mut on_click = self.on_click.lock().unwrap(); - (on_click)(&mut btn); + let mut response = command!( + Command::Render(2), + Command::Sleep(120) + ); + (on_click)(&mut btn, &mut response); drop(on_click); *self = btn; - return self.event_response.clone(); + return response; } } _ => {} @@ -105,31 +105,18 @@ element! { } fn event(&mut self, event: Event) -> EventResponse { + let mut res = EventResponse::None; match event.clone() { Event::Key(k) => { if let Some(direction) = self.keybinds.get(&k) { self.child = crate::closest_component(&self.children, self.child, direction.clone()); } else if let Some(child) = self.get_child() { - let res = child.event(event.clone()); - match res.clone() { - EventResponse::UpdateElementById(id, elem) => { - for old in &mut self.children { - if old.get_id() == id { - *old = elem.clone(); - } - } - } - EventResponse::UpdateSelf(elem) => { - *child = elem; - } - _ => {} - } - return res; + res = child.event(event.clone()); } } _ => {} } - - EventResponse::None + execute_response!(self, res); + res } }