From 2f9d52e15e5b1aa63a48df06250f5f8588d0a8b5 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Thu, 3 Jul 2025 09:44:28 -0500 Subject: [PATCH] mouse input --- src/extensions/mod.rs | 9 +++++--- src/extensions/mouse.rs | 44 ++++++++++++++++++++++++++++++++++++++ src/extensions/tick.rs | 2 +- src/extensions/velocity.rs | 2 +- src/lib.rs | 22 +++++++++---------- src/main.rs | 6 +++++- src/render.rs | 4 ++++ 7 files changed, 71 insertions(+), 18 deletions(-) create mode 100644 src/extensions/mouse.rs diff --git a/src/extensions/mod.rs b/src/extensions/mod.rs index 4935328..426c7e9 100644 --- a/src/extensions/mod.rs +++ b/src/extensions/mod.rs @@ -1,11 +1,14 @@ +pub mod mouse; pub mod tick; pub mod velocity; use std::sync::Arc; -use crate::widget::Widget; +use minifb::Window; + +use crate::{style::RawTransform, widget::Widget}; pub trait Extension { - fn init(&self, _widgets: &Vec>) {} - fn render(&self, _widget: &Arc) {} + fn init(&mut self, _widgets: &Vec>) {} + fn render(&mut self, _widgets: &Arc, _transform: RawTransform, _win: &Window) {} } diff --git a/src/extensions/mouse.rs b/src/extensions/mouse.rs new file mode 100644 index 0000000..a4d93cf --- /dev/null +++ b/src/extensions/mouse.rs @@ -0,0 +1,44 @@ +use std::sync::Arc; + +use minifb::{MouseButton, Window}; + +use crate::{component, extensions::Extension, style::RawTransform, widget::Widget}; + +pub struct MouseExtension(bool); + +impl Extension for MouseExtension { + fn render(&mut self, widget: &Arc, transform: RawTransform, win: &Window) { + if win.get_mouse_down(MouseButton::Left) { + if !self.0 { + self.0 = true; + if let Some((mx, my)) = win.get_mouse_pos(minifb::MouseMode::Discard) { + let (mx, my) = (mx as usize, my as usize); + if mx >= transform.x + && my >= transform.y + && mx <= transform.x + transform.width + && mx <= transform.y + transform.height + { + std::thread::spawn({ + let widget = widget.clone(); + move || { + if let Some(on_click) = widget.get::() { + (on_click.0)(&widget) + } + } + }); + } + } + } + } else { + self.0 = false; + } + } +} + +impl MouseExtension { + pub fn new() -> Self { + MouseExtension(false) + } +} + +component!(OnClick(pub fn(&Arc))); diff --git a/src/extensions/tick.rs b/src/extensions/tick.rs index eed4495..9f4e1b1 100644 --- a/src/extensions/tick.rs +++ b/src/extensions/tick.rs @@ -5,7 +5,7 @@ use crate::{component, extensions::Extension, widget::Widget}; pub struct TickExtension(pub usize); impl Extension for TickExtension { - fn init(&self, widgets: &Vec>) { + fn init(&mut self, widgets: &Vec>) { let rate_dur = 1000 / self.0 as u64; std::thread::spawn({ let widgets = widgets.clone(); diff --git a/src/extensions/velocity.rs b/src/extensions/velocity.rs index 8df0868..8eda07f 100644 --- a/src/extensions/velocity.rs +++ b/src/extensions/velocity.rs @@ -42,7 +42,7 @@ impl VelocityExtension { } impl Extension for VelocityExtension { - fn init(&self, widgets: &Vec>) { + fn init(&mut self, widgets: &Vec>) { std::thread::spawn({ let widgets = widgets.clone(); move || { diff --git a/src/lib.rs b/src/lib.rs index 7ae2594..64598af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use minifb::Window; @@ -20,7 +20,7 @@ pub mod widget; pub struct Screen { window: Window, pub widgets: Vec>, - extensions: Vec>>, + extensions: Vec>>>, } impl Screen { @@ -38,7 +38,7 @@ impl Screen { } pub fn extension(&mut self, ext: E) { - self.extensions.push(Arc::new(Box::new(ext))); + self.extensions.push(Arc::new(Mutex::new(Box::new(ext)))); } pub fn run(&mut self) -> std::io::Result<()> { @@ -47,7 +47,7 @@ impl Screen { } for ext in &self.extensions { - ext.init(&self.widgets); + ext.lock().unwrap().init(&self.widgets); } while self.window.is_open() { @@ -68,13 +68,18 @@ impl Screen { scope.set_transform(&t); } - self.render_extension(elem.clone()).unwrap(); elem.0.lock().unwrap().render(&mut scope); if let Some(t) = elem.get() { scope.set_transform(&t); } + for ext in &self.extensions { + ext.lock() + .unwrap() + .render(elem, scope.get_transform(), &self.window); + } + scope.draw(); } @@ -82,11 +87,4 @@ impl Screen { .update_with_buffer(&scope.get_buffer1d(), w, h) .unwrap(); } - - pub fn render_extension(&self, wi: Arc) -> std::io::Result<()> { - for ext in &self.extensions { - ext.render(&wi); - } - Ok(()) - } } diff --git a/src/main.rs b/src/main.rs index 45df70c..4e75e81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ use minifb::{Window, WindowOptions}; use osgui::{ - elements::div::Div, extensions::velocity::VelocityExtension, style::Transform, Screen, + elements::div::Div, + extensions::{mouse::MouseExtension, velocity::VelocityExtension}, + style::Transform, + Screen, }; fn main() { @@ -17,6 +20,7 @@ fn main() { let mut app = Screen::new(window); app.extension(VelocityExtension); + app.extension(MouseExtension::new()); let mut d = Div::new(); diff --git a/src/render.rs b/src/render.rs index 8d62cf6..d324ce0 100644 --- a/src/render.rs +++ b/src/render.rs @@ -147,6 +147,10 @@ impl RenderScope { transform.use_position(self.parent_width, self.parent_height, &mut self.transform); } + pub fn get_transform(&mut self) -> RawTransform { + self.transform.clone() + } + pub fn update_size(&mut self) { self.max_size.0 = self.max_size.0.max(self.transform.width); self.max_size.1 = self.max_size.1.max(self.transform.height);