Refactor GoToLine to use cx.observe_new_views()
This commit is contained in:
parent
cbdd4aca89
commit
1b9f76c01d
11 changed files with 136 additions and 65 deletions
|
@ -18,8 +18,8 @@ use crate::{
|
|||
AppMetadata, AssetSource, BackgroundExecutor, ClipboardItem, Context, DispatchPhase, DisplayId,
|
||||
Entity, EventEmitter, FocusEvent, FocusHandle, FocusId, ForegroundExecutor, KeyBinding, Keymap,
|
||||
LayoutId, PathPromptOptions, Pixels, Platform, PlatformDisplay, Point, Render, SubscriberSet,
|
||||
Subscription, SvgRenderer, Task, TextStyle, TextStyleRefinement, TextSystem, View, Window,
|
||||
WindowContext, WindowHandle, WindowId,
|
||||
Subscription, SvgRenderer, Task, TextStyle, TextStyleRefinement, TextSystem, View, ViewContext,
|
||||
Window, WindowContext, WindowHandle, WindowId,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use collections::{HashMap, HashSet, VecDeque};
|
||||
|
@ -167,6 +167,7 @@ type Handler = Box<dyn FnMut(&mut AppContext) -> bool + 'static>;
|
|||
type Listener = Box<dyn FnMut(&dyn Any, &mut AppContext) -> bool + 'static>;
|
||||
type QuitHandler = Box<dyn FnOnce(&mut AppContext) -> LocalBoxFuture<'static, ()> + 'static>;
|
||||
type ReleaseListener = Box<dyn FnOnce(&mut dyn Any, &mut AppContext) + 'static>;
|
||||
type NewViewListener = Box<dyn FnMut(AnyView, &mut WindowContext) + 'static>;
|
||||
|
||||
// struct FrameConsumer {
|
||||
// next_frame_callbacks: Vec<FrameCallback>,
|
||||
|
@ -193,6 +194,7 @@ pub struct AppContext {
|
|||
pub(crate) text_style_stack: Vec<TextStyleRefinement>,
|
||||
pub(crate) globals_by_type: HashMap<TypeId, AnyBox>,
|
||||
pub(crate) entities: EntityMap,
|
||||
pub(crate) new_view_observers: SubscriberSet<TypeId, NewViewListener>,
|
||||
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
|
||||
pub(crate) keymap: Arc<Mutex<Keymap>>,
|
||||
pub(crate) global_action_listeners:
|
||||
|
@ -251,6 +253,7 @@ impl AppContext {
|
|||
text_style_stack: Vec::new(),
|
||||
globals_by_type: HashMap::default(),
|
||||
entities,
|
||||
new_view_observers: SubscriberSet::new(),
|
||||
windows: SlotMap::with_key(),
|
||||
keymap: Arc::new(Mutex::new(Keymap::default())),
|
||||
global_action_listeners: HashMap::default(),
|
||||
|
@ -599,6 +602,7 @@ impl AppContext {
|
|||
|
||||
fn apply_notify_effect(&mut self, emitter: EntityId) {
|
||||
self.pending_notifications.remove(&emitter);
|
||||
|
||||
self.observers
|
||||
.clone()
|
||||
.retain(&emitter, |handler| handler(self));
|
||||
|
@ -828,6 +832,23 @@ impl AppContext {
|
|||
self.globals_by_type.insert(global_type, lease.global);
|
||||
}
|
||||
|
||||
pub fn observe_new_views<V: 'static>(
|
||||
&mut self,
|
||||
on_new: impl 'static + Fn(&mut V, &mut ViewContext<V>),
|
||||
) -> Subscription {
|
||||
self.new_view_observers.insert(
|
||||
TypeId::of::<V>(),
|
||||
Box::new(move |any_view: AnyView, cx: &mut WindowContext| {
|
||||
any_view
|
||||
.downcast::<V>()
|
||||
.unwrap()
|
||||
.update(cx, |view_state, cx| {
|
||||
on_new(view_state, cx);
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn observe_release<E, T>(
|
||||
&mut self,
|
||||
handle: &E,
|
||||
|
|
|
@ -258,7 +258,7 @@ impl VisualContext for AsyncWindowContext {
|
|||
build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
|
||||
) -> Self::Result<View<V>>
|
||||
where
|
||||
V: 'static,
|
||||
V: 'static + Render,
|
||||
{
|
||||
self.window
|
||||
.update(self, |_, cx| cx.build_view(build_view_state))
|
||||
|
|
|
@ -112,7 +112,7 @@ pub trait VisualContext: Context {
|
|||
build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
|
||||
) -> Self::Result<View<V>>
|
||||
where
|
||||
V: 'static;
|
||||
V: 'static + Render;
|
||||
|
||||
fn update_view<V: 'static, R>(
|
||||
&mut self,
|
||||
|
|
|
@ -414,10 +414,14 @@ pub trait ElementInteractivity<V: 'static>: 'static {
|
|||
Box::new(move |_, key_down, context, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble {
|
||||
let key_down = key_down.downcast_ref::<KeyDownEvent>().unwrap();
|
||||
dbg!(key_down);
|
||||
if let KeyMatch::Some(action) =
|
||||
cx.match_keystroke(&global_id, &key_down.keystroke, context)
|
||||
{
|
||||
dbg!(&action);
|
||||
return Some(action);
|
||||
} else {
|
||||
dbg!("none");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1411,7 +1411,7 @@ impl VisualContext for WindowContext<'_> {
|
|||
build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
|
||||
) -> Self::Result<View<V>>
|
||||
where
|
||||
V: 'static,
|
||||
V: 'static + Render,
|
||||
{
|
||||
let slot = self.app.entities.reserve();
|
||||
let view = View {
|
||||
|
@ -1419,7 +1419,16 @@ impl VisualContext for WindowContext<'_> {
|
|||
};
|
||||
let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view);
|
||||
let entity = build_view_state(&mut cx);
|
||||
self.entities.insert(slot, entity);
|
||||
cx.entities.insert(slot, entity);
|
||||
|
||||
cx.new_view_observers
|
||||
.clone()
|
||||
.retain(&TypeId::of::<V>(), |observer| {
|
||||
let any_view = AnyView::from(view.clone());
|
||||
(observer)(any_view, self);
|
||||
true
|
||||
});
|
||||
|
||||
view
|
||||
}
|
||||
|
||||
|
@ -2102,7 +2111,7 @@ impl<V> Context for ViewContext<'_, V> {
|
|||
}
|
||||
|
||||
impl<V: 'static> VisualContext for ViewContext<'_, V> {
|
||||
fn build_view<W: 'static>(
|
||||
fn build_view<W: Render + 'static>(
|
||||
&mut self,
|
||||
build_view_state: impl FnOnce(&mut ViewContext<'_, W>) -> W,
|
||||
) -> Self::Result<View<W>> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue