smol changes

This commit is contained in:
2024-11-08 21:09:40 +01:00
parent c65bd68be5
commit 6d5abf2774
5 changed files with 105 additions and 35 deletions
+55 -3
View File
@@ -21,13 +21,58 @@ pub enum EventResponse {
/// Indicates no response. /// Indicates no response.
None, None,
/// Issues a single command. /// Issues a single command.
Command(Command),
/// Issues a list of commands. /// Issues a list of commands.
CommandList(Vec<Command>), CommandList(Vec<Command>),
// Update the current element /// Update the current element
UpdateSelf(Box<dyn crate::Element>), UpdateSelf(Box<dyn crate::Element>),
// Update a element by a id /// Update a element by a id
UpdateElementById(String, Box<dyn crate::Element>), UpdateElementById(String, Box<dyn crate::Element>),
/// Multiple Responses
/// # DO NOT USE MANUALLY
Mul(Vec<EventResponse>),
}
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<dyn crate::Element>) {
self.add_response(Self::UpdateSelf(elem));
}
pub fn update_element_by_id(&mut self, id: &str, elem: Box<dyn crate::Element>) {
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<EventResponse> {
return match self {
EventResponse::Mul(v) => v.clone(),
_ => vec![self.clone()],
};
}
} }
/// Enum representing the possible responses from an element update. /// Enum representing the possible responses from an element update.
@@ -36,3 +81,10 @@ pub enum Event {
Key(Key), Key(Key),
State(usize), 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<T> = std::sync::Arc<std::sync::Mutex<dyn FnMut(&mut T, &mut EventResponse)>>;
-1
View File
@@ -79,7 +79,6 @@ pub mod app {
/// `true` if an `Exit` command is issued, signaling the application to terminate. /// `true` if an `Exit` command is issued, signaling the application to terminate.
fn update(elem: &mut Box<dyn Element>, event: Event) -> bool { fn update(elem: &mut Box<dyn Element>, event: Event) -> bool {
match elem.event(event) { match elem.event(event) {
EventResponse::Command(command) => run_command(command, elem),
EventResponse::CommandList(commands) => { EventResponse::CommandList(commands) => {
for command in commands { for command in commands {
if run_command(command, elem) { if run_command(command, elem) {
+28
View File
@@ -249,6 +249,9 @@ macro_rules! parse_rsx_param {
($elem:expr, $text:expr) => { ($elem:expr, $text:expr) => {
$elem.text = format!($text); $elem.text = format!($text);
}; };
($elem:expr, $text:expr, $($inner:tt)*) => {
$elem.text = format!($text, $($inner)*);
};
// Empty // Empty
($elem:expr, ) => {}; ($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;
}
}
}
};
}
+8 -4
View File
@@ -1,11 +1,15 @@
use crate::{self as osui, arc, rsx, rsx_elem, ui::*, Element, EventResponse}; use crate::{self as osui, arc, rsx, rsx_elem, ui::*, Element, EventResponse};
pub fn app() -> Box<dyn Element> { pub fn app() -> Box<dyn Element> {
let mut something = String::from("!");
rsx! { rsx! {
button { on_click: arc!(move |btn: &mut Button| { button { on_click: arc!(move |_btn: &mut Button, response: &mut EventResponse| {
btn.event_response = EventResponse::UpdateElementById("my_id".to_string(), rsx_elem! { button { y: 2, id: "my_id", "updated!" } } ); something += "!";
}), "click me" } 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, "!" }
} }
} }
+14 -27
View File
@@ -5,7 +5,8 @@ use std::{
use crate::{ use crate::{
command, element, command, element,
event::{Command, Event}, event::{Command, Event, Handler},
execute_response,
key::Key, key::Key,
render_to_frame, render_to_frame,
ui::{Color, Font}, ui::{Color, Font},
@@ -36,16 +37,11 @@ element! {
/// based on its interaction state, such as being "clicked". /// based on its interaction state, such as being "clicked".
Button { Button {
/// A callback function executed when the button is clicked. use `arc!` to use function /// A callback function executed when the button is clicked. use `arc!` to use function
pub on_click: Arc<Mutex<dyn FnMut(&mut Button)>>, pub on_click: Handler<Button<'a>>,
pub event_response: EventResponse,
} }
defaults { defaults {
on_click: Arc::new(Mutex::new(|_btn: &mut Button<'_>| {})), on_click: Arc::new(Mutex::new(|_btn: &mut Button<'_>, _: &mut EventResponse| {})),
event_response: command!(
Command::Render(2),
Command::Sleep(120)
),
} }
fn render(&self, state: usize) -> String { fn render(&self, state: usize) -> String {
@@ -61,10 +57,14 @@ element! {
if k == Key::Enter { if k == Key::Enter {
let mut btn = self.clone(); let mut btn = self.clone();
let mut on_click = self.on_click.lock().unwrap(); 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); drop(on_click);
*self = btn; *self = btn;
return self.event_response.clone(); return response;
} }
} }
_ => {} _ => {}
@@ -105,31 +105,18 @@ element! {
} }
fn event(&mut self, event: Event) -> EventResponse { fn event(&mut self, event: Event) -> EventResponse {
let mut res = EventResponse::None;
match event.clone() { match event.clone() {
Event::Key(k) => { Event::Key(k) => {
if let Some(direction) = self.keybinds.get(&k) { if let Some(direction) = self.keybinds.get(&k) {
self.child = crate::closest_component(&self.children, self.child, direction.clone()); self.child = crate::closest_component(&self.children, self.child, direction.clone());
} else if let Some(child) = self.get_child() { } else if let Some(child) = self.get_child() {
let res = child.event(event.clone()); 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;
} }
} }
_ => {} _ => {}
} }
execute_response!(self, res);
EventResponse::None res
} }
} }