WIP
This commit is contained in:
+26
-22
@@ -936,6 +936,16 @@ impl AppContext {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn read_window<T, F: FnOnce(&WindowContext) -> T>(
|
||||
&self,
|
||||
window_id: usize,
|
||||
callback: F,
|
||||
) -> Option<T> {
|
||||
let window = self.windows.get(&window_id)?;
|
||||
let window_context = WindowContext::immutable(self, &window, window_id);
|
||||
Some(callback(&window_context))
|
||||
}
|
||||
|
||||
pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
|
||||
&mut self,
|
||||
window_id: usize,
|
||||
@@ -943,13 +953,7 @@ impl AppContext {
|
||||
) -> Option<T> {
|
||||
self.update(|app_context| {
|
||||
let mut window = app_context.windows.remove(&window_id)?;
|
||||
let mut window_context = WindowContext {
|
||||
app_context,
|
||||
window: &mut window,
|
||||
window_id,
|
||||
refreshing: false,
|
||||
};
|
||||
|
||||
let mut window_context = WindowContext::mutable(app_context, &mut window, window_id);
|
||||
let result = callback(&mut window_context);
|
||||
app_context.windows.insert(window_id, window);
|
||||
Some(result)
|
||||
@@ -1651,7 +1655,7 @@ impl AppContext {
|
||||
}));
|
||||
|
||||
let mut window = Window::new(window_id, platform_window, self, build_root_view);
|
||||
let scene = WindowContext::new(self, &mut window, window_id).build_scene();
|
||||
let scene = WindowContext::mutable(self, &mut window, window_id).build_scene();
|
||||
window.platform_window.present_scene(scene);
|
||||
window
|
||||
}
|
||||
@@ -3244,7 +3248,7 @@ impl<M> DerefMut for ModelContext<'_, M> {
|
||||
}
|
||||
|
||||
pub struct ViewContext<'a, 'b, 'c, T: ?Sized> {
|
||||
window_context: WindowContextRef<'a, 'b, 'c>,
|
||||
window_context: Reference<'c, WindowContext<'a, 'b>>,
|
||||
view_id: usize,
|
||||
view_type: PhantomData<T>,
|
||||
}
|
||||
@@ -3266,7 +3270,7 @@ impl<T: View> DerefMut for ViewContext<'_, '_, '_, T> {
|
||||
impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
|
||||
pub(crate) fn mutable(window_context: &'c mut WindowContext<'a, 'b>, view_id: usize) -> Self {
|
||||
Self {
|
||||
window_context: WindowContextRef::Mutable(window_context),
|
||||
window_context: Reference::Mutable(window_context),
|
||||
view_id,
|
||||
view_type: PhantomData,
|
||||
}
|
||||
@@ -3274,7 +3278,7 @@ impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
|
||||
|
||||
pub(crate) fn immutable(window_context: &'c WindowContext<'a, 'b>, view_id: usize) -> Self {
|
||||
Self {
|
||||
window_context: WindowContextRef::Immutable(window_context),
|
||||
window_context: Reference::Immutable(window_context),
|
||||
view_id,
|
||||
view_type: PhantomData,
|
||||
}
|
||||
@@ -3819,29 +3823,29 @@ impl<V: View> UpdateView for ViewContext<'_, '_, '_, V> {
|
||||
}
|
||||
}
|
||||
|
||||
enum WindowContextRef<'a, 'b, 'c> {
|
||||
Immutable(&'c WindowContext<'a, 'b>),
|
||||
Mutable(&'c mut WindowContext<'a, 'b>),
|
||||
pub(crate) enum Reference<'a, T> {
|
||||
Immutable(&'a T),
|
||||
Mutable(&'a mut T),
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c> Deref for WindowContextRef<'a, 'b, 'c> {
|
||||
type Target = WindowContext<'a, 'b>;
|
||||
impl<'a, T> Deref for Reference<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
WindowContextRef::Immutable(window_context) => window_context,
|
||||
WindowContextRef::Mutable(window_context) => window_context,
|
||||
Reference::Immutable(target) => target,
|
||||
Reference::Mutable(target) => target,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c> DerefMut for WindowContextRef<'a, 'b, 'c> {
|
||||
impl<'a, T> DerefMut for Reference<'a, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
match self {
|
||||
WindowContextRef::Immutable(_) => {
|
||||
panic!("cannot mutably deref an immutable WindowContext. this is a bug in GPUI.");
|
||||
Reference::Immutable(_) => {
|
||||
panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
|
||||
}
|
||||
WindowContextRef::Mutable(window_context) => window_context,
|
||||
Reference::Mutable(target) => target,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::{
|
||||
platform::{Event, InputHandler, KeyDownEvent, Platform},
|
||||
Action, AnyViewHandle, AppContext, Entity, FontCache, Handle, ModelContext, ModelHandle,
|
||||
ReadModelWith, ReadViewWith, Task, UpdateModel, UpdateView, View, ViewContext, ViewHandle,
|
||||
WeakHandle,
|
||||
WeakHandle, WindowContext,
|
||||
};
|
||||
use collections::BTreeMap;
|
||||
|
||||
@@ -114,6 +114,22 @@ impl TestAppContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_window<T, F: FnOnce(&WindowContext) -> T>(
|
||||
&self,
|
||||
window_id: usize,
|
||||
callback: F,
|
||||
) -> Option<T> {
|
||||
self.cx.borrow().read_window(window_id, callback)
|
||||
}
|
||||
|
||||
pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
|
||||
&mut self,
|
||||
window_id: usize,
|
||||
callback: F,
|
||||
) -> Option<T> {
|
||||
self.cx.borrow_mut().update_window(window_id, callback)
|
||||
}
|
||||
|
||||
pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
|
||||
where
|
||||
T: Entity,
|
||||
@@ -147,17 +163,6 @@ impl TestAppContext {
|
||||
self.cx.borrow().window_ids().collect()
|
||||
}
|
||||
|
||||
pub fn root_view(&self, window_id: usize) -> Option<AnyViewHandle> {
|
||||
Some(
|
||||
self.cx
|
||||
.borrow()
|
||||
.windows
|
||||
.get(&window_id)?
|
||||
.root_view()
|
||||
.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
|
||||
callback(&*self.cx.borrow())
|
||||
}
|
||||
@@ -173,28 +178,6 @@ impl TestAppContext {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn render<F, V, T>(&mut self, handle: &ViewHandle<V>, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut V, &mut ViewContext<V>) -> T,
|
||||
V: View,
|
||||
{
|
||||
todo!()
|
||||
// handle.update(&mut *self.cx.borrow_mut(), |view, cx| {
|
||||
// let mut render_cx = ViewContext {
|
||||
// app: cx,
|
||||
// window_id: handle.window_id(),
|
||||
// view_id: handle.id(),
|
||||
// view_type: PhantomData,
|
||||
// titlebar_height: 0.,
|
||||
// hovered_region_ids: Default::default(),
|
||||
// clicked_region_ids: None,
|
||||
// refreshing: false,
|
||||
// appearance: Appearance::Light,
|
||||
// };
|
||||
// f(view, &mut render_cx)
|
||||
// })
|
||||
}
|
||||
|
||||
pub fn to_async(&self) -> AsyncAppContext {
|
||||
AsyncAppContext(self.cx.clone())
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ use sqlez::{
|
||||
use std::ops::{Deref, DerefMut, Range};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::Reference;
|
||||
|
||||
pub struct Window {
|
||||
pub(crate) root_view: Option<AnyViewHandle>,
|
||||
pub(crate) focused_view_id: Option<usize>,
|
||||
@@ -83,7 +85,7 @@ impl Window {
|
||||
appearance,
|
||||
};
|
||||
|
||||
let mut window_context = WindowContext::new(cx, &mut window, window_id);
|
||||
let mut window_context = WindowContext::mutable(cx, &mut window, window_id);
|
||||
let root_view = window_context
|
||||
.build_and_insert_view(ParentId::Root, |cx| Some(build_view(cx)))
|
||||
.unwrap();
|
||||
@@ -101,8 +103,8 @@ impl Window {
|
||||
}
|
||||
|
||||
pub struct WindowContext<'a: 'b, 'b> {
|
||||
pub(crate) app_context: &'a mut AppContext,
|
||||
pub(crate) window: &'b mut Window, // TODO: make this private?
|
||||
pub(crate) app_context: Reference<'a, AppContext>,
|
||||
pub(crate) window: Reference<'b, Window>,
|
||||
pub(crate) window_id: usize,
|
||||
pub(crate) refreshing: bool,
|
||||
}
|
||||
@@ -111,7 +113,7 @@ impl Deref for WindowContext<'_, '_> {
|
||||
type Target = AppContext;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.app_context
|
||||
&self.app_context
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,10 +150,23 @@ impl UpgradeViewHandle for WindowContext<'_, '_> {
|
||||
}
|
||||
|
||||
impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
||||
pub fn new(app_context: &'a mut AppContext, window: &'b mut Window, window_id: usize) -> Self {
|
||||
pub fn mutable(
|
||||
app_context: &'a mut AppContext,
|
||||
window: &'b mut Window,
|
||||
window_id: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
app_context,
|
||||
window,
|
||||
app_context: Reference::Mutable(app_context),
|
||||
window: Reference::Mutable(window),
|
||||
window_id,
|
||||
refreshing: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn immutable(app_context: &'a AppContext, window: &'b Window, window_id: usize) -> Self {
|
||||
Self {
|
||||
app_context: Reference::Immutable(app_context),
|
||||
window: Reference::Immutable(window),
|
||||
window_id,
|
||||
refreshing: false,
|
||||
}
|
||||
@@ -162,7 +177,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
||||
}
|
||||
|
||||
pub fn app_context(&mut self) -> &mut AppContext {
|
||||
self.app_context
|
||||
&mut self.app_context
|
||||
}
|
||||
|
||||
pub fn root_view(&self) -> &AnyViewHandle {
|
||||
@@ -406,7 +421,8 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
||||
MouseEvent::Hover(_) => {
|
||||
let mut highest_z_index = None;
|
||||
let mouse_position = self.window.mouse_position.clone();
|
||||
for (region, z_index) in self.window.mouse_regions.iter().rev() {
|
||||
let window = &mut *self.window;
|
||||
for (region, z_index) in window.mouse_regions.iter().rev() {
|
||||
// Allow mouse regions to appear transparent to hovers
|
||||
if !region.hoverable {
|
||||
continue;
|
||||
@@ -424,7 +440,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
||||
// highest_z_index is set.
|
||||
if contains_mouse && z_index == highest_z_index.unwrap() {
|
||||
//Ensure that hover entrance events aren't sent twice
|
||||
if self.window.hovered_region_ids.insert(region.id()) {
|
||||
if window.hovered_region_ids.insert(region.id()) {
|
||||
valid_regions.push(region.clone());
|
||||
if region.notify_on_hover {
|
||||
notified_views.insert(region.id().view_id());
|
||||
@@ -432,7 +448,7 @@ impl<'a: 'b, 'b> WindowContext<'a, 'b> {
|
||||
}
|
||||
} else {
|
||||
// Ensure that hover exit events aren't sent twice
|
||||
if self.window.hovered_region_ids.remove(®ion.id()) {
|
||||
if window.hovered_region_ids.remove(®ion.id()) {
|
||||
valid_regions.push(region.clone());
|
||||
if region.notify_on_hover {
|
||||
notified_views.insert(region.id().view_id());
|
||||
|
||||
Reference in New Issue
Block a user