WIP
This commit is contained in:
parent
516236e044
commit
8e3314e680
9 changed files with 167 additions and 130 deletions
|
@ -3,12 +3,12 @@ use crate::{
|
|||
Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect,
|
||||
Element, EntityId, EventEmitter, ExternalPaths, FileDropEvent, FocusEvent, FontId,
|
||||
GlobalElementId, GlyphId, Handle, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch,
|
||||
KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, Modifiers, MonochromeSprite,
|
||||
MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas,
|
||||
PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams,
|
||||
RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription,
|
||||
TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle, WindowOptions,
|
||||
SUBPIXEL_VARIANTS,
|
||||
KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, ModelContext, Modifiers,
|
||||
MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels,
|
||||
PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams,
|
||||
RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
|
||||
Style, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, WeakHandle,
|
||||
WeakView, WindowOptions, SUBPIXEL_VARIANTS,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use collections::HashMap;
|
||||
|
@ -281,7 +281,7 @@ impl ContentMask<Pixels> {
|
|||
}
|
||||
|
||||
pub struct WindowContext<'a, 'w> {
|
||||
app: Reference<'a, AppContext>,
|
||||
pub(crate) app: Reference<'a, AppContext>,
|
||||
pub(crate) window: Reference<'w, Window>,
|
||||
}
|
||||
|
||||
|
@ -800,43 +800,46 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
|||
|
||||
pub(crate) fn draw(&mut self) {
|
||||
let unit_entity = self.unit_entity.clone();
|
||||
self.update_entity(&unit_entity, |view, cx| {
|
||||
cx.start_frame();
|
||||
let mut root_view = self.window.root_view.take().unwrap();
|
||||
let mut root_view_cx = ViewContext::mutable(
|
||||
&mut self.app,
|
||||
&mut self.window,
|
||||
self.unit_entity.downgrade(),
|
||||
);
|
||||
|
||||
let mut root_view = cx.window.root_view.take().unwrap();
|
||||
root_view_cx.start_frame();
|
||||
|
||||
cx.stack(0, |cx| {
|
||||
let available_space = cx.window.content_size.map(Into::into);
|
||||
draw_any_view(&mut root_view, available_space, cx);
|
||||
});
|
||||
|
||||
if let Some(mut active_drag) = cx.active_drag.take() {
|
||||
cx.stack(1, |cx| {
|
||||
let offset = cx.mouse_position() - active_drag.cursor_offset;
|
||||
cx.with_element_offset(Some(offset), |cx| {
|
||||
let available_space =
|
||||
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
|
||||
if let Some(drag_handle_view) = &mut active_drag.drag_handle_view {
|
||||
draw_any_view(drag_handle_view, available_space, cx);
|
||||
}
|
||||
cx.active_drag = Some(active_drag);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
cx.window.root_view = Some(root_view);
|
||||
let scene = cx.window.scene_builder.build();
|
||||
|
||||
cx.run_on_main(view, |_, cx| {
|
||||
cx.window
|
||||
.platform_window
|
||||
.borrow_on_main_thread()
|
||||
.draw(scene);
|
||||
cx.window.dirty = false;
|
||||
})
|
||||
.detach();
|
||||
root_view_cx.stack(0, |cx| {
|
||||
let available_space = cx.window.content_size.map(Into::into);
|
||||
draw_any_view(&mut root_view, available_space, cx);
|
||||
});
|
||||
|
||||
if let Some(mut active_drag) = self.app.active_drag.take() {
|
||||
root_view_cx.stack(1, |cx| {
|
||||
let offset = cx.mouse_position() - active_drag.cursor_offset;
|
||||
cx.with_element_offset(Some(offset), |cx| {
|
||||
let available_space =
|
||||
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
|
||||
if let Some(drag_handle_view) = &mut active_drag.drag_handle_view {
|
||||
draw_any_view(drag_handle_view, available_space, cx);
|
||||
}
|
||||
cx.active_drag = Some(active_drag);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
self.window.root_view = Some(root_view);
|
||||
let scene = self.window.scene_builder.build();
|
||||
|
||||
self.run_on_main(|cx| {
|
||||
cx.window
|
||||
.platform_window
|
||||
.borrow_on_main_thread()
|
||||
.draw(scene);
|
||||
cx.window.dirty = false;
|
||||
})
|
||||
.detach();
|
||||
|
||||
fn draw_any_view(
|
||||
view: &mut AnyView,
|
||||
available_space: Size<AvailableSpace>,
|
||||
|
@ -1169,34 +1172,30 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
|||
}
|
||||
|
||||
impl Context for WindowContext<'_, '_> {
|
||||
type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
|
||||
type EntityContext<'a, T> = ModelContext<'a, T>;
|
||||
type Result<T> = T;
|
||||
|
||||
fn entity<T>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
|
||||
) -> Handle<T>
|
||||
where
|
||||
T: 'static + Send,
|
||||
{
|
||||
let slot = self.app.entities.reserve();
|
||||
let entity = build_entity(&mut ViewContext::mutable(
|
||||
&mut *self.app,
|
||||
&mut self.window,
|
||||
slot.downgrade(),
|
||||
));
|
||||
let entity = build_entity(&mut ModelContext::mutable(&mut *self.app, slot.downgrade()));
|
||||
self.entities.insert(slot, entity)
|
||||
}
|
||||
|
||||
fn update_entity<T: 'static, R>(
|
||||
&mut self,
|
||||
handle: &Handle<T>,
|
||||
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
|
||||
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
|
||||
) -> R {
|
||||
let mut entity = self.entities.lease(handle);
|
||||
let result = update(
|
||||
&mut *entity,
|
||||
&mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.downgrade()),
|
||||
&mut ModelContext::mutable(&mut *self.app, handle.downgrade()),
|
||||
);
|
||||
self.entities.end_lease(entity);
|
||||
result
|
||||
|
@ -1389,7 +1388,7 @@ impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
|
|||
|
||||
pub struct ViewContext<'a, 'w, V> {
|
||||
window_cx: WindowContext<'a, 'w>,
|
||||
view_state: WeakHandle<V>,
|
||||
view: View<V>,
|
||||
}
|
||||
|
||||
impl<V> Borrow<AppContext> for ViewContext<'_, '_, V> {
|
||||
|
@ -1417,15 +1416,19 @@ impl<V> BorrowMut<Window> for ViewContext<'_, '_, V> {
|
|||
}
|
||||
|
||||
impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
||||
fn mutable(app: &'a mut AppContext, window: &'w mut Window, view_state: WeakHandle<V>) -> Self {
|
||||
pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window, view: View<V>) -> Self {
|
||||
Self {
|
||||
window_cx: WindowContext::mutable(app, window),
|
||||
view_state,
|
||||
view,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view(&self) -> WeakView<V> {
|
||||
self.view.downgrade()
|
||||
}
|
||||
|
||||
pub fn handle(&self) -> WeakHandle<V> {
|
||||
self.view_state.clone()
|
||||
self.view.state.downgrade()
|
||||
}
|
||||
|
||||
pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||
|
@ -1439,10 +1442,8 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
where
|
||||
V: Any + Send,
|
||||
{
|
||||
let entity = self.handle();
|
||||
self.window_cx.on_next_frame(move |cx| {
|
||||
entity.update(cx, f).ok();
|
||||
});
|
||||
let view = self.view();
|
||||
self.window_cx.on_next_frame(move |cx| view.update(cx, f));
|
||||
}
|
||||
|
||||
pub fn observe<E>(
|
||||
|
@ -1454,7 +1455,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
E: 'static,
|
||||
V: Any + Send,
|
||||
{
|
||||
let this = self.handle();
|
||||
let view = self.view();
|
||||
let handle = handle.downgrade();
|
||||
let window_handle = self.window.handle;
|
||||
self.app.observers.insert(
|
||||
|
@ -1462,7 +1463,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
Box::new(move |cx| {
|
||||
cx.update_window(window_handle.id, |cx| {
|
||||
if let Some(handle) = handle.upgrade() {
|
||||
this.update(cx, |this, cx| on_notify(this, handle, cx))
|
||||
view.update(cx, |this, cx| on_notify(this, handle, cx))
|
||||
.is_ok()
|
||||
} else {
|
||||
false
|
||||
|
@ -1480,7 +1481,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
+ Send
|
||||
+ 'static,
|
||||
) -> Subscription {
|
||||
let this = self.handle();
|
||||
let this = self.view();
|
||||
let handle = handle.downgrade();
|
||||
let window_handle = self.window.handle;
|
||||
self.app.event_listeners.insert(
|
||||
|
@ -1490,7 +1491,6 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
if let Some(handle) = handle.upgrade() {
|
||||
let event = event.downcast_ref().expect("invalid event type");
|
||||
this.update(cx, |this, cx| on_event(this, handle, event, cx))
|
||||
.is_ok()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -1506,7 +1506,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
) -> Subscription {
|
||||
let window_handle = self.window.handle;
|
||||
self.app.release_listeners.insert(
|
||||
self.view_state.entity_id,
|
||||
self.view.entity_id,
|
||||
Box::new(move |this, cx| {
|
||||
let this = this.downcast_mut().expect("invalid entity type");
|
||||
// todo!("are we okay with silently swallowing the error?")
|
||||
|
@ -1523,7 +1523,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
where
|
||||
V: Any + Send,
|
||||
{
|
||||
let this = self.handle();
|
||||
let this = self.view();
|
||||
let window_handle = self.window.handle;
|
||||
self.app.release_listeners.insert(
|
||||
handle.entity_id,
|
||||
|
@ -1540,7 +1540,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
pub fn notify(&mut self) {
|
||||
self.window_cx.notify();
|
||||
self.window_cx.app.push_effect(Effect::Notify {
|
||||
emitter: self.view_state.entity_id,
|
||||
emitter: self.view.entity_id,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1548,7 +1548,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
&mut self,
|
||||
listener: impl Fn(&mut V, &FocusEvent, &mut ViewContext<V>) + Send + 'static,
|
||||
) {
|
||||
let handle = self.handle();
|
||||
let handle = self.view();
|
||||
self.window.focus_listeners.push(Box::new(move |event, cx| {
|
||||
handle
|
||||
.update(cx, |view, cx| listener(view, event, cx))
|
||||
|
@ -1564,7 +1564,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
let old_stack_len = self.window.key_dispatch_stack.len();
|
||||
if !self.window.freeze_key_dispatch_stack {
|
||||
for (event_type, listener) in key_listeners {
|
||||
let handle = self.handle();
|
||||
let handle = self.view();
|
||||
let listener = Box::new(
|
||||
move |event: &dyn Any,
|
||||
context_stack: &[&DispatchContext],
|
||||
|
@ -1654,7 +1654,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread<Self>>(self) };
|
||||
Task::ready(Ok(f(view, cx)))
|
||||
} else {
|
||||
let handle = self.handle().upgrade().unwrap();
|
||||
let handle = self.view().upgrade().unwrap();
|
||||
self.window_cx.run_on_main(move |cx| handle.update(cx, f))
|
||||
}
|
||||
}
|
||||
|
@ -1667,7 +1667,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
R: Send + 'static,
|
||||
Fut: Future<Output = R> + Send + 'static,
|
||||
{
|
||||
let handle = self.handle();
|
||||
let handle = self.view();
|
||||
self.window_cx.spawn(move |_, cx| {
|
||||
let result = f(handle, cx);
|
||||
async move { result.await }
|
||||
|
@ -1689,7 +1689,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
f: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) + Send + 'static,
|
||||
) -> Subscription {
|
||||
let window_id = self.window.handle.id;
|
||||
let handle = self.handle();
|
||||
let handle = self.view();
|
||||
self.global_observers.insert(
|
||||
TypeId::of::<G>(),
|
||||
Box::new(move |cx| {
|
||||
|
@ -1705,7 +1705,7 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
|
|||
&mut self,
|
||||
handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + Send + 'static,
|
||||
) {
|
||||
let handle = self.handle().upgrade().unwrap();
|
||||
let handle = self.view().upgrade().unwrap();
|
||||
self.window_cx.on_mouse_event(move |event, phase, cx| {
|
||||
handle.update(cx, |view, cx| {
|
||||
handler(view, event, phase, cx);
|
||||
|
@ -1720,7 +1720,7 @@ where
|
|||
V::Event: Any + Send,
|
||||
{
|
||||
pub fn emit(&mut self, event: V::Event) {
|
||||
let emitter = self.view_state.entity_id;
|
||||
let emitter = self.view.entity_id;
|
||||
self.app.push_effect(Effect::Emit {
|
||||
emitter,
|
||||
event: Box::new(event),
|
||||
|
@ -1729,12 +1729,12 @@ where
|
|||
}
|
||||
|
||||
impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
|
||||
type EntityContext<'b, 'c, U> = ViewContext<'b, 'c, U>;
|
||||
type EntityContext<'b, U> = ModelContext<'b, U>;
|
||||
type Result<U> = U;
|
||||
|
||||
fn entity<T>(
|
||||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
|
||||
) -> Handle<T>
|
||||
where
|
||||
T: 'static + Send,
|
||||
|
@ -1745,7 +1745,7 @@ impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
|
|||
fn update_entity<T: 'static, R>(
|
||||
&mut self,
|
||||
handle: &Handle<T>,
|
||||
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
|
||||
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
|
||||
) -> R {
|
||||
self.window_cx.update_entity(handle, update)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue