From 75fbb5fc14a36ca18d4a6fd66d7f432d50504f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 1 Nov 2023 03:47:47 +0100 Subject: [PATCH] Assign an `Id` to windows --- examples/widget-gallery/src/main.rs | 1 + src/id.rs | 7 ++++ src/window_handle.rs | 52 +++++++++++++++-------------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/examples/widget-gallery/src/main.rs b/examples/widget-gallery/src/main.rs index 27800c47..62e6e7de 100644 --- a/examples/widget-gallery/src/main.rs +++ b/examples/widget-gallery/src/main.rs @@ -144,6 +144,7 @@ fn app_view() -> impl View { ) }) .style(|s| s.size(100.pct(), 100.pct())) + .window_title(|| "Widget Gallery".to_owned()) } fn main() { diff --git a/src/id.rs b/src/id.rs index 2a78229a..de82d802 100644 --- a/src/id.rs +++ b/src/id.rs @@ -32,6 +32,13 @@ pub struct Id(u64); #[derive(Clone, Default, Debug)] pub struct IdPath(pub(crate) Vec); +impl IdPath { + /// Returns the slice of the ids excluding the first id identifying the window. + pub(crate) fn dispatch(&self) -> &[Id] { + &self.0[1..] + } +} + impl Id { /// Allocate a new, unique `Id`. pub fn next() -> Id { diff --git a/src/window_handle.rs b/src/window_handle.rs index da2eefb2..8f7d5613 100644 --- a/src/window_handle.rs +++ b/src/window_handle.rs @@ -45,6 +45,7 @@ use crate::{ /// - requesting a new animation frame from the backend pub(crate) struct WindowHandle { pub(crate) window: Option, + id: Id, /// Reactive Scope for this WindowHandle scope: Scope, view: Box, @@ -69,6 +70,7 @@ impl WindowHandle { ) -> Self { let scope = Scope::new(); let window_id = window.id(); + let id = Id::next(); let scale = window.scale_factor(); let size: LogicalSize = window.inner_size().to_logical(scale); let size = Size::new(size.width, size.height); @@ -76,6 +78,12 @@ impl WindowHandle { let theme = scope.create_rw_signal(window.theme()); let is_maximized = window.is_maximized(); + set_current_view(id); + + ID_PATHS.with(|id_paths| { + id_paths.borrow_mut().insert(id, IdPath(vec![id])); + }); + #[cfg(target_os = "linux")] let context_menu = scope.create_rw_signal(None); @@ -93,16 +101,13 @@ impl WindowHandle { ) }); - ID_PATHS.with(|id_paths| { - id_paths - .borrow_mut() - .insert(view.id(), IdPath(vec![view.id()])); - }); + view.id().set_parent(id); view_children_set_parent_id(&*view); let paint_state = PaintState::new(&window, scale, size.get_untracked() * scale); let mut window_handle = Self { window: Some(window), + id, scope, view, app_state: AppState::new(), @@ -123,7 +128,7 @@ impl WindowHandle { } pub fn event(&mut self, event: Event) { - set_current_view(self.view.id()); + set_current_view(self.id); let event = event.scale(self.app_state.scale); let mut cx = EventCx { @@ -210,7 +215,7 @@ impl WindowHandle { let id_path = ID_PATHS.with(|paths| paths.borrow().get(&id).cloned()); if let Some(id_path) = id_path { self.view - .event_main(&mut cx, Some(&id_path.0), event.clone()); + .event_main(&mut cx, Some(id_path.dispatch()), event.clone()); } if let Event::PointerUp(_) = &event { // To remove the styles applied by the Active selector @@ -246,8 +251,11 @@ impl WindowHandle { } else { let id_path = ID_PATHS.with(|paths| paths.borrow().get(id).cloned()); if let Some(id_path) = id_path { - self.view - .event_main(&mut cx, Some(&id_path.0), Event::PointerLeave); + self.view.event_main( + &mut cx, + Some(id_path.dispatch()), + Event::PointerLeave, + ); } } } @@ -349,7 +357,7 @@ impl WindowHandle { } pub(crate) fn pointer_leave(&mut self) { - set_current_view(self.view.id()); + set_current_view(self.id); let mut cx = EventCx { app_state: &mut self.app_state, }; @@ -365,7 +373,7 @@ impl WindowHandle { let id_path = ID_PATHS.with(|paths| paths.borrow().get(&id).cloned()); if let Some(id_path) = id_path { self.view - .event_main(&mut cx, Some(&id_path.0), Event::PointerLeave); + .event_main(&mut cx, Some(id_path.dispatch()), Event::PointerLeave); } } self.process_update(); @@ -553,11 +561,8 @@ impl WindowHandle { let mut flags = ChangeFlags::empty(); loop { self.process_central_messages(); - let msgs = UPDATE_MESSAGES.with(|msgs| { - msgs.borrow_mut() - .remove(&self.view.id()) - .unwrap_or_default() - }); + let msgs = + UPDATE_MESSAGES.with(|msgs| msgs.borrow_mut().remove(&self.id).unwrap_or_default()); if msgs.is_empty() { break; } @@ -609,7 +614,7 @@ impl WindowHandle { UpdateMessage::State { id, state } => { let id_path = ID_PATHS.with(|paths| paths.borrow().get(&id).cloned()); if let Some(id_path) = id_path { - flags |= self.view.update_main(&mut cx, &id_path.0, state); + flags |= self.view.update_main(&mut cx, id_path.dispatch(), state); } } UpdateMessage::BaseStyle { id, style } => { @@ -783,11 +788,8 @@ impl WindowHandle { fn process_deferred_update_messages(&mut self) -> ChangeFlags { self.process_central_messages(); let mut flags = ChangeFlags::empty(); - let msgs = DEFERRED_UPDATE_MESSAGES.with(|msgs| { - msgs.borrow_mut() - .remove(&self.view.id()) - .unwrap_or_default() - }); + let msgs = DEFERRED_UPDATE_MESSAGES + .with(|msgs| msgs.borrow_mut().remove(&self.id).unwrap_or_default()); if msgs.is_empty() { return flags; } @@ -798,7 +800,7 @@ impl WindowHandle { for (id, state) in msgs { let id_path = ID_PATHS.with(|paths| paths.borrow().get(&id).cloned()); if let Some(id_path) = id_path { - flags |= self.view.update_main(&mut cx, &id_path.0, state); + flags |= self.view.update_main(&mut cx, id_path.dispatch(), state); } } @@ -889,7 +891,7 @@ impl WindowHandle { fn has_deferred_update_messages(&self) -> bool { DEFERRED_UPDATE_MESSAGES.with(|m| { m.borrow() - .get(&self.view.id()) + .get(&self.id) .map(|m| !m.is_empty()) .unwrap_or(false) }) @@ -1001,7 +1003,7 @@ impl WindowHandle { } pub(crate) fn menu_action(&mut self, id: usize) { - set_current_view(self.view.id()); + set_current_view(self.id); if let Some(action) = self.app_state.window_menu.get(&id) { (*action)(); self.process_update();