Checkpoint

This commit is contained in:
Antonio Scandurra 2023-10-19 19:43:28 +02:00
parent 90d34c1251
commit 2b90b8d6b7
6 changed files with 77 additions and 7 deletions

View file

@ -4,7 +4,7 @@ use collections::{HashMap, HashSet};
use std::any::Any;
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 as_any(&self) -> &dyn Any;
}

View file

@ -112,7 +112,7 @@ pub struct AppContext {
pub(crate) unit_entity: Handle<()>,
pub(crate) entities: EntityMap,
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
keymap: Arc<RwLock<Keymap>>,
pub(crate) keymap: Arc<RwLock<Keymap>>,
pub(crate) pending_notifications: HashSet<EntityId>,
pending_effects: VecDeque<Effect>,
pub(crate) observers: SubscriberSet<EntityId, Handler>,

View file

@ -33,7 +33,7 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
}
#[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 {
fn id(&self) -> Option<ElementId>;

View file

@ -63,7 +63,7 @@ impl KeyBinding {
action: &dyn Action,
contexts: &[ActionContext],
) -> 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())
} else {
None

View file

@ -1035,8 +1035,21 @@ pub trait BorrowWindow: BorrowAppContext {
id: impl Into<ElementId>,
f: impl FnOnce(GlobalElementId, &mut Self) -> R,
) -> R {
self.window_mut().element_id_stack.push(id.into());
let global_id = self.window_mut().element_id_stack.clone();
let keymap = self.app_mut().keymap.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);
self.window_mut().element_id_stack.pop();
result

View file

@ -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;
#[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 {
text: View<()>,
}
impl FocusStory {
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 color_1 = theme.lowest.negative.default.foreground;
@ -22,6 +65,12 @@ impl FocusStory {
let child_2 = cx.focus_handle();
view(cx.entity(|cx| ()), move |_, cx| {
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)
.on_focus(|_, _, _| println!("Parent focused"))
.on_blur(|_, _, _| println!("Parent blurred"))
@ -39,6 +88,10 @@ impl FocusStory {
.focus_in(|style| style.bg(color_3))
.child(
div()
.id("child 1")
.on_action(|_, action: &ActionA, phase, cx| {
println!("Action A dispatched on child 1 during {:?}", phase);
})
.focusable(&child_1)
.w_full()
.h_6()
@ -59,6 +112,10 @@ impl FocusStory {
)
.child(
div()
.id("child 2")
.on_action(|_, action: &ActionB, phase, cx| {
println!("Action B dispatched on child 2 during {:?}", phase);
})
.focusable(&child_2)
.w_full()
.h_6()