Detailed changes
@@ -1007,6 +1007,22 @@ impl Context for AppContext {
let entity = self.entities.read(handle);
read(entity, self)
}
+
+ fn read_window<R>(
+ &self,
+ window: &AnyWindowHandle,
+ read: impl FnOnce(AnyView, &AppContext) -> R,
+ ) -> Result<R> {
+ let window = self
+ .windows
+ .get(window.id)
+ .ok_or_else(|| anyhow!("window not found"))?
+ .as_ref()
+ .unwrap();
+
+ let root_view = window.root_view.clone().unwrap();
+ Ok(read(root_view, self))
+ }
}
/// These effects are processed at the end of each application update cycle.
@@ -66,6 +66,16 @@ impl Context for AsyncAppContext {
let mut lock = app.borrow_mut();
lock.update_window(window, f)
}
+
+ fn read_window<R>(
+ &self,
+ window: &AnyWindowHandle,
+ read: impl FnOnce(AnyView, &AppContext) -> R,
+ ) -> Result<R> {
+ let app = self.app.upgrade().context("app was released")?;
+ let lock = app.borrow();
+ lock.read_window(window, read)
+ }
}
impl AsyncAppContext {
@@ -250,6 +260,14 @@ impl Context for AsyncWindowContext {
{
self.app.read_model(handle, read)
}
+
+ fn read_window<R>(
+ &self,
+ window: &AnyWindowHandle,
+ read: impl FnOnce(AnyView, &AppContext) -> R,
+ ) -> Result<R> {
+ self.app.read_window(window, read)
+ }
}
impl VisualContext for AsyncWindowContext {
@@ -239,6 +239,14 @@ impl<'a, T> Context for ModelContext<'a, T> {
{
self.app.read_model(handle, read)
}
+
+ fn read_window<R>(
+ &self,
+ window: &AnyWindowHandle,
+ read: impl FnOnce(AnyView, &AppContext) -> R,
+ ) -> Result<R> {
+ self.app.read_window(window, read)
+ }
}
impl<T> Borrow<AppContext> for ModelContext<'_, T> {
@@ -58,6 +58,15 @@ impl Context for TestAppContext {
let app = self.app.borrow();
app.read_model(handle, read)
}
+
+ fn read_window<R>(
+ &self,
+ window: &AnyWindowHandle,
+ read: impl FnOnce(AnyView, &AppContext) -> R,
+ ) -> Result<R> {
+ let app = self.app.borrow();
+ app.read_window(window, read)
+ }
}
impl TestAppContext {
@@ -146,6 +155,11 @@ impl TestAppContext {
Some(read(lock.try_global()?, &lock))
}
+ pub fn set_global<G: 'static, R>(&mut self, global: G) {
+ let mut lock = self.app.borrow_mut();
+ lock.set_global(global);
+ }
+
pub fn update_global<G: 'static, R>(
&mut self,
update: impl FnOnce(&mut G, &mut AppContext) -> R,
@@ -104,6 +104,12 @@ pub trait Context {
fn update_window<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Result<T>
where
F: FnOnce(AnyView, &mut WindowContext<'_>) -> T;
+
+ fn read_window<R>(
+ &self,
+ window: &AnyWindowHandle,
+ read: impl FnOnce(AnyView, &AppContext) -> R,
+ ) -> Result<R>;
}
pub trait VisualContext: Context {
@@ -45,7 +45,7 @@ impl<V: 'static> ElementInputHandler<V> {
/// containing view.
pub fn new(element_bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) -> Self {
ElementInputHandler {
- view: cx.view(),
+ view: cx.view().clone(),
element_bounds,
cx: cx.to_async(),
}
@@ -1428,6 +1428,19 @@ impl Context for WindowContext<'_> {
let entity = self.entities.read(handle);
read(&*entity, &*self.app)
}
+
+ fn read_window<R>(
+ &self,
+ window: &AnyWindowHandle,
+ read: impl FnOnce(AnyView, &AppContext) -> R,
+ ) -> Result<R> {
+ if window == &self.window.handle {
+ let root_view = self.window.root_view.clone().unwrap();
+ Ok(read(root_view, self))
+ } else {
+ window.read(self.app, read)
+ }
+ }
}
impl VisualContext for WindowContext<'_> {
@@ -1747,9 +1760,8 @@ impl<'a, V: 'static> ViewContext<'a, V> {
}
}
- // todo!("change this to return a reference");
- pub fn view(&self) -> View<V> {
- self.view.clone()
+ pub fn view(&self) -> &View<V> {
+ self.view
}
pub fn model(&self) -> Model<V> {
@@ -1772,7 +1784,7 @@ impl<'a, V: 'static> ViewContext<'a, V> {
where
V: 'static,
{
- let view = self.view();
+ let view = self.view().clone();
self.window_cx.on_next_frame(move |cx| view.update(cx, f));
}
@@ -2170,7 +2182,7 @@ impl<'a, V: 'static> ViewContext<'a, V> {
&mut self,
handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 'static,
) {
- let handle = self.view();
+ let handle = self.view().clone();
self.window_cx.on_mouse_event(move |event, phase, cx| {
handle.update(cx, |view, cx| {
handler(view, event, phase, cx);
@@ -2244,6 +2256,14 @@ impl<V> Context for ViewContext<'_, V> {
{
self.window_cx.read_model(handle, read)
}
+
+ fn read_window<R>(
+ &self,
+ window: &AnyWindowHandle,
+ read: impl FnOnce(AnyView, &AppContext) -> R,
+ ) -> Result<R> {
+ self.window_cx.read_window(window, read)
+ }
}
impl<V: 'static> VisualContext for ViewContext<'_, V> {
@@ -2315,6 +2335,14 @@ impl<V: 'static + Render> WindowHandle<V> {
}
}
+ pub fn root<C: Context>(&self, cx: &C) -> Result<View<V>> {
+ cx.read_window(&self.any_handle, |root_view, _| {
+ root_view
+ .downcast::<V>()
+ .map_err(|_| anyhow!("the type of the window's root view has changed"))
+ })?
+ }
+
pub fn update<C, R>(
self,
cx: &mut C,
@@ -2395,6 +2423,13 @@ impl AnyWindowHandle {
{
cx.update_window(self, update)
}
+
+ pub fn read<C, R>(self, cx: &C, read: impl FnOnce(AnyView, &AppContext) -> R) -> Result<R>
+ where
+ C: Context,
+ {
+ cx.read_window(&self, read)
+ }
}
#[cfg(any(test, feature = "test-support"))]