feat(segmented_button): pressed state style

This commit is contained in:
Michael Aaron Murphy 2025-08-13 12:13:05 +02:00
parent 4f423349a2
commit 5434dc95d5
No known key found for this signature in database
GPG key ID: B2732D4240C9212C
3 changed files with 37 additions and 23 deletions

View file

@ -63,6 +63,7 @@ impl StyleSheet for Theme {
text_color: container.component.on.into(), text_color: container.component.on.into(),
}, },
hover: hover(cosmic, &active, 0.2), hover: hover(cosmic, &active, 0.2),
pressed: hover(cosmic, &active, 0.15),
active, active,
..Default::default() ..Default::default()
} }
@ -117,6 +118,7 @@ impl StyleSheet for Theme {
text_color: container.component.on.into(), text_color: container.component.on.into(),
}, },
hover: hover(cosmic, &active, 0.2), hover: hover(cosmic, &active, 0.2),
pressed: hover(cosmic, &active, 0.15),
active, active,
..Default::default() ..Default::default()
} }
@ -169,6 +171,7 @@ mod horizontal {
text_color: container.component.on.into(), text_color: container.component.on.into(),
}, },
hover: super::hover(cosmic, &active, 0.3), hover: super::hover(cosmic, &active, 0.3),
pressed: super::hover(cosmic, &active, 0.25),
active, active,
..Default::default() ..Default::default()
} }
@ -262,6 +265,7 @@ mod vertical {
..active ..active
}, },
hover: super::hover(cosmic, &active, 0.3), hover: super::hover(cosmic, &active, 0.3),
pressed: super::hover(cosmic, &active, 0.25),
active, active,
..Default::default() ..Default::default()
} }

View file

@ -13,6 +13,7 @@ pub struct Appearance {
pub active: ItemStatusAppearance, pub active: ItemStatusAppearance,
pub inactive: ItemStatusAppearance, pub inactive: ItemStatusAppearance,
pub hover: ItemStatusAppearance, pub hover: ItemStatusAppearance,
pub pressed: ItemStatusAppearance,
} }
/// Appearance of an item in the segmented button. /// Appearance of an item in the segmented button.

View file

@ -541,6 +541,10 @@ where
.is_some_and(|id| id.data.is_some_and(|d| d == key)) .is_some_and(|id| id.data.is_some_and(|d| d == key))
} }
fn button_is_pressed(&self, state: &LocalState, key: Entity) -> bool {
state.pressed_item == Some(Item::Tab(key))
}
/// Returns the drag id of the destination. /// Returns the drag id of the destination.
/// ///
/// # Panics /// # Panics
@ -923,28 +927,15 @@ where
} }
} }
if let Event::Mouse(mouse::Event::ButtonReleased(_)) if is_lifted(&event) {
| Event::Touch(touch::Event::FingerLifted { .. }) = event
{
state.unfocus(); state.unfocus();
} }
if let Some(on_activate) = self.on_activate.as_ref() { if let Some(on_activate) = self.on_activate.as_ref() {
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) if is_pressed(&event) {
| Event::Touch(touch::Event::FingerPressed { .. }) = event
{
state.pressed_item = Some(Item::Tab(key)); state.pressed_item = Some(Item::Tab(key));
} else if let Event::Mouse(mouse::Event::ButtonReleased( } else if is_lifted(&event) {
mouse::Button::Left, if self.button_is_pressed(state, key) {
))
| Event::Touch(touch::Event::FingerLifted { .. }) = event
{
let mut can_activate = true;
if state.pressed_item != Some(Item::Tab(key)) {
can_activate = false;
}
if can_activate {
shell.publish(on_activate(key)); shell.publish(on_activate(key));
state.set_focused(); state.set_focused();
state.focused_item = Item::Tab(key); state.focused_item = Item::Tab(key);
@ -1046,13 +1037,13 @@ where
} }
} else if state.is_focused() { } else if state.is_focused() {
// Unfocus on clicks outside of the boundaries of the segmented button. // Unfocus on clicks outside of the boundaries of the segmented button.
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) if is_pressed(&event) {
| Event::Touch(touch::Event::FingerPressed { .. }) = event
{
state.unfocus(); state.unfocus();
state.pressed_item = None; state.pressed_item = None;
return event::Status::Ignored; return event::Status::Ignored;
} }
} else if is_lifted(&event) {
state.pressed_item = None;
} }
if state.is_focused() { if state.is_focused() {
@ -1343,8 +1334,10 @@ where
let key_is_active = self.model.is_active(key); let key_is_active = self.model.is_active(key);
let key_is_focused = self.button_is_focused(state, key); let key_is_focused = self.button_is_focused(state, key);
let key_is_hovered = LazyCell::new(|| self.button_is_hovered(state, key)); let key_is_hovered = self.button_is_hovered(state, key);
let status_appearance = if *key_is_hovered || menu_open() { let status_appearance = if self.button_is_pressed(state, key) && key_is_hovered {
appearance.pressed
} else if key_is_hovered || menu_open() {
appearance.hover appearance.hover
} else if key_is_active { } else if key_is_active {
appearance.active appearance.active
@ -1504,7 +1497,7 @@ where
// Whether to show the close button on this tab. // Whether to show the close button on this tab.
let show_close_button = let show_close_button =
(key_is_active || !self.show_close_icon_on_hover || *key_is_hovered) (key_is_active || !self.show_close_icon_on_hover || key_is_hovered)
&& self.model.is_closable(key); && self.model.is_closable(key);
// Width of the icon used by the close button, which we will subtract from the text bounds. // Width of the icon used by the close button, which we will subtract from the text bounds.
@ -1856,6 +1849,22 @@ fn right_button_released(event: &Event) -> bool {
) )
} }
fn is_pressed(event: &Event) -> bool {
matches!(
event,
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
| Event::Touch(touch::Event::FingerPressed { .. })
)
}
fn is_lifted(event: &Event) -> bool {
matches!(
event,
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left,))
| Event::Touch(touch::Event::FingerLifted { .. })
)
}
fn touch_lifted(event: &Event) -> bool { fn touch_lifted(event: &Event) -> bool {
matches!(event, Event::Touch(touch::Event::FingerLifted { .. })) matches!(event, Event::Touch(touch::Event::FingerLifted { .. }))
} }