Merge branch 'gpui2' of github.com:zed-industries/zed into gpui2

This commit is contained in:
Marshall Bowers 2023-10-18 14:19:29 -04:00
commit 5a42ca6772
6 changed files with 117 additions and 10 deletions

View File

@ -324,7 +324,10 @@ where
let focus_handle = focus_handle.clone();
cx.on_mouse_event(move |_, event: &MouseDownEvent, phase, cx| {
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
cx.focus(&focus_handle);
if !cx.default_prevented() {
cx.focus(&focus_handle);
cx.prevent_default();
}
}
})
}

View File

@ -89,11 +89,16 @@ pub trait Focus: Interactive {
self.listeners()
.focus
.push(Box::new(move |view, event, cx| {
if event
let descendant_blurred = event
.blurred
.as_ref()
.map_or(false, |blurred| handle.contains(blurred, cx));
let descendant_focused = event
.focused
.as_ref()
.map_or(false, |focused| focused.contains(&handle, cx))
{
.map_or(false, |focused| handle.contains(focused, cx));
if !descendant_blurred && descendant_focused {
listener(view, event, cx)
}
}));
@ -114,11 +119,15 @@ pub trait Focus: Interactive {
self.listeners()
.focus
.push(Box::new(move |view, event, cx| {
if event
let descendant_blurred = event
.blurred
.as_ref()
.map_or(false, |blurred| handle.contains(&blurred, cx))
{
.map_or(false, |blurred| handle.contains(blurred, cx));
let descendant_focused = event
.focused
.as_ref()
.map_or(false, |focused| handle.contains(focused, cx));
if descendant_blurred && !descendant_focused {
listener(view, event, cx)
}
}));

View File

@ -160,6 +160,7 @@ pub struct Window {
pub(crate) focus_listeners: Vec<AnyFocusListener>,
pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
propagate_event: bool,
default_prevented: bool,
mouse_position: Point<Pixels>,
scale_factor: f32,
pub(crate) scene_builder: SceneBuilder,
@ -230,6 +231,7 @@ impl Window {
focus_parents_by_child: HashMap::default(),
focus_listeners: Vec::new(),
propagate_event: true,
default_prevented: true,
mouse_position,
scale_factor,
scene_builder: SceneBuilder::new(),
@ -447,6 +449,14 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.propagate_event = false;
}
pub fn prevent_default(&mut self) {
self.window.default_prevented = true;
}
pub fn default_prevented(&self) -> bool {
self.window.default_prevented
}
pub fn on_mouse_event<Event: 'static>(
&mut self,
handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + Send + Sync + 'static,
@ -837,6 +847,10 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.mouse_position = *position;
}
// Handlers may set this to false by calling `stop_propagation`
self.window.propagate_event = true;
self.window.default_prevented = false;
if let Some(mut handlers) = self
.window
.mouse_listeners
@ -845,9 +859,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
// Because handlers may add other handlers, we sort every time.
handlers.sort_by(|(a, _), (b, _)| a.cmp(b));
// Handlers may set this to false by calling `stop_propagation`
self.window.propagate_event = true;
// Capture phase, events bubble from back to front. Handlers for this phase are used for
// special purposes, such as detecting events outside of a given Bounds.
for (_, handler) in &handlers {

View File

@ -1,7 +1,9 @@
mod focus;
mod kitchen_sink;
mod text;
mod z_index;
pub use focus::*;
pub use kitchen_sink::*;
pub use text::*;
pub use z_index::*;

View File

@ -0,0 +1,80 @@
use gpui3::{div, view, Context, Focus, ParentElement, Styled, View, WindowContext};
use crate::themes::rose_pine;
pub struct FocusStory {
text: View<()>,
}
impl FocusStory {
pub fn view(cx: &mut WindowContext) -> View<()> {
let theme = rose_pine();
let color_1 = theme.lowest.negative.default.foreground;
let color_2 = theme.lowest.positive.default.foreground;
let color_3 = theme.lowest.warning.default.foreground;
let color_4 = theme.lowest.accent.default.foreground;
let color_5 = theme.lowest.variant.default.foreground;
let color_6 = theme.highest.negative.default.foreground;
let parent = cx.focus_handle();
let child_1 = cx.focus_handle();
let child_2 = cx.focus_handle();
view(cx.entity(|cx| ()), move |_, cx| {
div()
.focusable(&parent)
.on_focus(|_, _, _| println!("Parent focused"))
.on_blur(|_, _, _| println!("Parent blurred"))
.on_focus_in(|_, _, _| println!("Parent focus_in"))
.on_focus_out(|_, _, _| println!("Parent focus_out"))
.on_key_down(|_, event, phase, _| {
println!("Key down on parent {:?} {:?}", phase, event)
})
.on_key_up(|_, event, phase, _| {
println!("Key up on parent {:?} {:?}", phase, event)
})
.size_full()
.bg(color_1)
.focus(|style| style.bg(color_2))
.focus_in(|style| style.bg(color_3))
.child(
div()
.focusable(&child_1)
.w_full()
.h_6()
.bg(color_4)
.focus(|style| style.bg(color_5))
.in_focus(|style| style.bg(color_6))
.on_focus(|_, _, _| println!("Child 1 focused"))
.on_blur(|_, _, _| println!("Child 1 blurred"))
.on_focus_in(|_, _, _| println!("Child 1 focus_in"))
.on_focus_out(|_, _, _| println!("Child 1 focus_out"))
.on_key_down(|_, event, phase, _| {
println!("Key down on child 1 {:?} {:?}", phase, event)
})
.on_key_up(|_, event, phase, _| {
println!("Key up on child 1 {:?} {:?}", phase, event)
})
.child("Child 1"),
)
.child(
div()
.focusable(&child_2)
.w_full()
.h_6()
.bg(color_4)
.on_focus(|_, _, _| println!("Child 2 focused"))
.on_blur(|_, _, _| println!("Child 2 blurred"))
.on_focus_in(|_, _, _| println!("Child 2 focus_in"))
.on_focus_out(|_, _, _| println!("Child 2 focus_out"))
.on_key_down(|_, event, phase, _| {
println!("Key down on child 2 {:?} {:?}", phase, event)
})
.on_key_up(|_, event, phase, _| {
println!("Key up on child 2 {:?} {:?}", phase, event)
})
.child("Child 2"),
)
})
}
}

View File

@ -15,6 +15,7 @@ pub enum ElementStory {
Avatar,
Button,
Details,
Focus,
Icon,
Input,
Label,
@ -35,6 +36,7 @@ impl ElementStory {
ui::DetailsStory::new().into_any()
})
.into_any(),
Self::Focus => FocusStory::view(cx).into_any(),
Self::Icon => {
view(cx.entity(|cx| ()), |_, _| ui::IconStory::new().into_any()).into_any()
}