Checkpoint
This commit is contained in:
parent
90d34c1251
commit
2b90b8d6b7
6 changed files with 77 additions and 7 deletions
|
@ -4,7 +4,7 @@ use collections::{HashMap, HashSet};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
pub trait Action: Any + Send + Sync {
|
pub trait Action: Any + Send + Sync {
|
||||||
fn partial_eq(&self, action: &dyn Action) -> bool;
|
fn eq(&self, action: &dyn Action) -> bool;
|
||||||
fn boxed_clone(&self) -> Box<dyn Action>;
|
fn boxed_clone(&self) -> Box<dyn Action>;
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ pub struct AppContext {
|
||||||
pub(crate) unit_entity: Handle<()>,
|
pub(crate) unit_entity: Handle<()>,
|
||||||
pub(crate) entities: EntityMap,
|
pub(crate) entities: EntityMap,
|
||||||
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
|
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
|
||||||
keymap: Arc<RwLock<Keymap>>,
|
pub(crate) keymap: Arc<RwLock<Keymap>>,
|
||||||
pub(crate) pending_notifications: HashSet<EntityId>,
|
pub(crate) pending_notifications: HashSet<EntityId>,
|
||||||
pending_effects: VecDeque<Effect>,
|
pending_effects: VecDeque<Effect>,
|
||||||
pub(crate) observers: SubscriberSet<EntityId, Handler>,
|
pub(crate) observers: SubscriberSet<EntityId, Handler>,
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct GlobalElementId(SmallVec<[ElementId; 8]>);
|
pub struct GlobalElementId(SmallVec<[ElementId; 32]>);
|
||||||
|
|
||||||
pub trait ElementIdentity: 'static + Send + Sync {
|
pub trait ElementIdentity: 'static + Send + Sync {
|
||||||
fn id(&self) -> Option<ElementId>;
|
fn id(&self) -> Option<ElementId>;
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl KeyBinding {
|
||||||
action: &dyn Action,
|
action: &dyn Action,
|
||||||
contexts: &[ActionContext],
|
contexts: &[ActionContext],
|
||||||
) -> Option<SmallVec<[Keystroke; 2]>> {
|
) -> Option<SmallVec<[Keystroke; 2]>> {
|
||||||
if self.action.partial_eq(action) && self.matches_context(contexts) {
|
if self.action.eq(action) && self.matches_context(contexts) {
|
||||||
Some(self.keystrokes.clone())
|
Some(self.keystrokes.clone())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -1035,8 +1035,21 @@ pub trait BorrowWindow: BorrowAppContext {
|
||||||
id: impl Into<ElementId>,
|
id: impl Into<ElementId>,
|
||||||
f: impl FnOnce(GlobalElementId, &mut Self) -> R,
|
f: impl FnOnce(GlobalElementId, &mut Self) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
self.window_mut().element_id_stack.push(id.into());
|
let keymap = self.app_mut().keymap.clone();
|
||||||
let global_id = self.window_mut().element_id_stack.clone();
|
let window = self.window_mut();
|
||||||
|
window.element_id_stack.push(id.into());
|
||||||
|
let global_id = window.element_id_stack.clone();
|
||||||
|
|
||||||
|
if window.key_matchers.get(&global_id).is_none() {
|
||||||
|
window.key_matchers.insert(
|
||||||
|
global_id.clone(),
|
||||||
|
window
|
||||||
|
.prev_frame_key_matchers
|
||||||
|
.remove(&global_id)
|
||||||
|
.unwrap_or_else(|| KeyMatcher::new(keymap)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let result = f(global_id, self);
|
let result = f(global_id, self);
|
||||||
self.window_mut().element_id_stack.pop();
|
self.window_mut().element_id_stack.pop();
|
||||||
result
|
result
|
||||||
|
|
|
@ -1,13 +1,56 @@
|
||||||
use gpui3::{div, view, Context, Focus, ParentElement, Styled, View, WindowContext};
|
use std::any::Any;
|
||||||
|
|
||||||
|
use gpui3::{
|
||||||
|
div, view, Action, Context, Focus, Interactive, KeyBinding, ParentElement, Styled, View,
|
||||||
|
WindowContext,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::themes::rose_pine;
|
use crate::themes::rose_pine;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct ActionA;
|
||||||
|
|
||||||
|
impl Action for ActionA {
|
||||||
|
fn eq(&self, action: &dyn Action) -> bool {
|
||||||
|
action.as_any().downcast_ref::<Self>().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn boxed_clone(&self) -> Box<dyn Action> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct ActionB;
|
||||||
|
|
||||||
|
impl Action for ActionB {
|
||||||
|
fn eq(&self, action: &dyn Action) -> bool {
|
||||||
|
action.as_any().downcast_ref::<Self>().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn boxed_clone(&self) -> Box<dyn Action> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct FocusStory {
|
pub struct FocusStory {
|
||||||
text: View<()>,
|
text: View<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FocusStory {
|
impl FocusStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<()> {
|
pub fn view(cx: &mut WindowContext) -> View<()> {
|
||||||
|
cx.bind_keys([
|
||||||
|
KeyBinding::new("cmd-a", ActionA, None),
|
||||||
|
KeyBinding::new("cmd-b", ActionB, None),
|
||||||
|
]);
|
||||||
let theme = rose_pine();
|
let theme = rose_pine();
|
||||||
|
|
||||||
let color_1 = theme.lowest.negative.default.foreground;
|
let color_1 = theme.lowest.negative.default.foreground;
|
||||||
|
@ -22,6 +65,12 @@ impl FocusStory {
|
||||||
let child_2 = cx.focus_handle();
|
let child_2 = cx.focus_handle();
|
||||||
view(cx.entity(|cx| ()), move |_, cx| {
|
view(cx.entity(|cx| ()), move |_, cx| {
|
||||||
div()
|
div()
|
||||||
|
.on_action(|_, action: &ActionA, phase, cx| {
|
||||||
|
println!("Action A dispatched on parent during {:?}", phase);
|
||||||
|
})
|
||||||
|
.on_action(|_, action: &ActionB, phase, cx| {
|
||||||
|
println!("Action A dispatched on parent during {:?}", phase);
|
||||||
|
})
|
||||||
.focusable(&parent)
|
.focusable(&parent)
|
||||||
.on_focus(|_, _, _| println!("Parent focused"))
|
.on_focus(|_, _, _| println!("Parent focused"))
|
||||||
.on_blur(|_, _, _| println!("Parent blurred"))
|
.on_blur(|_, _, _| println!("Parent blurred"))
|
||||||
|
@ -39,6 +88,10 @@ impl FocusStory {
|
||||||
.focus_in(|style| style.bg(color_3))
|
.focus_in(|style| style.bg(color_3))
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
|
.id("child 1")
|
||||||
|
.on_action(|_, action: &ActionA, phase, cx| {
|
||||||
|
println!("Action A dispatched on child 1 during {:?}", phase);
|
||||||
|
})
|
||||||
.focusable(&child_1)
|
.focusable(&child_1)
|
||||||
.w_full()
|
.w_full()
|
||||||
.h_6()
|
.h_6()
|
||||||
|
@ -59,6 +112,10 @@ impl FocusStory {
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
|
.id("child 2")
|
||||||
|
.on_action(|_, action: &ActionB, phase, cx| {
|
||||||
|
println!("Action B dispatched on child 2 during {:?}", phase);
|
||||||
|
})
|
||||||
.focusable(&child_2)
|
.focusable(&child_2)
|
||||||
.w_full()
|
.w_full()
|
||||||
.h_6()
|
.h_6()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue