mod.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use async_trait::async_trait;
  19. use miniquad::{KeyCode, KeyMods, MouseButton, TouchPhase};
  20. use std::sync::{Arc, Weak};
  21. use crate::{
  22. error::{Error, Result},
  23. expr::{SExprMachine, SExprVal},
  24. gfx::{GfxBufferId, GfxDrawCall, GfxTextureId, Point, Rectangle},
  25. prop::{PropertyPtr, Role},
  26. scene::{Pimpl, SceneNode as SceneNode3, SceneNodeId, SceneNodePtr},
  27. ExecutorPtr,
  28. };
  29. //mod button;
  30. //pub use button::{Button, ButtonPtr};
  31. //pub mod chatview;
  32. //pub use chatview::{ChatView, ChatViewPtr};
  33. //mod editbox;
  34. //pub use editbox::{EditBox, EditBoxPtr};
  35. mod image;
  36. pub use image::{Image, ImagePtr};
  37. pub mod vector_art;
  38. pub use vector_art::{
  39. shape::{ShapeVertex, VectorShape},
  40. VectorArt, VectorArtPtr,
  41. };
  42. mod layer;
  43. pub use layer::{Layer, LayerPtr};
  44. mod text;
  45. pub use text::{Text, TextPtr};
  46. mod win;
  47. pub use win::{Window, WindowPtr};
  48. #[async_trait]
  49. pub trait UIObject: Sync {
  50. fn z_index(&self) -> u32;
  51. async fn draw(&self, parent_rect: Rectangle) -> Option<DrawUpdate> {
  52. None
  53. }
  54. async fn handle_char(&self, key: char, mods: KeyMods, repeat: bool) -> bool {
  55. false
  56. }
  57. async fn handle_key_down(&self, key: KeyCode, mods: KeyMods, repeat: bool) -> bool {
  58. false
  59. }
  60. async fn handle_key_up(&self, key: KeyCode, mods: KeyMods) -> bool {
  61. false
  62. }
  63. async fn handle_mouse_btn_down(&self, btn: MouseButton, mouse_pos: Point) -> bool {
  64. false
  65. }
  66. async fn handle_mouse_btn_up(&self, btn: MouseButton, mouse_pos: Point) -> bool {
  67. false
  68. }
  69. async fn handle_mouse_move(&self, mouse_pos: Point) -> bool {
  70. false
  71. }
  72. async fn handle_mouse_wheel(&self, wheel_pos: Point) -> bool {
  73. false
  74. }
  75. async fn handle_touch(&self, phase: TouchPhase, id: u64, touch_pos: Point) -> bool {
  76. false
  77. }
  78. }
  79. pub struct DrawUpdate {
  80. pub key: u64,
  81. pub draw_calls: Vec<(u64, GfxDrawCall)>,
  82. pub freed_textures: Vec<GfxTextureId>,
  83. pub freed_buffers: Vec<GfxBufferId>,
  84. }
  85. pub struct OnModify<T> {
  86. ex: ExecutorPtr,
  87. node_name: String,
  88. node_id: SceneNodeId,
  89. me: Weak<T>,
  90. pub tasks: Vec<smol::Task<()>>,
  91. }
  92. impl<T: Send + Sync + 'static> OnModify<T> {
  93. pub fn new(ex: ExecutorPtr, node_name: String, node_id: SceneNodeId, me: Weak<T>) -> Self {
  94. Self { ex, node_name, node_id, me, tasks: vec![] }
  95. }
  96. pub fn when_change<F>(&mut self, prop: PropertyPtr, f: impl Fn(Arc<T>) -> F + Send + 'static)
  97. where
  98. F: std::future::Future<Output = ()> + Send + 'static,
  99. {
  100. let node_name = self.node_name.clone();
  101. let node_id = self.node_id;
  102. let on_modify_sub = prop.subscribe_modify();
  103. let prop_name = prop.name.clone();
  104. let me = self.me.clone();
  105. let task = self.ex.spawn(async move {
  106. loop {
  107. let Ok((role, _)) = on_modify_sub.receive().await else {
  108. error!(target: "app", "Property '{}':{}/'{}' on_modify pipe is broken", node_name, node_id, prop_name);
  109. return
  110. };
  111. if role == Role::Internal {
  112. continue
  113. }
  114. debug!(target: "app", "Property '{}':{}/'{}' modified", node_name, node_id, prop_name);
  115. let Some(self_) = me.upgrade() else {
  116. // Should not happen
  117. panic!(
  118. "'{}':{}/'{}' self destroyed before modify_task was stopped!",
  119. node_name, node_id, prop_name
  120. );
  121. };
  122. debug!(target: "app", "property modified");
  123. f(self_).await;
  124. }
  125. });
  126. self.tasks.push(task);
  127. }
  128. }
  129. pub fn get_ui_object3<'a>(node: &'a SceneNode3) -> &'a dyn UIObject {
  130. match &node.pimpl {
  131. Pimpl::Layer(obj) => obj.as_ref(),
  132. Pimpl::VectorArt(obj) => obj.as_ref(),
  133. Pimpl::Text(obj) => obj.as_ref(),
  134. //Pimpl::EditBox(editb) => editb.as_ref(),
  135. //Pimpl::ChatView(chat) => chat.as_ref(),
  136. Pimpl::Image(obj) => obj.as_ref(),
  137. //Pimpl::Button(btn) => btn.as_ref(),
  138. _ => panic!("unhandled type for get_ui_object"),
  139. }
  140. }
  141. pub fn get_children_ordered(node: &SceneNode3) -> Vec<SceneNodePtr> {
  142. let mut child_infs = vec![];
  143. for child in node.get_children() {
  144. let obj = get_ui_object3(&child);
  145. let z_index = obj.z_index();
  146. child_infs.push((child, z_index));
  147. }
  148. child_infs.sort_unstable_by_key(|(_, z_index)| *z_index);
  149. let nodes = child_infs.into_iter().rev().map(|(node, _)| node).collect();
  150. nodes
  151. }