improv(segmented_button): nav bar, tab, and segmented control theme improvements

This commit is contained in:
Michael Aaron Murphy 2025-08-12 17:15:18 +02:00
parent 562e885872
commit 8badf73383
No known key found for this signature in database
GPG key ID: B2732D4240C9212C
8 changed files with 279 additions and 256 deletions

View file

@ -5,7 +5,7 @@
use crate::widget::segmented_button::{Appearance, ItemAppearance, StyleSheet};
use crate::{theme::Theme, widget::segmented_button::ItemStatusAppearance};
use cosmic_theme::{Component, Container};
use iced::Border;
use iced_core::{Background, border::Radius};
use palette::WithAlpha;
@ -16,6 +16,8 @@ pub enum SegmentedButton {
TabBar,
/// A widget for multiple choice selection.
Control,
/// Navigation bar style
NavBar,
/// Or implement any custom theme of your liking.
Custom(Box<dyn Fn(&Theme) -> Appearance>),
}
@ -25,85 +27,54 @@ impl StyleSheet for Theme {
#[allow(clippy::too_many_lines)]
fn horizontal(&self, style: &Self::Style) -> Appearance {
let container = &self.current_container();
let cosmic = self.cosmic();
let container = self.current_container();
match style {
SegmentedButton::TabBar => {
let cosmic = self.cosmic();
let active = horizontal::tab_bar_active(cosmic);
let hc = cosmic.is_high_contrast;
let (border_end, border_start, border_top) = if hc {
(
Some((1., container.component.border.into())),
Some((1., container.component.border.into())),
Some((1., container.component.border.into())),
)
} else {
(None, None, None)
};
Appearance {
border_radius: cosmic.corner_radii.radius_0.into(),
inactive: ItemStatusAppearance {
background: None,
first: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())),
border_end,
border_start,
border_top,
},
middle: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())),
border_end,
border_start,
border_top,
},
last: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())),
border_end,
border_start,
border_top,
},
text_color: container.component.on.into(),
},
hover: hover(cosmic, &container.component, &active),
focus: focus(cosmic, container, &active),
active,
..Default::default()
}
}
SegmentedButton::Control => {
let cosmic = self.cosmic();
let active = horizontal::selection_active(cosmic, &container.component);
let rad_m = cosmic.corner_radii.radius_m;
let rad_xl = cosmic.corner_radii.radius_xl;
let rad_0 = cosmic.corner_radii.radius_0;
let active = horizontal::selection_active(cosmic, &container.component);
Appearance {
background: Some(Background::Color(container.small_widget.into())),
border_radius: rad_m.into(),
background: Some(Background::Color(container.component.base.into())),
border: Border {
radius: rad_xl.into(),
..Default::default()
},
inactive: ItemStatusAppearance {
background: None,
first: ItemAppearance {
border_radius: Radius::from([rad_m[0], rad_0[1], rad_0[2], rad_m[3]]),
..Default::default()
border: Border {
radius: Radius::from([rad_xl[0], rad_0[1], rad_0[2], rad_xl[3]]),
..Default::default()
},
},
middle: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
border: Border {
radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
},
},
last: ItemAppearance {
border_radius: Radius::from([rad_0[0], rad_m[1], rad_m[2], rad_0[3]]),
..Default::default()
border: Border {
radius: Radius::from([rad_0[0], rad_xl[1], rad_xl[2], rad_0[3]]),
..Default::default()
},
},
text_color: container.component.on.into(),
},
hover: hover(cosmic, &container.component, &active),
focus: focus(cosmic, container, &active),
hover: hover(cosmic, &active, 0.2),
active,
..Default::default()
}
}
SegmentedButton::NavBar => Appearance {
active_width: 0.0,
..horizontal::tab_bar(cosmic, container)
},
SegmentedButton::TabBar => horizontal::tab_bar(cosmic, container),
SegmentedButton::Custom(func) => func(self),
}
}
@ -111,84 +82,126 @@ impl StyleSheet for Theme {
#[allow(clippy::too_many_lines)]
fn vertical(&self, style: &Self::Style) -> Appearance {
let cosmic = self.cosmic();
let rad_m = cosmic.corner_radii.radius_m;
let rad_0 = cosmic.corner_radii.radius_0;
let container = self.current_container();
match style {
SegmentedButton::TabBar => {
let container = &self.cosmic().primary;
let active = vertical::tab_bar_active(cosmic);
Appearance {
border_radius: cosmic.corner_radii.radius_0.into(),
inactive: ItemStatusAppearance {
background: None,
text_color: container.component.on.into(),
..active
},
hover: hover(cosmic, &container.component, &active),
focus: focus(cosmic, container, &active),
active,
..Default::default()
}
}
SegmentedButton::Control => {
let container = self.current_container();
let rad_xl = cosmic.corner_radii.radius_xl;
let rad_0 = cosmic.corner_radii.radius_0;
let active = vertical::selection_active(cosmic, &container.component);
Appearance {
background: Some(Background::Color(container.small_widget.into())),
border_radius: rad_m.into(),
background: Some(Background::Color(container.component.base.into())),
border: Border {
radius: rad_xl.into(),
..Default::default()
},
inactive: ItemStatusAppearance {
background: None,
first: ItemAppearance {
border_radius: Radius::from([rad_m[0], rad_m[1], rad_0[0], rad_0[0]]),
..Default::default()
border: Border {
radius: Radius::from([rad_xl[0], rad_xl[1], rad_0[0], rad_0[0]]),
..Default::default()
},
},
middle: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
border: Border {
radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
},
},
last: ItemAppearance {
border_radius: Radius::from([rad_0[0], rad_0[1], rad_m[2], rad_m[3]]),
..Default::default()
border: Border {
radius: Radius::from([rad_0[0], rad_0[1], rad_xl[2], rad_xl[3]]),
..Default::default()
},
},
text_color: container.component.on.into(),
},
hover: hover(cosmic, &container.component, &active),
focus: focus(cosmic, container, &active),
hover: hover(cosmic, &active, 0.2),
active,
..Default::default()
}
}
SegmentedButton::NavBar => Appearance {
active_width: 0.0,
..vertical::tab_bar(cosmic, container)
},
SegmentedButton::TabBar => vertical::tab_bar(cosmic, container),
SegmentedButton::Custom(func) => func(self),
}
}
}
mod horizontal {
use super::Appearance;
use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance};
use cosmic_theme::Component;
use cosmic_theme::{Component, Container};
use iced::Border;
use iced_core::{Background, border::Radius};
use palette::WithAlpha;
pub fn tab_bar(cosmic: &cosmic_theme::Theme, container: &Container) -> Appearance {
let active = tab_bar_active(cosmic);
let hc = cosmic.is_high_contrast;
let border = if hc {
Border {
color: container.component.border.into(),
radius: cosmic.corner_radii.radius_0.into(),
width: 1.0,
}
} else {
Border::default()
};
Appearance {
active_width: 4.0,
border: Border {
radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
},
inactive: ItemStatusAppearance {
background: None,
first: ItemAppearance { border },
middle: ItemAppearance { border },
last: ItemAppearance { border },
text_color: container.component.on.into(),
},
hover: super::hover(cosmic, &active, 0.3),
active,
..Default::default()
}
}
pub fn selection_active(
cosmic: &cosmic_theme::Theme,
component: &Component,
) -> ItemStatusAppearance {
let rad_m = cosmic.corner_radii.radius_m;
let rad_xl = cosmic.corner_radii.radius_xl;
let rad_0 = cosmic.corner_radii.radius_0;
ItemStatusAppearance {
background: Some(Background::Color(component.selected_state_color().into())),
background: Some(Background::Color(
cosmic.palette.neutral_5.with_alpha(0.1).into(),
)),
first: ItemAppearance {
border_radius: Radius::from([rad_m[0], rad_0[1], rad_0[2], rad_m[3]]),
..Default::default()
border: Border {
radius: Radius::from([rad_xl[0], rad_0[1], rad_0[2], rad_xl[3]]),
..Default::default()
},
},
middle: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
border: Border {
radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
},
},
last: ItemAppearance {
border_radius: Radius::from([rad_0[0], rad_m[1], rad_m[2], rad_0[3]]),
..Default::default()
border: Border {
radius: Radius::from([rad_0[0], rad_xl[1], rad_xl[2], rad_0[3]]),
..Default::default()
},
},
text_color: cosmic.accent_text_color().into(),
}
@ -202,78 +215,86 @@ mod horizontal {
cosmic.palette.neutral_5.with_alpha(0.2).into(),
)),
first: ItemAppearance {
border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
border_bottom: Some((4.0, cosmic.accent.base.into())),
..Default::default()
border: Border {
color: cosmic.accent.base.into(),
radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
width: 0.0,
},
},
middle: ItemAppearance {
border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
border_bottom: Some((4.0, cosmic.accent.base.into())),
..Default::default()
border: Border {
color: cosmic.accent.base.into(),
radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
width: 0.0,
},
},
last: ItemAppearance {
border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
border_bottom: Some((4.0, cosmic.accent.base.into())),
..Default::default()
border: Border {
color: cosmic.accent.base.into(),
radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
width: 0.0,
},
},
text_color: cosmic.accent_text_color().into(),
}
}
}
pub fn focus(
cosmic: &cosmic_theme::Theme,
container: &Container,
default: &ItemStatusAppearance,
) -> ItemStatusAppearance {
let color = container.small_widget;
ItemStatusAppearance {
background: Some(Background::Color(color.into())),
text_color: cosmic.accent_text_color().into(),
..*default
}
}
pub fn hover(
cosmic: &cosmic_theme::Theme,
component: &Component,
default: &ItemStatusAppearance,
) -> ItemStatusAppearance {
ItemStatusAppearance {
background: Some(Background::Color(component.hover.with_alpha(0.2).into())),
text_color: cosmic.accent_text_color().into(),
..*default
}
}
mod vertical {
use super::Appearance;
use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance};
use cosmic_theme::Component;
use cosmic_theme::{Component, Container};
use iced::Border;
use iced_core::{Background, border::Radius};
use palette::WithAlpha;
pub fn tab_bar(cosmic: &cosmic_theme::Theme, container: &Container) -> Appearance {
let active = tab_bar_active(cosmic);
Appearance {
active_width: 4.0,
border: Border {
radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
},
inactive: ItemStatusAppearance {
background: None,
text_color: container.component.on.into(),
..active
},
hover: super::hover(cosmic, &active, 0.3),
active,
..Default::default()
}
}
pub fn selection_active(
cosmic: &cosmic_theme::Theme,
component: &Component,
) -> ItemStatusAppearance {
let rad_0 = cosmic.corner_radii.radius_0;
let rad_m = cosmic.corner_radii.radius_m;
let rad_xl = cosmic.corner_radii.radius_xl;
ItemStatusAppearance {
background: Some(Background::Color(
component.selected_state_color().with_alpha(0.3).into(),
cosmic.palette.neutral_5.with_alpha(0.1).into(),
)),
first: ItemAppearance {
border_radius: Radius::from([rad_m[0], rad_m[1], rad_0[2], rad_0[3]]),
..Default::default()
border: Border {
radius: Radius::from([rad_xl[0], rad_xl[1], rad_0[2], rad_0[3]]),
..Default::default()
},
},
middle: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
border: Border {
radius: cosmic.corner_radii.radius_0.into(),
..Default::default()
},
},
last: ItemAppearance {
border_radius: Radius::from([rad_0[0], rad_0[1], rad_m[2], rad_m[3]]),
..Default::default()
border: Border {
radius: Radius::from([rad_0[0], rad_0[1], rad_xl[2], rad_xl[3]]),
..Default::default()
},
},
text_color: cosmic.accent_text_color().into(),
}
@ -285,18 +306,41 @@ mod vertical {
cosmic.palette.neutral_5.with_alpha(0.2).into(),
)),
first: ItemAppearance {
border_radius: cosmic.corner_radii.radius_m.into(),
..Default::default()
border: Border {
radius: cosmic.corner_radii.radius_m.into(),
width: 0.0,
..Default::default()
},
},
middle: ItemAppearance {
border_radius: cosmic.corner_radii.radius_m.into(),
..Default::default()
border: Border {
radius: cosmic.corner_radii.radius_m.into(),
width: 0.0,
..Default::default()
},
},
last: ItemAppearance {
border_radius: cosmic.corner_radii.radius_m.into(),
..Default::default()
border: Border {
radius: cosmic.corner_radii.radius_m.into(),
width: 0.0,
..Default::default()
},
},
text_color: cosmic.accent_text_color().into(),
}
}
}
pub fn hover(
cosmic: &cosmic_theme::Theme,
default: &ItemStatusAppearance,
alpha: f32,
) -> ItemStatusAppearance {
ItemStatusAppearance {
background: Some(Background::Color(
cosmic.palette.neutral_5.with_alpha(alpha).into(),
)),
text_color: cosmic.accent_text_color().into(),
..*default
}
}

View file

@ -149,7 +149,7 @@ impl<'a, Message: Clone + 'static> From<NavBar<'a, Message>>
.button_padding([space_s, space_xxs, space_s, space_xxs])
.button_spacing(space_xxs)
.spacing(space_xxs)
.style(crate::theme::SegmentedButton::TabBar)
.style(crate::theme::SegmentedButton::NavBar)
.apply(container)
.padding(space_xxs)
.apply(scrollable)

View file

@ -36,6 +36,8 @@ where
Model<SelectionMode>: Selectable,
SelectionMode: Default,
{
const VERTICAL: bool = false;
fn variant_appearance(
theme: &crate::Theme,
style: &crate::theme::SegmentedButton,

View file

@ -1,31 +1,24 @@
// Copyright 2022 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0
use iced_core::{Background, Color, border::Radius};
use iced::Border;
use iced_core::{Background, Color};
/// Appearance of the segmented button.
#[derive(Default, Clone, Copy)]
pub struct Appearance {
pub background: Option<Background>,
pub border_radius: Radius,
pub border_bottom: Option<(f32, Color)>,
pub border_end: Option<(f32, Color)>,
pub border_start: Option<(f32, Color)>,
pub border_top: Option<(f32, Color)>,
pub border: Border,
pub active_width: f32,
pub active: ItemStatusAppearance,
pub inactive: ItemStatusAppearance,
pub hover: ItemStatusAppearance,
pub focus: ItemStatusAppearance,
}
/// Appearance of an item in the segmented button.
#[derive(Default, Clone, Copy)]
pub struct ItemAppearance {
pub border_radius: Radius,
pub border_bottom: Option<(f32, Color)>,
pub border_end: Option<(f32, Color)>,
pub border_start: Option<(f32, Color)>,
pub border_top: Option<(f32, Color)>,
pub border: Border,
}
/// Appearance of an item based on its status.

View file

@ -36,6 +36,8 @@ where
Model<SelectionMode>: Selectable,
SelectionMode: Default,
{
const VERTICAL: bool = true;
fn variant_appearance(
theme: &crate::Theme,
style: &crate::theme::SegmentedButton,

View file

@ -22,11 +22,12 @@ use iced::{
use iced_core::mouse::ScrollDelta;
use iced_core::text::{LineHeight, Renderer as TextRenderer, Shaping, Wrapping};
use iced_core::widget::{self, operation, tree};
use iced_core::{Border, Gradient, Point, Renderer as IcedRenderer, Shadow, Text};
use iced_core::{Border, Point, Renderer as IcedRenderer, Shadow, Text};
use iced_core::{Clipboard, Layout, Shell, Widget, layout, renderer, widget::Tree};
use iced_runtime::{Action, task};
use slotmap::{Key, SecondaryMap};
use std::borrow::Cow;
use std::cell::LazyCell;
use std::collections::HashSet;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
@ -46,6 +47,8 @@ pub enum ItemBounds {
/// Isolates variant-specific behaviors from [`SegmentedButton`].
pub trait SegmentedVariant {
const VERTICAL: bool;
/// Get the appearance for this variant of the widget.
fn variant_appearance(
theme: &crate::Theme,
@ -107,11 +110,11 @@ where
/// Spacing for each indent.
pub(super) indent_spacing: u16,
/// Desired font for active tabs.
pub(super) font_active: Option<crate::font::Font>,
pub(super) font_active: crate::font::Font,
/// Desired font for hovered tabs.
pub(super) font_hovered: Option<crate::font::Font>,
pub(super) font_hovered: crate::font::Font,
/// Desired font for inactive tabs.
pub(super) font_inactive: Option<crate::font::Font>,
pub(super) font_inactive: crate::font::Font,
/// Size of the font.
pub(super) font_size: f32,
/// Desired width of the widget.
@ -175,9 +178,9 @@ where
minimum_button_width: u16::MIN,
maximum_button_width: u16::MAX,
indent_spacing: 16,
font_active: None,
font_hovered: None,
font_inactive: None,
font_active: crate::font::semibold(),
font_hovered: crate::font::semibold(),
font_inactive: crate::font::default(),
font_size: 14.0,
height: Length::Shrink,
width: Length::Fill,
@ -603,16 +606,16 @@ where
for key in self.model.order.iter().copied() {
if let Some(text) = self.model.text.get(key) {
let (font, button_state) =
if self.model.is_active(key) || self.button_is_focused(state, key) {
(self.font_active, 0)
} else if self.button_is_hovered(state, key) {
(self.font_hovered, 1)
} else {
(self.font_inactive, 2)
};
let (font, button_state) = if self.button_is_focused(state, key) {
(self.font_active, 0)
} else if state.show_context.is_some() || self.button_is_hovered(state, key) {
(self.font_hovered, 1)
} else if self.model.is_active(key) {
(self.font_active, 2)
} else {
(self.font_inactive, 3)
};
let font = font.unwrap_or_else(crate::font::default);
let mut hasher = DefaultHasher::new();
text.hash(&mut hasher);
font.hash(&mut hasher);
@ -1171,47 +1174,15 @@ where
let bounds: Rectangle = layout.bounds();
let button_amount = self.model.items.len();
// Modifies alpha color when `on_activate` is unset.
let apply_alpha = |mut c: Color| {
if self.on_activate.is_none() {
c.a /= 2.0;
}
c
};
// Maps `apply_alpha` to background color.
let bg_with_alpha = |mut b| {
match &mut b {
Background::Color(c) => {
*c = apply_alpha(*c);
}
Background::Gradient(g) => {
let Gradient::Linear(l) = g;
for c in &mut l.stops {
let Some(stop) = c else {
continue;
};
stop.color = apply_alpha(stop.color);
}
}
}
b
};
// Draw the background, if a background was defined.
if let Some(background) = appearance.background {
renderer.fill_quad(
renderer::Quad {
bounds,
border: Border {
radius: appearance.border_radius,
..Border::default()
},
border: appearance.border,
shadow: Shadow::default(),
},
bg_with_alpha(background),
background,
);
}
@ -1222,7 +1193,7 @@ where
// Previous tab button
let mut background_appearance =
if self.on_activate.is_some() && Item::PrevButton == state.focused_item {
Some(appearance.focus)
Some(appearance.active)
} else if self.on_activate.is_some() && Item::PrevButton == state.hovered {
Some(appearance.hover)
} else {
@ -1241,7 +1212,7 @@ where
},
background_appearance
.background
.map_or(Background::Color(Color::TRANSPARENT), bg_with_alpha),
.unwrap_or(Background::Color(Color::TRANSPARENT)),
);
}
@ -1251,13 +1222,11 @@ where
style,
cursor,
viewport,
apply_alpha(if state.buttons_offset == 0 {
if state.buttons_offset == 0 {
appearance.inactive.text_color
} else if let Item::PrevButton = state.focused_item {
appearance.focus.text_color
} else {
appearance.active.text_color
}),
},
Rectangle {
x: tab_bounds.x + 8.0,
y: tab_bounds.y + f32::from(self.button_height) / 4.0,
@ -1272,7 +1241,7 @@ where
// Next tab button
background_appearance =
if self.on_activate.is_some() && Item::NextButton == state.focused_item {
Some(appearance.focus)
Some(appearance.active)
} else if self.on_activate.is_some() && Item::NextButton == state.hovered {
Some(appearance.hover)
} else {
@ -1301,13 +1270,13 @@ where
style,
cursor,
viewport,
apply_alpha(if self.next_tab_sensitive(state) {
if self.next_tab_sensitive(state) {
appearance.active.text_color
} else if let Item::NextButton = state.focused_item {
appearance.focus.text_color
appearance.active.text_color
} else {
appearance.inactive.text_color
}),
},
Rectangle {
x: tab_bounds.x + 8.0,
y: tab_bounds.y + f32::from(self.button_height) / 4.0,
@ -1349,22 +1318,23 @@ where
let center_y = bounds.center_y();
let menu_open = !tree.children.is_empty()
&& tree.children[0]
.state
.downcast_ref::<MenuBarState>()
.inner
.with_data(|data| data.open);
let menu_open = || {
state.show_context == Some(key)
&& !tree.children.is_empty()
&& tree.children[0]
.state
.downcast_ref::<MenuBarState>()
.inner
.with_data(|data| data.open)
};
let key_is_active = self.model.is_active(key);
let key_is_hovered = self.button_is_hovered(state, key);
let key_has_context_menu_open = menu_open && state.show_context == Some(key);
let status_appearance = if self.button_is_focused(state, key) {
appearance.focus
let key_is_focused = self.button_is_focused(state, key);
let key_is_hovered = LazyCell::new(|| self.button_is_hovered(state, key));
let status_appearance = if *key_is_hovered || menu_open() {
appearance.hover
} else if key_is_active {
appearance.active
} else if key_is_hovered || key_has_context_menu_open {
appearance.hover
} else {
appearance.inactive
};
@ -1378,29 +1348,45 @@ where
};
// Render the background of the button.
if status_appearance.background.is_some() {
if key_is_focused || status_appearance.background.is_some() {
renderer.fill_quad(
renderer::Quad {
bounds,
border: Border {
radius: button_appearance.border_radius,
..Default::default()
border: if key_is_focused {
Border {
width: 1.0,
color: appearance.active.text_color,
radius: button_appearance.border.radius,
}
} else {
button_appearance.border
},
shadow: Shadow::default(),
},
status_appearance
.background
.map_or(Background::Color(Color::TRANSPARENT), bg_with_alpha),
.unwrap_or(Background::Color(Color::TRANSPARENT)),
);
}
// Draw the bottom border defined for this button.
if let Some((width, background)) = button_appearance.border_bottom {
let mut bounds = bounds;
bounds.y = bounds.y + bounds.height - width;
bounds.height = width;
// Draw the active hint on tabs
if appearance.active_width > 0.0 {
let rad_0 = THEME.lock().unwrap().cosmic().corner_radii.radius_0;
let active_width = if key_is_active {
appearance.active_width
} else {
1.0
};
let mut bounds = bounds;
if Self::VERTICAL {
bounds.x += bounds.height - active_width;
bounds.width = active_width;
} else {
bounds.y += bounds.height - active_width;
bounds.height = active_width;
}
renderer.fill_quad(
renderer::Quad {
bounds,
@ -1410,7 +1396,7 @@ where
},
shadow: Shadow::default(),
},
bg_with_alpha(background.into()),
appearance.active.text_color,
);
}
@ -1455,7 +1441,7 @@ where
style,
cursor,
viewport,
apply_alpha(status_appearance.text_color),
status_appearance.text_color,
Rectangle {
width,
height: width,
@ -1470,7 +1456,7 @@ where
if key_is_active {
if let crate::theme::SegmentedButton::Control = self.style {
let mut image_bounds = bounds;
image_bounds.y = center_y - 16.0 / 2.0;
image_bounds.y = center_y - 8.0;
draw_icon::<Message>(
renderer,
@ -1478,7 +1464,7 @@ where
style,
cursor,
viewport,
apply_alpha(status_appearance.text_color),
status_appearance.text_color,
Rectangle {
width: 16.0,
height: 16.0,
@ -1505,7 +1491,7 @@ where
// Whether to show the close button on this tab.
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);
// Width of the icon used by the close button, which we will subtract from the text bounds.
@ -1527,7 +1513,7 @@ where
renderer.fill_paragraph(
state.paragraphs[key].raw(),
bounds.position(),
apply_alpha(status_appearance.text_color),
status_appearance.text_color,
Rectangle {
x: bounds.x,
width: bounds.width,
@ -1546,7 +1532,7 @@ where
style,
cursor,
viewport,
apply_alpha(status_appearance.text_color),
status_appearance.text_color,
close_button_bounds,
self.close_icon.clone(),
);

View file

@ -30,7 +30,6 @@ where
.button_padding([space_s, 0, space_s, 0])
.button_spacing(space_xxs)
.style(crate::theme::SegmentedButton::Control)
.font_active(Some(crate::font::semibold()))
}
/// A selection of multiple choices appearing as a conjoined button.
@ -55,5 +54,4 @@ where
.button_padding([space_s, 0, space_s, 0])
.button_spacing(space_xxs)
.style(crate::theme::SegmentedButton::Control)
.font_active(Some(crate::font::semibold()))
}

View file

@ -29,7 +29,6 @@ where
.button_height(44)
.button_padding([space_s, space_xs, space_s, space_xs])
.style(crate::theme::SegmentedButton::TabBar)
.font_active(Some(crate::font::semibold()))
}
/// A collection of tabs for developing a tabbed interface.
@ -52,5 +51,4 @@ where
.button_height(44)
.button_padding([space_s, space_xs, space_s, space_xs])
.style(crate::theme::SegmentedButton::TabBar)
.font_active(Some(crate::font::semibold()))
}