WIP
This commit is contained in:
parent
b695c42e11
commit
300ce61bd0
4 changed files with 47 additions and 38 deletions
|
@ -498,8 +498,8 @@ pub struct AppContext {
|
||||||
// Action Types -> Action Handlers
|
// Action Types -> Action Handlers
|
||||||
global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
|
global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
|
||||||
keystroke_matcher: KeymapMatcher,
|
keystroke_matcher: KeymapMatcher,
|
||||||
next_entity_id: usize,
|
next_id: usize,
|
||||||
next_window_id: usize,
|
// next_window_id: usize,
|
||||||
next_subscription_id: usize,
|
next_subscription_id: usize,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
|
|
||||||
|
@ -558,8 +558,7 @@ impl AppContext {
|
||||||
actions: Default::default(),
|
actions: Default::default(),
|
||||||
global_actions: Default::default(),
|
global_actions: Default::default(),
|
||||||
keystroke_matcher: KeymapMatcher::default(),
|
keystroke_matcher: KeymapMatcher::default(),
|
||||||
next_entity_id: 0,
|
next_id: 0,
|
||||||
next_window_id: 0,
|
|
||||||
next_subscription_id: 0,
|
next_subscription_id: 0,
|
||||||
frame_count: 0,
|
frame_count: 0,
|
||||||
subscriptions: Default::default(),
|
subscriptions: Default::default(),
|
||||||
|
@ -1230,7 +1229,7 @@ impl AppContext {
|
||||||
F: FnOnce(&mut ModelContext<T>) -> T,
|
F: FnOnce(&mut ModelContext<T>) -> T,
|
||||||
{
|
{
|
||||||
self.update(|this| {
|
self.update(|this| {
|
||||||
let model_id = post_inc(&mut this.next_entity_id);
|
let model_id = post_inc(&mut this.next_id);
|
||||||
let handle = ModelHandle::new(model_id, &this.ref_counts);
|
let handle = ModelHandle::new(model_id, &this.ref_counts);
|
||||||
let mut cx = ModelContext::new(this, model_id);
|
let mut cx = ModelContext::new(this, model_id);
|
||||||
let model = build_model(&mut cx);
|
let model = build_model(&mut cx);
|
||||||
|
@ -1310,7 +1309,7 @@ impl AppContext {
|
||||||
F: FnOnce(&mut ViewContext<V>) -> V,
|
F: FnOnce(&mut ViewContext<V>) -> V,
|
||||||
{
|
{
|
||||||
self.update(|this| {
|
self.update(|this| {
|
||||||
let window_id = post_inc(&mut this.next_window_id);
|
let window_id = post_inc(&mut this.next_id);
|
||||||
let platform_window =
|
let platform_window =
|
||||||
this.platform
|
this.platform
|
||||||
.open_window(window_id, window_options, this.foreground.clone());
|
.open_window(window_id, window_options, this.foreground.clone());
|
||||||
|
@ -1326,7 +1325,7 @@ impl AppContext {
|
||||||
F: FnOnce(&mut ViewContext<V>) -> V,
|
F: FnOnce(&mut ViewContext<V>) -> V,
|
||||||
{
|
{
|
||||||
self.update(|this| {
|
self.update(|this| {
|
||||||
let window_id = post_inc(&mut this.next_window_id);
|
let window_id = post_inc(&mut this.next_id);
|
||||||
let platform_window = this.platform.add_status_item(window_id);
|
let platform_window = this.platform.add_status_item(window_id);
|
||||||
let window = this.build_window(window_id, platform_window, build_root_view);
|
let window = this.build_window(window_id, platform_window, build_root_view);
|
||||||
let root_view = window.root_view().clone().downcast::<V>().unwrap();
|
let root_view = window.root_view().clone().downcast::<V>().unwrap();
|
||||||
|
@ -3810,6 +3809,7 @@ pub struct WindowHandle<T> {
|
||||||
view_type: PhantomData<T>,
|
view_type: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
impl<V: View> WindowHandle<V> {
|
impl<V: View> WindowHandle<V> {
|
||||||
fn id(&self) -> usize {
|
fn id(&self) -> usize {
|
||||||
self.any_handle.id()
|
self.any_handle.id()
|
||||||
|
@ -3922,6 +3922,17 @@ impl AnyWindowHandle {
|
||||||
pub fn id(&self) -> usize {
|
pub fn id(&self) -> usize {
|
||||||
self.window_id
|
self.window_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn downcast<V: View>(self) -> Option<WindowHandle<V>> {
|
||||||
|
if TypeId::of::<V>() == self.root_view_type {
|
||||||
|
Some(WindowHandle {
|
||||||
|
any_handle: self,
|
||||||
|
view_type: PhantomData,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for AnyWindowHandle {
|
impl Drop for AnyWindowHandle {
|
||||||
|
@ -5613,20 +5624,18 @@ mod tests {
|
||||||
child: None,
|
child: None,
|
||||||
});
|
});
|
||||||
let view_1 = window.root(cx);
|
let view_1 = window.root(cx);
|
||||||
let view_2 = window
|
let view_2 = window.update(cx, |cx| {
|
||||||
.update(cx, |cx| {
|
let view_2 = cx.add_view(|_| View {
|
||||||
let view_2 = cx.add_view(|_| View {
|
events: view_events.clone(),
|
||||||
events: view_events.clone(),
|
name: "view 2".to_string(),
|
||||||
name: "view 2".to_string(),
|
child: None,
|
||||||
child: None,
|
});
|
||||||
});
|
view_1.update(cx, |view_1, cx| {
|
||||||
view_1.update(cx, |view_1, cx| {
|
view_1.child = Some(view_2.clone().into_any());
|
||||||
view_1.child = Some(view_2.clone().into_any());
|
cx.notify();
|
||||||
cx.notify();
|
});
|
||||||
});
|
view_2
|
||||||
view_2
|
});
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
|
let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
|
||||||
view_1.update(cx, |_, cx| {
|
view_1.update(cx, |_, cx| {
|
||||||
|
@ -6071,26 +6080,26 @@ mod tests {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.update_window(window_id, |cx| {
|
window.update(cx, |cx| {
|
||||||
cx.dispatch_keystroke(&Keystroke::parse("a").unwrap())
|
cx.dispatch_keystroke(&Keystroke::parse("a").unwrap())
|
||||||
});
|
});
|
||||||
assert_eq!(&*actions.borrow(), &["2 a"]);
|
assert_eq!(&*actions.borrow(), &["2 a"]);
|
||||||
actions.borrow_mut().clear();
|
actions.borrow_mut().clear();
|
||||||
|
|
||||||
cx.update_window(window_id, |cx| {
|
window.update(cx, |cx| {
|
||||||
cx.dispatch_keystroke(&Keystroke::parse("b").unwrap());
|
cx.dispatch_keystroke(&Keystroke::parse("b").unwrap());
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
|
assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
|
||||||
actions.borrow_mut().clear();
|
actions.borrow_mut().clear();
|
||||||
|
|
||||||
cx.update_window(window_id, |cx| {
|
window.update(cx, |cx| {
|
||||||
cx.dispatch_keystroke(&Keystroke::parse("c").unwrap());
|
cx.dispatch_keystroke(&Keystroke::parse("c").unwrap());
|
||||||
});
|
});
|
||||||
assert_eq!(&*actions.borrow(), &["3 c"]);
|
assert_eq!(&*actions.borrow(), &["3 c"]);
|
||||||
actions.borrow_mut().clear();
|
actions.borrow_mut().clear();
|
||||||
|
|
||||||
cx.update_window(window_id, |cx| {
|
window.update(cx, |cx| {
|
||||||
cx.dispatch_keystroke(&Keystroke::parse("d").unwrap());
|
cx.dispatch_keystroke(&Keystroke::parse("d").unwrap());
|
||||||
});
|
});
|
||||||
assert_eq!(&*actions.borrow(), &["2 d"]);
|
assert_eq!(&*actions.borrow(), &["2 d"]);
|
||||||
|
@ -6201,7 +6210,7 @@ mod tests {
|
||||||
|
|
||||||
// Check that global actions do not have a binding, even if a binding does exist in another view
|
// Check that global actions do not have a binding, even if a binding does exist in another view
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&available_actions(window_id, view_1.id(), cx),
|
&available_actions(window.id(), view_1.id(), cx),
|
||||||
&[
|
&[
|
||||||
("test::Action1", vec![Keystroke::parse("a").unwrap()]),
|
("test::Action1", vec![Keystroke::parse("a").unwrap()]),
|
||||||
("test::GlobalAction", vec![])
|
("test::GlobalAction", vec![])
|
||||||
|
@ -6210,7 +6219,7 @@ mod tests {
|
||||||
|
|
||||||
// Check that view 1 actions and bindings are available even when called from view 2
|
// Check that view 1 actions and bindings are available even when called from view 2
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&available_actions(window_id, view_2.id(), cx),
|
&available_actions(window.id(), view_2.id(), cx),
|
||||||
&[
|
&[
|
||||||
("test::Action1", vec![Keystroke::parse("a").unwrap()]),
|
("test::Action1", vec![Keystroke::parse("a").unwrap()]),
|
||||||
("test::Action2", vec![Keystroke::parse("b").unwrap()]),
|
("test::Action2", vec![Keystroke::parse("b").unwrap()]),
|
||||||
|
@ -6273,7 +6282,7 @@ mod tests {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
let actions = cx.available_actions(window_id, view.id());
|
let actions = cx.available_actions(window.id(), view.id());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actions[0].1.as_any().downcast_ref::<ActionWithArg>(),
|
actions[0].1.as_any().downcast_ref::<ActionWithArg>(),
|
||||||
Some(&ActionWithArg { arg: false })
|
Some(&ActionWithArg { arg: false })
|
||||||
|
@ -6559,25 +6568,25 @@ mod tests {
|
||||||
[("window 2", false), ("window 3", true)]
|
[("window 2", false), ("window 3", true)]
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.simulate_window_activation(Some(window_2));
|
cx.simulate_window_activation(Some(window_2.id()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
mem::take(&mut *events.borrow_mut()),
|
mem::take(&mut *events.borrow_mut()),
|
||||||
[("window 3", false), ("window 2", true)]
|
[("window 3", false), ("window 2", true)]
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.simulate_window_activation(Some(window_1));
|
cx.simulate_window_activation(Some(window_1.id()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
mem::take(&mut *events.borrow_mut()),
|
mem::take(&mut *events.borrow_mut()),
|
||||||
[("window 2", false), ("window 1", true)]
|
[("window 2", false), ("window 1", true)]
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.simulate_window_activation(Some(window_3));
|
cx.simulate_window_activation(Some(window_3.id()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
mem::take(&mut *events.borrow_mut()),
|
mem::take(&mut *events.borrow_mut()),
|
||||||
[("window 1", false), ("window 3", true)]
|
[("window 1", false), ("window 3", true)]
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.simulate_window_activation(Some(window_3));
|
cx.simulate_window_activation(Some(window_3.id()));
|
||||||
assert_eq!(mem::take(&mut *events.borrow_mut()), []);
|
assert_eq!(mem::take(&mut *events.borrow_mut()), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6633,12 +6642,13 @@ mod tests {
|
||||||
|
|
||||||
let child_rendered = Rc::new(Cell::new(false));
|
let child_rendered = Rc::new(Cell::new(false));
|
||||||
let child_dropped = Rc::new(Cell::new(false));
|
let child_dropped = Rc::new(Cell::new(false));
|
||||||
let (_, root_view) = cx.add_window(|cx| Parent {
|
let window = cx.add_window(|cx| Parent {
|
||||||
child: Some(cx.add_view(|_| Child {
|
child: Some(cx.add_view(|_| Child {
|
||||||
rendered: child_rendered.clone(),
|
rendered: child_rendered.clone(),
|
||||||
dropped: child_dropped.clone(),
|
dropped: child_dropped.clone(),
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
let root_view = window.root(cx);
|
||||||
assert!(child_rendered.take());
|
assert!(child_rendered.take());
|
||||||
assert!(!child_dropped.take());
|
assert!(!child_dropped.take());
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ struct ElementStateRefCount {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RefCounts {
|
pub struct RefCounts {
|
||||||
window_counts: HashMap<usize, usize>,
|
|
||||||
entity_counts: HashMap<usize, usize>,
|
entity_counts: HashMap<usize, usize>,
|
||||||
element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
|
element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
|
||||||
dropped_windows: HashSet<usize>,
|
dropped_windows: HashSet<usize>,
|
||||||
|
@ -46,7 +45,7 @@ impl RefCounts {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inc_window(&mut self, window_id: usize) {
|
pub fn inc_window(&mut self, window_id: usize) {
|
||||||
match self.window_counts.entry(window_id) {
|
match self.entity_counts.entry(window_id) {
|
||||||
Entry::Occupied(mut entry) => {
|
Entry::Occupied(mut entry) => {
|
||||||
*entry.get_mut() += 1;
|
*entry.get_mut() += 1;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +99,7 @@ impl RefCounts {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dec_window(&mut self, window_id: usize) {
|
pub fn dec_window(&mut self, window_id: usize) {
|
||||||
let count = self.window_counts.get_mut(&window_id).unwrap();
|
let count = self.entity_counts.get_mut(&window_id).unwrap();
|
||||||
*count -= 1;
|
*count -= 1;
|
||||||
if *count == 0 {
|
if *count == 0 {
|
||||||
self.entity_counts.remove(&window_id);
|
self.entity_counts.remove(&window_id);
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl TestAppContext {
|
||||||
RefCounts::new(leak_detector),
|
RefCounts::new(leak_detector),
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
cx.next_entity_id = first_entity_id;
|
cx.next_id = first_entity_id;
|
||||||
let cx = TestAppContext {
|
let cx = TestAppContext {
|
||||||
cx: Rc::new(RefCell::new(cx)),
|
cx: Rc::new(RefCell::new(cx)),
|
||||||
foreground_platform,
|
foreground_platform,
|
||||||
|
|
|
@ -1176,7 +1176,7 @@ impl<'a> WindowContext<'a> {
|
||||||
F: FnOnce(&mut ViewContext<T>) -> Option<T>,
|
F: FnOnce(&mut ViewContext<T>) -> Option<T>,
|
||||||
{
|
{
|
||||||
let window_id = self.window_id;
|
let window_id = self.window_id;
|
||||||
let view_id = post_inc(&mut self.next_entity_id);
|
let view_id = post_inc(&mut self.next_id);
|
||||||
let mut cx = ViewContext::mutable(self, view_id);
|
let mut cx = ViewContext::mutable(self, view_id);
|
||||||
let handle = if let Some(view) = build_view(&mut cx) {
|
let handle = if let Some(view) = build_view(&mut cx) {
|
||||||
let mut keymap_context = KeymapContext::default();
|
let mut keymap_context = KeymapContext::default();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue