mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
wallet: make Point copy and allow Point arithmetic.
This commit is contained in:
183
bin/darkwallet/src/gfx/linalg.rs
Normal file
183
bin/darkwallet/src/gfx/linalg.rs
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Self> {
|
||||
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<Point> 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<Point> 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 }
|
||||
}
|
||||
}
|
||||
@@ -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<Self> {
|
||||
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<RenderApi>;
|
||||
|
||||
pub struct RenderApi {
|
||||
|
||||
@@ -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<Vec<u8>>;
|
||||
|
||||
@@ -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<Self> {
|
||||
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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -124,7 +124,6 @@ impl UIObject for Layer {
|
||||
self.z_index.get()
|
||||
}
|
||||
|
||||
//#[async_recursion]
|
||||
async fn draw(&self, sg: &SceneGraph, parent_rect: &Rectangle) -> Option<DrawUpdate> {
|
||||
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();
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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<smol::Task<()>>,
|
||||
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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user