diff --git a/crates/gpui3/src/elements/div.rs b/crates/gpui3/src/elements/div.rs index 2f6fc00595..1cada008f2 100644 --- a/crates/gpui3/src/elements/div.rs +++ b/crates/gpui3/src/elements/div.rs @@ -74,6 +74,9 @@ where group_hover: None, active_style: StyleRefinement::default(), group_active: None, + focus_style: StyleRefinement::default(), + focus_in_style: StyleRefinement::default(), + in_focus_style: StyleRefinement::default(), listeners: EventListeners::default(), } } @@ -88,6 +91,9 @@ pub struct Div, active_style: StyleRefinement, group_active: Option, + focus_style: StyleRefinement, + focus_in_style: StyleRefinement, + in_focus_style: StyleRefinement, listeners: EventListeners, } @@ -112,6 +118,9 @@ where group_hover: self.group_hover, active_style: self.active_style, group_active: self.group_active, + focus_style: self.focus_style, + focus_in_style: self.focus_in_style, + in_focus_style: self.in_focus_style, listeners: self.listeners, } } @@ -192,6 +201,20 @@ where let mut computed_style = Style::default(); computed_style.refine(&self.base_style); + if let Some(handle) = self.focusability.focus_handle() { + if handle.contains_focused(cx) { + computed_style.refine(&self.focus_in_style); + } + + if handle.within_focused(cx) { + computed_style.refine(&self.in_focus_style); + } + + if handle.is_focused(cx) { + computed_style.refine(&self.focus_style); + } + } + let mouse_position = cx.mouse_position(); if let Some(group_hover) = self.group_hover.as_ref() { @@ -334,6 +357,9 @@ where group_hover: self.group_hover, active_style: self.active_style, group_active: self.group_active, + focus_style: self.focus_style, + focus_in_style: self.focus_in_style, + in_focus_style: self.in_focus_style, listeners: self.listeners, } } @@ -347,6 +373,18 @@ where fn handle(&self) -> &FocusHandle { self.focusability.as_ref() } + + fn set_focus_style(&mut self, style: StyleRefinement) { + self.focus_style = style; + } + + fn set_focus_in_style(&mut self, style: StyleRefinement) { + self.focus_in_style = style; + } + + fn set_in_focus_style(&mut self, style: StyleRefinement) { + self.in_focus_style = style; + } } impl Element for Div diff --git a/crates/gpui3/src/focus.rs b/crates/gpui3/src/focus.rs index c7f405a358..d6e9adc6fd 100644 --- a/crates/gpui3/src/focus.rs +++ b/crates/gpui3/src/focus.rs @@ -1,10 +1,38 @@ use crate::{ - DispatchPhase, FocusEvent, FocusHandle, Interactive, KeyDownEvent, KeyUpEvent, ViewContext, + DispatchPhase, FocusEvent, FocusHandle, Interactive, KeyDownEvent, KeyUpEvent, StyleRefinement, + ViewContext, }; pub trait Focus: Interactive { + fn set_focus_style(&mut self, style: StyleRefinement); + fn set_focus_in_style(&mut self, style: StyleRefinement); + fn set_in_focus_style(&mut self, style: StyleRefinement); fn handle(&self) -> &FocusHandle; + fn focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self + where + Self: Sized, + { + self.set_focus_style(f(StyleRefinement::default())); + self + } + + fn focus_in(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self + where + Self: Sized, + { + self.set_focus_in_style(f(StyleRefinement::default())); + self + } + + fn in_focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self + where + Self: Sized, + { + self.set_in_focus_style(f(StyleRefinement::default())); + self + } + fn on_focus( mut self, listener: impl Fn(&mut Self::ViewState, &FocusEvent, &mut ViewContext)