diff --git a/bin/darkwallet/src/gfx/linalg.rs b/bin/darkwallet/src/gfx/linalg.rs new file mode 100644 index 000000000..17fb94289 --- /dev/null +++ b/bin/darkwallet/src/gfx/linalg.rs @@ -0,0 +1,183 @@ +/* This file is part of DarkFi (https://dark.fi) + * + * Copyright (C) 2020-2024 Dyne.org foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +use std::ops::{Add, Sub}; + +#[derive(Clone, Copy, Debug)] +pub struct Point { + pub x: f32, + pub y: f32, +} + +impl Point { + pub fn new(x: f32, y: f32) -> Self { + Self { x, y } + } + + pub fn unpack(&self) -> (f32, f32) { + (self.x, self.y) + } + + pub fn as_arr(&self) -> [f32; 2] { + [self.x, self.y] + } + + pub fn offset(&self, off_x: f32, off_y: f32) -> Self { + Self { x: self.x + off_x, y: self.y + off_y } + } + + pub fn to_rect(&self, w: f32, h: f32) -> Rectangle { + Rectangle { x: self.x, y: self.y, w, h } + } +} + +impl From<[f32; 2]> for Point { + fn from(pos: [f32; 2]) -> Self { + Self { x: pos[0], y: pos[1] } + } +} + +impl Add for Point { + type Output = Self; + + fn add(self, other: Self) -> Self::Output { + Self { x: self.x + other.x, y: self.y + other.y } + } +} + +impl Sub for Point { + type Output = Self; + + fn sub(self, other: Self) -> Self::Output { + Self { x: self.x - other.x, y: self.y - other.y } + } +} + +#[derive(Debug, Clone)] +pub struct Rectangle { + pub x: f32, + pub y: f32, + pub w: f32, + pub h: f32, +} + +impl Rectangle { + pub fn new(x: f32, y: f32, w: f32, h: f32) -> Self { + Self { x, y, w, h } + } + + pub fn zero() -> Self { + Self { x: 0., y: 0., w: 0., h: 0. } + } + + pub fn from_array(arr: [f32; 4]) -> Self { + Self { x: arr[0], y: arr[1], w: arr[2], h: arr[3] } + } + + pub fn clip(&self, other: &Self) -> Option { + if other.x + other.w < self.x || + other.x > self.x + self.w || + other.y + other.h < self.y || + other.y > self.y + self.h + { + return None + } + + let mut clipped = other.clone(); + if clipped.x < self.x { + clipped.x = self.x; + clipped.w = other.x + other.w - clipped.x; + } + if clipped.y < self.y { + clipped.y = self.y; + clipped.h = other.y + other.h - clipped.y; + } + if clipped.x + clipped.w > self.x + self.w { + clipped.w = self.x + self.w - clipped.x; + } + if clipped.y + clipped.h > self.y + self.h { + clipped.h = self.y + self.h - clipped.y; + } + Some(clipped) + } + + pub fn clip_point(&self, point: &mut Point) { + if point.x < self.x { + point.x = self.x; + } + if point.y < self.y { + point.y = self.y; + } + if point.x > self.x + self.w { + point.x = self.x + self.w; + } + if point.y > self.y + self.h { + point.y = self.y + self.h; + } + } + + pub fn contains(&self, point: Point) -> bool { + self.x <= point.x && + point.x <= self.x + self.w && + self.y <= point.y && + point.y <= self.y + self.h + } + + pub fn rhs(&self) -> f32 { + self.x + self.w + } + pub fn bhs(&self) -> f32 { + self.y + self.h + } + + pub fn pos(&self) -> Point { + Point { x: self.x, y: self.y } + } + pub fn corner(&self) -> Point { + Point { x: self.x + self.w, y: self.y + self.h } + } + + #[deprecated] + pub fn top_left(&self) -> Point { + Point { x: self.x, y: self.y } + } + #[deprecated] + pub fn bottom_right(&self) -> Point { + Point { x: self.x + self.w, y: self.y + self.h } + } + + pub fn includes(&self, child: &Self) -> bool { + self.contains(child.pos()) && self.contains(child.corner()) + } +} + +impl Add for Rectangle { + type Output = Rectangle; + + fn add(self, other: Point) -> Self::Output { + Self { x: self.x + other.x, y: self.y + other.y, w: self.w, h: self.h } + } +} + +impl Sub for Rectangle { + type Output = Rectangle; + + fn sub(self, other: Point) -> Self::Output { + Self { x: self.x - other.x, y: self.y - other.y, w: self.w, h: self.h } + } +} diff --git a/bin/darkwallet/src/gfx/mod.rs b/bin/darkwallet/src/gfx/mod.rs index da4dfc61d..c0f8828ca 100644 --- a/bin/darkwallet/src/gfx/mod.rs +++ b/bin/darkwallet/src/gfx/mod.rs @@ -30,6 +30,8 @@ use std::{ time::{Duration, Instant}, }; +mod linalg; +pub use linalg::{Point, Rectangle}; mod shader; use crate::{ @@ -63,125 +65,6 @@ impl Vertex { } } -#[derive(Clone, Debug)] -pub struct Point { - pub x: f32, - pub y: f32, -} - -impl Point { - pub fn unpack(&self) -> (f32, f32) { - (self.x, self.y) - } - - pub fn as_arr(&self) -> [f32; 2] { - [self.x, self.y] - } - - pub fn offset(&self, off_x: f32, off_y: f32) -> Self { - Self { x: self.x + off_x, y: self.y + off_y } - } - - pub fn to_rect(&self, w: f32, h: f32) -> Rectangle { - Rectangle { x: self.x, y: self.y, w, h } - } -} - -impl From<[f32; 2]> for Point { - fn from(pos: [f32; 2]) -> Self { - Self { x: pos[0], y: pos[1] } - } -} - -#[derive(Debug, Clone)] -pub struct Rectangle { - pub x: f32, - pub y: f32, - pub w: f32, - pub h: f32, -} - -impl Rectangle { - pub fn new(x: f32, y: f32, w: f32, h: f32) -> Self { - Self { x, y, w, h } - } - - pub fn zero() -> Self { - Self { x: 0., y: 0., w: 0., h: 0. } - } - - pub fn from_array(arr: [f32; 4]) -> Self { - Self { x: arr[0], y: arr[1], w: arr[2], h: arr[3] } - } - - pub fn clip(&self, other: &Self) -> Option { - if other.x + other.w < self.x || - other.x > self.x + self.w || - other.y + other.h < self.y || - other.y > self.y + self.h - { - return None - } - - let mut clipped = other.clone(); - if clipped.x < self.x { - clipped.x = self.x; - clipped.w = other.x + other.w - clipped.x; - } - if clipped.y < self.y { - clipped.y = self.y; - clipped.h = other.y + other.h - clipped.y; - } - if clipped.x + clipped.w > self.x + self.w { - clipped.w = self.x + self.w - clipped.x; - } - if clipped.y + clipped.h > self.y + self.h { - clipped.h = self.y + self.h - clipped.y; - } - Some(clipped) - } - - pub fn clip_point(&self, point: &mut Point) { - if point.x < self.x { - point.x = self.x; - } - if point.y < self.y { - point.y = self.y; - } - if point.x > self.x + self.w { - point.x = self.x + self.w; - } - if point.y > self.y + self.h { - point.y = self.y + self.h; - } - } - - pub fn contains(&self, point: &Point) -> bool { - self.x <= point.x && - point.x <= self.x + self.w && - self.y <= point.y && - point.y <= self.y + self.h - } - - pub fn rhs(&self) -> f32 { - self.x + self.w - } - pub fn bhs(&self) -> f32 { - self.y + self.h - } - - pub fn top_left(&self) -> Point { - Point { x: self.x, y: self.y } - } - pub fn bottom_right(&self) -> Point { - Point { x: self.x + self.w, y: self.y + self.h } - } - - pub fn includes(&self, child: &Self) -> bool { - self.contains(&child.top_left()) && self.contains(&child.bottom_right()) - } -} - pub type RenderApiPtr = Arc; pub struct RenderApi { diff --git a/bin/darkwallet/src/prop/mod.rs b/bin/darkwallet/src/prop/mod.rs index 5efebb5a2..005d9cfdf 100644 --- a/bin/darkwallet/src/prop/mod.rs +++ b/bin/darkwallet/src/prop/mod.rs @@ -31,7 +31,8 @@ use crate::{ mod wrap; pub use wrap::{ - PropertyBool, PropertyColor, PropertyFloat32, PropertyRect, PropertyStr, PropertyUint32, + PropertyBool, PropertyColor, PropertyFloat32, PropertyPoint, PropertyRect, PropertyStr, + PropertyUint32, }; type Buffer = Arc>; diff --git a/bin/darkwallet/src/prop/wrap.rs b/bin/darkwallet/src/prop/wrap.rs index 25b784d31..467295a36 100644 --- a/bin/darkwallet/src/prop/wrap.rs +++ b/bin/darkwallet/src/prop/wrap.rs @@ -19,7 +19,7 @@ use crate::{ error::{Error, Result}, expr::{SExprMachine, SExprVal}, - gfx::Rectangle, + gfx::{Point, Rectangle}, scene::SceneNode, }; @@ -193,6 +193,40 @@ impl PropertyColor { } } +#[derive(Clone)] +pub struct PropertyPoint { + prop: PropertyPtr, + role: Role, +} + +impl PropertyPoint { + pub fn wrap(node: &SceneNode, role: Role, prop_name: &str) -> Result { + let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?; + + if !prop.is_bounded() || prop.get_len() != 2 { + return Err(Error::PropertyWrongLen) + } + + // Test if it works + let _ = prop.get_f32(0)?; + + Ok(Self { prop, role }) + } + + pub fn get(&self) -> Point { + [self.prop.get_f32(0).unwrap(), self.prop.get_f32(1).unwrap()].into() + } + + pub fn set(&self, pos: Point) { + self.prop.set_f32(self.role, 0, pos.x).unwrap(); + self.prop.set_f32(self.role, 1, pos.y).unwrap(); + } + + pub fn prop(&self) -> PropertyPtr { + self.prop.clone() + } +} + #[derive(Clone)] pub struct PropertyRect { prop: PropertyPtr, diff --git a/bin/darkwallet/src/ui/button.rs b/bin/darkwallet/src/ui/button.rs index 9a81093fc..6a3f2580e 100644 --- a/bin/darkwallet/src/ui/button.rs +++ b/bin/darkwallet/src/ui/button.rs @@ -90,7 +90,7 @@ impl UIObject for Button { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { if !self.is_active.get() { return false @@ -113,7 +113,7 @@ impl UIObject for Button { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { if !self.is_active.get() { return false @@ -147,7 +147,7 @@ impl UIObject for Button { sg: &SceneGraph, phase: TouchPhase, id: u64, - touch_pos: &Point, + touch_pos: Point, ) -> bool { if !self.is_active.get() { return false diff --git a/bin/darkwallet/src/ui/chatview/mod.rs b/bin/darkwallet/src/ui/chatview/mod.rs index 25e26b557..05fcf75ff 100644 --- a/bin/darkwallet/src/ui/chatview/mod.rs +++ b/bin/darkwallet/src/ui/chatview/mod.rs @@ -756,7 +756,7 @@ impl UIObject for ChatView { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { if btn != MouseButton::Left { return false @@ -776,17 +776,17 @@ impl UIObject for ChatView { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { if btn != MouseButton::Left { return false } self.mouse_btn_held.store(false, Ordering::Relaxed); - true + false } - async fn handle_mouse_move(&self, sg: &SceneGraph, mouse_pos: &Point) -> bool { + async fn handle_mouse_move(&self, sg: &SceneGraph, mouse_pos: Point) -> bool { //debug!(target: "ui::chatview", "handle_mouse_move({mouse_x}, {mouse_y})"); // We store the mouse pos for use in handle_mouse_wheel() @@ -805,13 +805,13 @@ impl UIObject for ChatView { false } - async fn handle_mouse_wheel(&self, sg: &SceneGraph, wheel_pos: &Point) -> bool { + async fn handle_mouse_wheel(&self, sg: &SceneGraph, wheel_pos: Point) -> bool { //debug!(target: "ui::chatview", "handle_mouse_wheel({wheel_x}, {wheel_y})"); let rect = self.rect.get(); let mouse_pos = self.mouse_pos.lock().unwrap().clone(); - if !rect.contains(&mouse_pos) { + if !rect.contains(mouse_pos) { //debug!(target: "ui::chatview", "not inside rect"); return false } @@ -826,7 +826,7 @@ impl UIObject for ChatView { sg: &SceneGraph, phase: TouchPhase, id: u64, - touch_pos: &Point, + touch_pos: Point, ) -> bool { // Ignore multi-touch if id != 0 { diff --git a/bin/darkwallet/src/ui/editbox.rs b/bin/darkwallet/src/ui/editbox.rs index fa8916517..9e42106e6 100644 --- a/bin/darkwallet/src/ui/editbox.rs +++ b/bin/darkwallet/src/ui/editbox.rs @@ -432,7 +432,7 @@ impl EditBox { self.redraw().await; } - async fn handle_click_down(&self, btn: MouseButton, mouse_pos: &Point) { + async fn handle_click_down(&self, btn: MouseButton, mouse_pos: Point) { if btn != MouseButton::Left { return } @@ -442,7 +442,7 @@ impl EditBox { // clicking inside box will: // 1. make it active // 2. begin selection - if rect.contains(&mouse_pos) { + if rect.contains(mouse_pos) { window::show_keyboard(true); if self.is_focused.get() { @@ -476,7 +476,7 @@ impl EditBox { self.redraw().await; } - fn handle_click_up(&self, btn: MouseButton, pos: &Point) { + fn handle_click_up(&self, btn: MouseButton, pos: Point) { if btn != MouseButton::Left { return } @@ -484,7 +484,7 @@ impl EditBox { // releasing mouse button will end selection self.mouse_btn_held.store(false, Ordering::Relaxed); } - async fn handle_cursor_move(&self, pos: &Point) { + async fn handle_cursor_move(&self, pos: Point) { if !self.mouse_btn_held.load(Ordering::Relaxed) { return; } @@ -504,7 +504,7 @@ impl EditBox { self.redraw().await; } - async fn handle_touch(&self, phase: TouchPhase, id: u64, touch_pos: &Point) { + async fn handle_touch(&self, phase: TouchPhase, id: u64, touch_pos: Point) { // Ignore multi-touch if id != 0 { return @@ -1115,7 +1115,7 @@ impl UIObject for EditBox { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { if !self.is_active.get() { return true @@ -1129,7 +1129,7 @@ impl UIObject for EditBox { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { if !self.is_active.get() { return true @@ -1139,7 +1139,7 @@ impl UIObject for EditBox { true } - async fn handle_mouse_move(&self, sg: &SceneGraph, mouse_pos: &Point) -> bool { + async fn handle_mouse_move(&self, sg: &SceneGraph, mouse_pos: Point) -> bool { if !self.is_active.get() { return false } @@ -1153,7 +1153,7 @@ impl UIObject for EditBox { sg: &SceneGraph, phase: TouchPhase, id: u64, - touch_pos: &Point, + touch_pos: Point, ) -> bool { if !self.is_active.get() { return true diff --git a/bin/darkwallet/src/ui/layer.rs b/bin/darkwallet/src/ui/layer.rs index 83cbd2899..5c43f7bdc 100644 --- a/bin/darkwallet/src/ui/layer.rs +++ b/bin/darkwallet/src/ui/layer.rs @@ -124,7 +124,6 @@ impl UIObject for Layer { self.z_index.get() } - //#[async_recursion] async fn draw(&self, sg: &SceneGraph, parent_rect: &Rectangle) -> Option { debug!(target: "ui::layer", "Layer::draw()"); let node = sg.get_node(self.node_id).unwrap(); @@ -135,22 +134,20 @@ impl UIObject for Layer { } self.rect.eval(parent_rect).ok()?; - let mut rect = self.rect.get(); - rect.x += parent_rect.x; - rect.y += parent_rect.x; + let mut screen_rect = self.rect.get() + parent_rect.pos(); - if !parent_rect.includes(&rect) { + if !parent_rect.includes(&screen_rect) { error!( target: "ui::layer", "layer '{}':{} rect {:?} is not inside parent {:?}", - node.name, node.id, rect, parent_rect + node.name, node.id, screen_rect, parent_rect ); return None } debug!(target: "ui::layer", "Parent rect: {:?}", parent_rect); - debug!(target: "ui::layer", "Viewport rect: {:?}", rect); + debug!(target: "ui::layer", "Viewport rect: {:?}", screen_rect); // Apply viewport @@ -162,7 +159,7 @@ impl UIObject for Layer { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); - let Some(mut draw_update) = obj.draw(sg, &rect).await else { + let Some(mut draw_update) = obj.draw(sg, &screen_rect).await else { debug!(target: "ui::layer", "Skipped draw() of {node:?}"); continue }; @@ -174,7 +171,7 @@ impl UIObject for Layer { } let dc = GfxDrawCall { - instrs: vec![GfxDrawInstruction::ApplyViewport(rect)], + instrs: vec![GfxDrawInstruction::ApplyViewport(screen_rect)], dcs: child_calls, z_index: 0, }; @@ -224,7 +221,7 @@ impl UIObject for Layer { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); @@ -239,7 +236,7 @@ impl UIObject for Layer { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); @@ -250,7 +247,7 @@ impl UIObject for Layer { } false } - async fn handle_mouse_move(&self, sg: &SceneGraph, mouse_pos: &Point) -> bool { + async fn handle_mouse_move(&self, sg: &SceneGraph, mouse_pos: Point) -> bool { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); @@ -260,7 +257,7 @@ impl UIObject for Layer { } false } - async fn handle_mouse_wheel(&self, sg: &SceneGraph, wheel_pos: &Point) -> bool { + async fn handle_mouse_wheel(&self, sg: &SceneGraph, wheel_pos: Point) -> bool { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); @@ -275,7 +272,7 @@ impl UIObject for Layer { sg: &SceneGraph, phase: TouchPhase, id: u64, - touch_pos: &Point, + touch_pos: Point, ) -> bool { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); diff --git a/bin/darkwallet/src/ui/mod.rs b/bin/darkwallet/src/ui/mod.rs index 0fb71b147..1d7e68f51 100644 --- a/bin/darkwallet/src/ui/mod.rs +++ b/bin/darkwallet/src/ui/mod.rs @@ -80,7 +80,7 @@ pub trait UIObject: Sync { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { false } @@ -88,14 +88,14 @@ pub trait UIObject: Sync { &self, sg: &SceneGraph, btn: MouseButton, - mouse_pos: &Point, + mouse_pos: Point, ) -> bool { false } - async fn handle_mouse_move(&self, sg: &SceneGraph, mouse_pos: &Point) -> bool { + async fn handle_mouse_move(&self, sg: &SceneGraph, mouse_pos: Point) -> bool { false } - async fn handle_mouse_wheel(&self, sg: &SceneGraph, wheel_pos: &Point) -> bool { + async fn handle_mouse_wheel(&self, sg: &SceneGraph, wheel_pos: Point) -> bool { false } async fn handle_touch( @@ -103,7 +103,7 @@ pub trait UIObject: Sync { sg: &SceneGraph, phase: TouchPhase, id: u64, - touch_pos: &Point, + touch_pos: Point, ) -> bool { false } diff --git a/bin/darkwallet/src/ui/win.rs b/bin/darkwallet/src/ui/win.rs index 54cc2efb4..544a7eeb4 100644 --- a/bin/darkwallet/src/ui/win.rs +++ b/bin/darkwallet/src/ui/win.rs @@ -21,7 +21,7 @@ use std::sync::{Arc, Weak}; use crate::{ gfx::{GfxDrawCall, GraphicsEventPublisherPtr, Point, Rectangle, RenderApiPtr}, - prop::{PropertyPtr, Role}, + prop::{PropertyFloat32, PropertyPtr, Role}, pubsub::Subscription, scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId}, ExecutorPtr, @@ -38,7 +38,8 @@ pub struct Window { // Task is dropped at the end of the scope for Window, hence ending it #[allow(dead_code)] tasks: Vec>, - screen_size_prop: PropertyPtr, + screen_w: PropertyFloat32, + screen_h: PropertyFloat32, render_api: RenderApiPtr, } @@ -55,7 +56,8 @@ impl Window { let scene_graph = sg.lock().await; let node = scene_graph.get_node(node_id).unwrap(); let node_name = node.name.clone(); - let screen_size_prop = node.get_property("screen_size").unwrap(); + let screen_w = PropertyFloat32::wrap(node, Role::Internal, "screen_size", 0).unwrap(); + let screen_h = PropertyFloat32::wrap(node, Role::Internal, "screen_size", 1).unwrap(); let scale_prop = node.get_property("scale").unwrap(); drop(scene_graph); @@ -63,7 +65,8 @@ impl Window { // Start a task monitoring for window resize events // which updates screen_size let ev_sub = event_pub.subscribe_resize(); - let screen_size_prop2 = screen_size_prop.clone(); + let screen_w2 = screen_w.clone(); + let screen_h2 = screen_h.clone(); let me2 = me.clone(); let sg2 = sg.clone(); let resize_task = ex.spawn(async move { @@ -75,8 +78,8 @@ impl Window { debug!(target: "ui::win", "Window resized ({w}, {h})"); // Now update the properties - screen_size_prop2.set_f32(Role::Internal, 0, w).unwrap(); - screen_size_prop2.set_f32(Role::Internal, 1, h).unwrap(); + screen_w2.set(w); + screen_h2.set(h); let Some(self_) = me2.upgrade() else { // Should not happen @@ -153,7 +156,7 @@ impl Window { ]; tasks.append(&mut on_modify.tasks); - Self { node_id, sg, tasks, screen_size_prop, render_api } + Self { node_id, sg, tasks, screen_w, screen_h, render_api } }); Pimpl::Window(self_) @@ -333,7 +336,7 @@ impl Window { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); - if obj.handle_mouse_btn_down(&sg, btn.clone(), &mouse_pos).await { + if obj.handle_mouse_btn_down(&sg, btn.clone(), mouse_pos).await { return } } @@ -345,7 +348,7 @@ impl Window { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); - if obj.handle_mouse_btn_up(&sg, btn.clone(), &mouse_pos).await { + if obj.handle_mouse_btn_up(&sg, btn.clone(), mouse_pos).await { return } } @@ -357,7 +360,7 @@ impl Window { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); - if obj.handle_mouse_move(&sg, &mouse_pos).await { + if obj.handle_mouse_move(&sg, mouse_pos).await { return } } @@ -369,7 +372,7 @@ impl Window { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); - if obj.handle_mouse_wheel(&sg, &wheel_pos).await { + if obj.handle_mouse_wheel(&sg, wheel_pos).await { return } } @@ -381,21 +384,21 @@ impl Window { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); - if obj.handle_touch(&sg, phase, id, &touch_pos).await { + if obj.handle_touch(&sg, phase, id, touch_pos).await { return } } } pub async fn draw(&self, sg: &SceneGraph) { - let screen_width = self.screen_size_prop.get_f32(0).unwrap(); - let screen_height = self.screen_size_prop.get_f32(1).unwrap(); - debug!(target: "ui::win", "Window::draw({screen_width}, {screen_height})"); + let screen_w = self.screen_w.get(); + let screen_h = self.screen_h.get(); + debug!(target: "ui::win", "Window::draw({screen_w}, {screen_h})"); // SceneGraph should remain locked for the entire draw let self_node = sg.get_node(self.node_id).unwrap(); - let parent_rect = Rectangle::from_array([0., 0., screen_width, screen_height]); + let screen_rect = Rectangle::new(0., 0., screen_w, screen_h); let mut draw_calls = vec![]; let mut child_calls = vec![]; @@ -405,7 +408,7 @@ impl Window { for child_id in get_child_nodes_ordered(&sg, self.node_id) { let node = sg.get_node(child_id).unwrap(); let obj = get_ui_object(node); - let Some(mut draw_update) = obj.draw(sg, &parent_rect).await else { + let Some(mut draw_update) = obj.draw(sg, &screen_rect).await else { error!(target: "ui::layer", "draw() of {node:?} failed"); continue };