mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-16 15:11:25 +00:00
Add group_active
This commit is contained in:
parent
d920f7edc1
commit
3dad0d9811
5 changed files with 37 additions and 16 deletions
|
@ -9,7 +9,7 @@ use smallvec::SmallVec;
|
|||
#[derive(Default)]
|
||||
struct GroupBounds(HashMap<SharedString, SmallVec<[Bounds<Pixels>; 1]>>);
|
||||
|
||||
pub fn element_group_bounds(name: &SharedString, cx: &mut AppContext) -> Option<Bounds<Pixels>> {
|
||||
pub fn group_bounds(name: &SharedString, cx: &mut AppContext) -> Option<Bounds<Pixels>> {
|
||||
cx.default_global::<GroupBounds>()
|
||||
.0
|
||||
.get(name)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
element_group_bounds, AnyElement, Bounds, DispatchPhase, Element, ElementId, IdentifiedElement,
|
||||
group_bounds, AnyElement, Bounds, DispatchPhase, Element, ElementId, IdentifiedElement,
|
||||
Interactive, MouseEventListeners, MouseMoveEvent, ParentElement, Pixels, SharedString, Styled,
|
||||
ViewContext,
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ use std::sync::{
|
|||
};
|
||||
|
||||
pub struct Hoverable<E: Styled> {
|
||||
hover_group: Option<SharedString>,
|
||||
group: Option<SharedString>,
|
||||
hovered: Arc<AtomicBool>,
|
||||
cascade_slot: CascadeSlot,
|
||||
hovered_style: <E::Style as Refineable>::Refinement,
|
||||
|
@ -21,7 +21,7 @@ pub struct Hoverable<E: Styled> {
|
|||
impl<E: Styled> Hoverable<E> {
|
||||
pub fn new(mut child: E, hover_group: Option<SharedString>) -> Self {
|
||||
Self {
|
||||
hover_group,
|
||||
group: hover_group,
|
||||
hovered: Arc::new(AtomicBool::new(false)),
|
||||
cascade_slot: child.style_cascade().reserve(),
|
||||
hovered_style: Default::default(),
|
||||
|
@ -80,13 +80,13 @@ where
|
|||
element_state: &mut Self::ElementState,
|
||||
cx: &mut ViewContext<Self::ViewState>,
|
||||
) {
|
||||
let hover_bounds = self
|
||||
.hover_group
|
||||
let target_bounds = self
|
||||
.group
|
||||
.as_ref()
|
||||
.and_then(|group| element_group_bounds(group, cx))
|
||||
.and_then(|group| group_bounds(group, cx))
|
||||
.unwrap_or(bounds);
|
||||
|
||||
let hovered = hover_bounds.contains_point(cx.mouse_position());
|
||||
let hovered = target_bounds.contains_point(cx.mouse_position());
|
||||
|
||||
let slot = self.cascade_slot;
|
||||
let style = hovered.then_some(self.hovered_style.clone());
|
||||
|
@ -98,7 +98,7 @@ where
|
|||
|
||||
move |_, event: &MouseMoveEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Capture {
|
||||
if hover_bounds.contains_point(event.position) != hovered.load(SeqCst) {
|
||||
if target_bounds.contains_point(event.position) != hovered.load(SeqCst) {
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
AnyElement, Bounds, DispatchPhase, Element, IdentifiedElement, Interactive, MouseDownEvent,
|
||||
MouseEventListeners, MouseUpEvent, ParentElement, Pixels, Styled, ViewContext,
|
||||
group_bounds, AnyElement, Bounds, DispatchPhase, Element, IdentifiedElement, Interactive,
|
||||
MouseDownEvent, MouseEventListeners, MouseUpEvent, ParentElement, Pixels, SharedString, Styled,
|
||||
ViewContext,
|
||||
};
|
||||
use refineable::{Cascade, CascadeSlot, Refineable};
|
||||
use smallvec::SmallVec;
|
||||
|
@ -10,6 +11,7 @@ use std::sync::{
|
|||
};
|
||||
|
||||
pub struct Pressable<E: Styled> {
|
||||
group: Option<SharedString>,
|
||||
cascade_slot: CascadeSlot,
|
||||
pressed_style: <E::Style as Refineable>::Refinement,
|
||||
child: E,
|
||||
|
@ -21,8 +23,9 @@ pub struct PressableState<S> {
|
|||
}
|
||||
|
||||
impl<E: Styled> Pressable<E> {
|
||||
pub fn new(mut child: E) -> Self {
|
||||
pub fn new(mut child: E, group: Option<SharedString>) -> Self {
|
||||
Self {
|
||||
group,
|
||||
cascade_slot: child.style_cascade().reserve(),
|
||||
pressed_style: Default::default(),
|
||||
child,
|
||||
|
@ -96,6 +99,12 @@ where
|
|||
element_state: &mut Self::ElementState,
|
||||
cx: &mut ViewContext<Self::ViewState>,
|
||||
) {
|
||||
let target_bounds = self
|
||||
.group
|
||||
.as_ref()
|
||||
.and_then(|group| group_bounds(group, cx))
|
||||
.unwrap_or(bounds);
|
||||
|
||||
let style = element_state
|
||||
.pressed
|
||||
.load(SeqCst)
|
||||
|
@ -105,8 +114,8 @@ where
|
|||
|
||||
let pressed = element_state.pressed.clone();
|
||||
cx.on_mouse_event(move |_, event: &MouseDownEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Capture {
|
||||
if bounds.contains_point(event.position) {
|
||||
if phase == DispatchPhase::Bubble {
|
||||
if target_bounds.contains_point(event.position) {
|
||||
pressed.store(true, SeqCst);
|
||||
cx.notify();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,15 @@ pub trait Styled {
|
|||
Self::Style: 'static + Refineable + Default + Send + Sync,
|
||||
<Self::Style as Refineable>::Refinement: 'static + Default + Send + Sync,
|
||||
{
|
||||
Pressable::new(self)
|
||||
Pressable::new(self, None)
|
||||
}
|
||||
|
||||
fn group_active(self, group_name: impl Into<SharedString>) -> Pressable<Self>
|
||||
where
|
||||
Self: 'static + Sized + Send + Sync,
|
||||
Self::Style: 'static + Refineable + Default + Send + Sync,
|
||||
<Self::Style as Refineable>::Refinement: 'static + Default + Send + Sync,
|
||||
{
|
||||
Pressable::new(self, Some(group_name.into()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,6 +175,7 @@ impl CollabPanel {
|
|||
.text_sm()
|
||||
.child(
|
||||
div()
|
||||
.id(0)
|
||||
// .uri(avatar_uri)
|
||||
.size_3p5()
|
||||
.rounded_full()
|
||||
|
@ -183,7 +184,9 @@ impl CollabPanel {
|
|||
.group_hover("")
|
||||
.fill(theme.middle.negative.default.foreground)
|
||||
.hover()
|
||||
.fill(theme.middle.warning.default.foreground),
|
||||
.fill(theme.middle.warning.default.foreground)
|
||||
.group_active("")
|
||||
.fill(theme.middle.accent.default.foreground),
|
||||
)
|
||||
.child(label),
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue