improv(segmented_button): nav bar, tab, and segmented control theme improvements
This commit is contained in:
parent
562e885872
commit
8badf73383
8 changed files with 279 additions and 256 deletions
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
use crate::widget::segmented_button::{Appearance, ItemAppearance, StyleSheet};
|
use crate::widget::segmented_button::{Appearance, ItemAppearance, StyleSheet};
|
||||||
use crate::{theme::Theme, widget::segmented_button::ItemStatusAppearance};
|
use crate::{theme::Theme, widget::segmented_button::ItemStatusAppearance};
|
||||||
use cosmic_theme::{Component, Container};
|
use iced::Border;
|
||||||
use iced_core::{Background, border::Radius};
|
use iced_core::{Background, border::Radius};
|
||||||
use palette::WithAlpha;
|
use palette::WithAlpha;
|
||||||
|
|
||||||
|
|
@ -16,6 +16,8 @@ pub enum SegmentedButton {
|
||||||
TabBar,
|
TabBar,
|
||||||
/// A widget for multiple choice selection.
|
/// A widget for multiple choice selection.
|
||||||
Control,
|
Control,
|
||||||
|
/// Navigation bar style
|
||||||
|
NavBar,
|
||||||
/// Or implement any custom theme of your liking.
|
/// Or implement any custom theme of your liking.
|
||||||
Custom(Box<dyn Fn(&Theme) -> Appearance>),
|
Custom(Box<dyn Fn(&Theme) -> Appearance>),
|
||||||
}
|
}
|
||||||
|
|
@ -25,85 +27,54 @@ impl StyleSheet for Theme {
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
fn horizontal(&self, style: &Self::Style) -> Appearance {
|
fn horizontal(&self, style: &Self::Style) -> Appearance {
|
||||||
let container = &self.current_container();
|
let cosmic = self.cosmic();
|
||||||
|
let container = self.current_container();
|
||||||
match style {
|
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 => {
|
SegmentedButton::Control => {
|
||||||
let cosmic = self.cosmic();
|
let rad_xl = cosmic.corner_radii.radius_xl;
|
||||||
let active = horizontal::selection_active(cosmic, &container.component);
|
|
||||||
let rad_m = cosmic.corner_radii.radius_m;
|
|
||||||
let rad_0 = cosmic.corner_radii.radius_0;
|
let rad_0 = cosmic.corner_radii.radius_0;
|
||||||
|
let active = horizontal::selection_active(cosmic, &container.component);
|
||||||
Appearance {
|
Appearance {
|
||||||
background: Some(Background::Color(container.small_widget.into())),
|
background: Some(Background::Color(container.component.base.into())),
|
||||||
border_radius: rad_m.into(),
|
border: Border {
|
||||||
|
radius: rad_xl.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
inactive: ItemStatusAppearance {
|
inactive: ItemStatusAppearance {
|
||||||
background: None,
|
background: None,
|
||||||
first: ItemAppearance {
|
first: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_m[0], rad_0[1], rad_0[2], rad_m[3]]),
|
border: Border {
|
||||||
..Default::default()
|
radius: Radius::from([rad_xl[0], rad_0[1], rad_0[2], rad_xl[3]]),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
middle: ItemAppearance {
|
middle: ItemAppearance {
|
||||||
border_radius: cosmic.corner_radii.radius_0.into(),
|
border: Border {
|
||||||
..Default::default()
|
radius: cosmic.corner_radii.radius_0.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
last: ItemAppearance {
|
last: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_0[0], rad_m[1], rad_m[2], rad_0[3]]),
|
border: Border {
|
||||||
..Default::default()
|
radius: Radius::from([rad_0[0], rad_xl[1], rad_xl[2], rad_0[3]]),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
text_color: container.component.on.into(),
|
text_color: container.component.on.into(),
|
||||||
},
|
},
|
||||||
hover: hover(cosmic, &container.component, &active),
|
hover: hover(cosmic, &active, 0.2),
|
||||||
focus: focus(cosmic, container, &active),
|
|
||||||
active,
|
active,
|
||||||
..Default::default()
|
..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),
|
SegmentedButton::Custom(func) => func(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -111,84 +82,126 @@ impl StyleSheet for Theme {
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
fn vertical(&self, style: &Self::Style) -> Appearance {
|
fn vertical(&self, style: &Self::Style) -> Appearance {
|
||||||
let cosmic = self.cosmic();
|
let cosmic = self.cosmic();
|
||||||
let rad_m = cosmic.corner_radii.radius_m;
|
let container = self.current_container();
|
||||||
let rad_0 = cosmic.corner_radii.radius_0;
|
|
||||||
match style {
|
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 => {
|
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);
|
let active = vertical::selection_active(cosmic, &container.component);
|
||||||
Appearance {
|
Appearance {
|
||||||
background: Some(Background::Color(container.small_widget.into())),
|
background: Some(Background::Color(container.component.base.into())),
|
||||||
border_radius: rad_m.into(),
|
border: Border {
|
||||||
|
radius: rad_xl.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
inactive: ItemStatusAppearance {
|
inactive: ItemStatusAppearance {
|
||||||
background: None,
|
background: None,
|
||||||
first: ItemAppearance {
|
first: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_m[0], rad_m[1], rad_0[0], rad_0[0]]),
|
border: Border {
|
||||||
..Default::default()
|
radius: Radius::from([rad_xl[0], rad_xl[1], rad_0[0], rad_0[0]]),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
middle: ItemAppearance {
|
middle: ItemAppearance {
|
||||||
border_radius: cosmic.corner_radii.radius_0.into(),
|
border: Border {
|
||||||
..Default::default()
|
radius: cosmic.corner_radii.radius_0.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
last: ItemAppearance {
|
last: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_0[0], rad_0[1], rad_m[2], rad_m[3]]),
|
border: Border {
|
||||||
..Default::default()
|
radius: Radius::from([rad_0[0], rad_0[1], rad_xl[2], rad_xl[3]]),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
text_color: container.component.on.into(),
|
text_color: container.component.on.into(),
|
||||||
},
|
},
|
||||||
hover: hover(cosmic, &container.component, &active),
|
hover: hover(cosmic, &active, 0.2),
|
||||||
focus: focus(cosmic, container, &active),
|
|
||||||
active,
|
active,
|
||||||
..Default::default()
|
..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),
|
SegmentedButton::Custom(func) => func(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod horizontal {
|
mod horizontal {
|
||||||
|
use super::Appearance;
|
||||||
use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance};
|
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 iced_core::{Background, border::Radius};
|
||||||
use palette::WithAlpha;
|
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(
|
pub fn selection_active(
|
||||||
cosmic: &cosmic_theme::Theme,
|
cosmic: &cosmic_theme::Theme,
|
||||||
component: &Component,
|
component: &Component,
|
||||||
) -> ItemStatusAppearance {
|
) -> 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;
|
let rad_0 = cosmic.corner_radii.radius_0;
|
||||||
|
|
||||||
ItemStatusAppearance {
|
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 {
|
first: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_m[0], rad_0[1], rad_0[2], rad_m[3]]),
|
border: Border {
|
||||||
..Default::default()
|
radius: Radius::from([rad_xl[0], rad_0[1], rad_0[2], rad_xl[3]]),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
middle: ItemAppearance {
|
middle: ItemAppearance {
|
||||||
border_radius: cosmic.corner_radii.radius_0.into(),
|
border: Border {
|
||||||
..Default::default()
|
radius: cosmic.corner_radii.radius_0.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
last: ItemAppearance {
|
last: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_0[0], rad_m[1], rad_m[2], rad_0[3]]),
|
border: Border {
|
||||||
..Default::default()
|
radius: Radius::from([rad_0[0], rad_xl[1], rad_xl[2], rad_0[3]]),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
text_color: cosmic.accent_text_color().into(),
|
text_color: cosmic.accent_text_color().into(),
|
||||||
}
|
}
|
||||||
|
|
@ -202,78 +215,86 @@ mod horizontal {
|
||||||
cosmic.palette.neutral_5.with_alpha(0.2).into(),
|
cosmic.palette.neutral_5.with_alpha(0.2).into(),
|
||||||
)),
|
)),
|
||||||
first: ItemAppearance {
|
first: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
|
border: Border {
|
||||||
border_bottom: Some((4.0, cosmic.accent.base.into())),
|
color: cosmic.accent.base.into(),
|
||||||
..Default::default()
|
radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
|
||||||
|
width: 0.0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
middle: ItemAppearance {
|
middle: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
|
border: Border {
|
||||||
border_bottom: Some((4.0, cosmic.accent.base.into())),
|
color: cosmic.accent.base.into(),
|
||||||
..Default::default()
|
radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
|
||||||
|
width: 0.0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
last: ItemAppearance {
|
last: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]),
|
border: Border {
|
||||||
border_bottom: Some((4.0, cosmic.accent.base.into())),
|
color: cosmic.accent.base.into(),
|
||||||
..Default::default()
|
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(),
|
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 {
|
mod vertical {
|
||||||
|
use super::Appearance;
|
||||||
use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance};
|
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 iced_core::{Background, border::Radius};
|
||||||
use palette::WithAlpha;
|
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(
|
pub fn selection_active(
|
||||||
cosmic: &cosmic_theme::Theme,
|
cosmic: &cosmic_theme::Theme,
|
||||||
component: &Component,
|
component: &Component,
|
||||||
) -> ItemStatusAppearance {
|
) -> ItemStatusAppearance {
|
||||||
let rad_0 = cosmic.corner_radii.radius_0;
|
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 {
|
ItemStatusAppearance {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
component.selected_state_color().with_alpha(0.3).into(),
|
cosmic.palette.neutral_5.with_alpha(0.1).into(),
|
||||||
)),
|
)),
|
||||||
first: ItemAppearance {
|
first: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_m[0], rad_m[1], rad_0[2], rad_0[3]]),
|
border: Border {
|
||||||
..Default::default()
|
radius: Radius::from([rad_xl[0], rad_xl[1], rad_0[2], rad_0[3]]),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
middle: ItemAppearance {
|
middle: ItemAppearance {
|
||||||
border_radius: cosmic.corner_radii.radius_0.into(),
|
border: Border {
|
||||||
..Default::default()
|
radius: cosmic.corner_radii.radius_0.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
last: ItemAppearance {
|
last: ItemAppearance {
|
||||||
border_radius: Radius::from([rad_0[0], rad_0[1], rad_m[2], rad_m[3]]),
|
border: Border {
|
||||||
..Default::default()
|
radius: Radius::from([rad_0[0], rad_0[1], rad_xl[2], rad_xl[3]]),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
text_color: cosmic.accent_text_color().into(),
|
text_color: cosmic.accent_text_color().into(),
|
||||||
}
|
}
|
||||||
|
|
@ -285,18 +306,41 @@ mod vertical {
|
||||||
cosmic.palette.neutral_5.with_alpha(0.2).into(),
|
cosmic.palette.neutral_5.with_alpha(0.2).into(),
|
||||||
)),
|
)),
|
||||||
first: ItemAppearance {
|
first: ItemAppearance {
|
||||||
border_radius: cosmic.corner_radii.radius_m.into(),
|
border: Border {
|
||||||
..Default::default()
|
radius: cosmic.corner_radii.radius_m.into(),
|
||||||
|
width: 0.0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
middle: ItemAppearance {
|
middle: ItemAppearance {
|
||||||
border_radius: cosmic.corner_radii.radius_m.into(),
|
border: Border {
|
||||||
..Default::default()
|
radius: cosmic.corner_radii.radius_m.into(),
|
||||||
|
width: 0.0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
last: ItemAppearance {
|
last: ItemAppearance {
|
||||||
border_radius: cosmic.corner_radii.radius_m.into(),
|
border: Border {
|
||||||
..Default::default()
|
radius: cosmic.corner_radii.radius_m.into(),
|
||||||
|
width: 0.0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
text_color: cosmic.accent_text_color().into(),
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ impl<'a, Message: Clone + 'static> From<NavBar<'a, Message>>
|
||||||
.button_padding([space_s, space_xxs, space_s, space_xxs])
|
.button_padding([space_s, space_xxs, space_s, space_xxs])
|
||||||
.button_spacing(space_xxs)
|
.button_spacing(space_xxs)
|
||||||
.spacing(space_xxs)
|
.spacing(space_xxs)
|
||||||
.style(crate::theme::SegmentedButton::TabBar)
|
.style(crate::theme::SegmentedButton::NavBar)
|
||||||
.apply(container)
|
.apply(container)
|
||||||
.padding(space_xxs)
|
.padding(space_xxs)
|
||||||
.apply(scrollable)
|
.apply(scrollable)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ where
|
||||||
Model<SelectionMode>: Selectable,
|
Model<SelectionMode>: Selectable,
|
||||||
SelectionMode: Default,
|
SelectionMode: Default,
|
||||||
{
|
{
|
||||||
|
const VERTICAL: bool = false;
|
||||||
|
|
||||||
fn variant_appearance(
|
fn variant_appearance(
|
||||||
theme: &crate::Theme,
|
theme: &crate::Theme,
|
||||||
style: &crate::theme::SegmentedButton,
|
style: &crate::theme::SegmentedButton,
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,24 @@
|
||||||
// Copyright 2022 System76 <info@system76.com>
|
// Copyright 2022 System76 <info@system76.com>
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
// 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.
|
/// Appearance of the segmented button.
|
||||||
#[derive(Default, Clone, Copy)]
|
#[derive(Default, Clone, Copy)]
|
||||||
pub struct Appearance {
|
pub struct Appearance {
|
||||||
pub background: Option<Background>,
|
pub background: Option<Background>,
|
||||||
pub border_radius: Radius,
|
pub border: Border,
|
||||||
pub border_bottom: Option<(f32, Color)>,
|
pub active_width: f32,
|
||||||
pub border_end: Option<(f32, Color)>,
|
|
||||||
pub border_start: Option<(f32, Color)>,
|
|
||||||
pub border_top: Option<(f32, Color)>,
|
|
||||||
pub active: ItemStatusAppearance,
|
pub active: ItemStatusAppearance,
|
||||||
pub inactive: ItemStatusAppearance,
|
pub inactive: ItemStatusAppearance,
|
||||||
pub hover: ItemStatusAppearance,
|
pub hover: ItemStatusAppearance,
|
||||||
pub focus: ItemStatusAppearance,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appearance of an item in the segmented button.
|
/// Appearance of an item in the segmented button.
|
||||||
#[derive(Default, Clone, Copy)]
|
#[derive(Default, Clone, Copy)]
|
||||||
pub struct ItemAppearance {
|
pub struct ItemAppearance {
|
||||||
pub border_radius: Radius,
|
pub border: Border,
|
||||||
pub border_bottom: Option<(f32, Color)>,
|
|
||||||
pub border_end: Option<(f32, Color)>,
|
|
||||||
pub border_start: Option<(f32, Color)>,
|
|
||||||
pub border_top: Option<(f32, Color)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appearance of an item based on its status.
|
/// Appearance of an item based on its status.
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ where
|
||||||
Model<SelectionMode>: Selectable,
|
Model<SelectionMode>: Selectable,
|
||||||
SelectionMode: Default,
|
SelectionMode: Default,
|
||||||
{
|
{
|
||||||
|
const VERTICAL: bool = true;
|
||||||
|
|
||||||
fn variant_appearance(
|
fn variant_appearance(
|
||||||
theme: &crate::Theme,
|
theme: &crate::Theme,
|
||||||
style: &crate::theme::SegmentedButton,
|
style: &crate::theme::SegmentedButton,
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,12 @@ use iced::{
|
||||||
use iced_core::mouse::ScrollDelta;
|
use iced_core::mouse::ScrollDelta;
|
||||||
use iced_core::text::{LineHeight, Renderer as TextRenderer, Shaping, Wrapping};
|
use iced_core::text::{LineHeight, Renderer as TextRenderer, Shaping, Wrapping};
|
||||||
use iced_core::widget::{self, operation, tree};
|
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_core::{Clipboard, Layout, Shell, Widget, layout, renderer, widget::Tree};
|
||||||
use iced_runtime::{Action, task};
|
use iced_runtime::{Action, task};
|
||||||
use slotmap::{Key, SecondaryMap};
|
use slotmap::{Key, SecondaryMap};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::cell::LazyCell;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
@ -46,6 +47,8 @@ pub enum ItemBounds {
|
||||||
|
|
||||||
/// Isolates variant-specific behaviors from [`SegmentedButton`].
|
/// Isolates variant-specific behaviors from [`SegmentedButton`].
|
||||||
pub trait SegmentedVariant {
|
pub trait SegmentedVariant {
|
||||||
|
const VERTICAL: bool;
|
||||||
|
|
||||||
/// Get the appearance for this variant of the widget.
|
/// Get the appearance for this variant of the widget.
|
||||||
fn variant_appearance(
|
fn variant_appearance(
|
||||||
theme: &crate::Theme,
|
theme: &crate::Theme,
|
||||||
|
|
@ -107,11 +110,11 @@ where
|
||||||
/// Spacing for each indent.
|
/// Spacing for each indent.
|
||||||
pub(super) indent_spacing: u16,
|
pub(super) indent_spacing: u16,
|
||||||
/// Desired font for active tabs.
|
/// 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.
|
/// 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.
|
/// Desired font for inactive tabs.
|
||||||
pub(super) font_inactive: Option<crate::font::Font>,
|
pub(super) font_inactive: crate::font::Font,
|
||||||
/// Size of the font.
|
/// Size of the font.
|
||||||
pub(super) font_size: f32,
|
pub(super) font_size: f32,
|
||||||
/// Desired width of the widget.
|
/// Desired width of the widget.
|
||||||
|
|
@ -175,9 +178,9 @@ where
|
||||||
minimum_button_width: u16::MIN,
|
minimum_button_width: u16::MIN,
|
||||||
maximum_button_width: u16::MAX,
|
maximum_button_width: u16::MAX,
|
||||||
indent_spacing: 16,
|
indent_spacing: 16,
|
||||||
font_active: None,
|
font_active: crate::font::semibold(),
|
||||||
font_hovered: None,
|
font_hovered: crate::font::semibold(),
|
||||||
font_inactive: None,
|
font_inactive: crate::font::default(),
|
||||||
font_size: 14.0,
|
font_size: 14.0,
|
||||||
height: Length::Shrink,
|
height: Length::Shrink,
|
||||||
width: Length::Fill,
|
width: Length::Fill,
|
||||||
|
|
@ -603,16 +606,16 @@ where
|
||||||
|
|
||||||
for key in self.model.order.iter().copied() {
|
for key in self.model.order.iter().copied() {
|
||||||
if let Some(text) = self.model.text.get(key) {
|
if let Some(text) = self.model.text.get(key) {
|
||||||
let (font, button_state) =
|
let (font, button_state) = if self.button_is_focused(state, key) {
|
||||||
if self.model.is_active(key) || self.button_is_focused(state, key) {
|
(self.font_active, 0)
|
||||||
(self.font_active, 0)
|
} else if state.show_context.is_some() || self.button_is_hovered(state, key) {
|
||||||
} else if self.button_is_hovered(state, key) {
|
(self.font_hovered, 1)
|
||||||
(self.font_hovered, 1)
|
} else if self.model.is_active(key) {
|
||||||
} else {
|
(self.font_active, 2)
|
||||||
(self.font_inactive, 2)
|
} else {
|
||||||
};
|
(self.font_inactive, 3)
|
||||||
|
};
|
||||||
|
|
||||||
let font = font.unwrap_or_else(crate::font::default);
|
|
||||||
let mut hasher = DefaultHasher::new();
|
let mut hasher = DefaultHasher::new();
|
||||||
text.hash(&mut hasher);
|
text.hash(&mut hasher);
|
||||||
font.hash(&mut hasher);
|
font.hash(&mut hasher);
|
||||||
|
|
@ -1171,47 +1174,15 @@ where
|
||||||
let bounds: Rectangle = layout.bounds();
|
let bounds: Rectangle = layout.bounds();
|
||||||
let button_amount = self.model.items.len();
|
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.
|
// Draw the background, if a background was defined.
|
||||||
if let Some(background) = appearance.background {
|
if let Some(background) = appearance.background {
|
||||||
renderer.fill_quad(
|
renderer.fill_quad(
|
||||||
renderer::Quad {
|
renderer::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
border: Border {
|
border: appearance.border,
|
||||||
radius: appearance.border_radius,
|
|
||||||
..Border::default()
|
|
||||||
},
|
|
||||||
shadow: Shadow::default(),
|
shadow: Shadow::default(),
|
||||||
},
|
},
|
||||||
bg_with_alpha(background),
|
background,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1222,7 +1193,7 @@ where
|
||||||
// Previous tab button
|
// Previous tab button
|
||||||
let mut background_appearance =
|
let mut background_appearance =
|
||||||
if self.on_activate.is_some() && Item::PrevButton == state.focused_item {
|
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 {
|
} else if self.on_activate.is_some() && Item::PrevButton == state.hovered {
|
||||||
Some(appearance.hover)
|
Some(appearance.hover)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1241,7 +1212,7 @@ where
|
||||||
},
|
},
|
||||||
background_appearance
|
background_appearance
|
||||||
.background
|
.background
|
||||||
.map_or(Background::Color(Color::TRANSPARENT), bg_with_alpha),
|
.unwrap_or(Background::Color(Color::TRANSPARENT)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1251,13 +1222,11 @@ where
|
||||||
style,
|
style,
|
||||||
cursor,
|
cursor,
|
||||||
viewport,
|
viewport,
|
||||||
apply_alpha(if state.buttons_offset == 0 {
|
if state.buttons_offset == 0 {
|
||||||
appearance.inactive.text_color
|
appearance.inactive.text_color
|
||||||
} else if let Item::PrevButton = state.focused_item {
|
|
||||||
appearance.focus.text_color
|
|
||||||
} else {
|
} else {
|
||||||
appearance.active.text_color
|
appearance.active.text_color
|
||||||
}),
|
},
|
||||||
Rectangle {
|
Rectangle {
|
||||||
x: tab_bounds.x + 8.0,
|
x: tab_bounds.x + 8.0,
|
||||||
y: tab_bounds.y + f32::from(self.button_height) / 4.0,
|
y: tab_bounds.y + f32::from(self.button_height) / 4.0,
|
||||||
|
|
@ -1272,7 +1241,7 @@ where
|
||||||
// Next tab button
|
// Next tab button
|
||||||
background_appearance =
|
background_appearance =
|
||||||
if self.on_activate.is_some() && Item::NextButton == state.focused_item {
|
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 {
|
} else if self.on_activate.is_some() && Item::NextButton == state.hovered {
|
||||||
Some(appearance.hover)
|
Some(appearance.hover)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1301,13 +1270,13 @@ where
|
||||||
style,
|
style,
|
||||||
cursor,
|
cursor,
|
||||||
viewport,
|
viewport,
|
||||||
apply_alpha(if self.next_tab_sensitive(state) {
|
if self.next_tab_sensitive(state) {
|
||||||
appearance.active.text_color
|
appearance.active.text_color
|
||||||
} else if let Item::NextButton = state.focused_item {
|
} else if let Item::NextButton = state.focused_item {
|
||||||
appearance.focus.text_color
|
appearance.active.text_color
|
||||||
} else {
|
} else {
|
||||||
appearance.inactive.text_color
|
appearance.inactive.text_color
|
||||||
}),
|
},
|
||||||
Rectangle {
|
Rectangle {
|
||||||
x: tab_bounds.x + 8.0,
|
x: tab_bounds.x + 8.0,
|
||||||
y: tab_bounds.y + f32::from(self.button_height) / 4.0,
|
y: tab_bounds.y + f32::from(self.button_height) / 4.0,
|
||||||
|
|
@ -1349,22 +1318,23 @@ where
|
||||||
|
|
||||||
let center_y = bounds.center_y();
|
let center_y = bounds.center_y();
|
||||||
|
|
||||||
let menu_open = !tree.children.is_empty()
|
let menu_open = || {
|
||||||
&& tree.children[0]
|
state.show_context == Some(key)
|
||||||
.state
|
&& !tree.children.is_empty()
|
||||||
.downcast_ref::<MenuBarState>()
|
&& tree.children[0]
|
||||||
.inner
|
.state
|
||||||
.with_data(|data| data.open);
|
.downcast_ref::<MenuBarState>()
|
||||||
|
.inner
|
||||||
|
.with_data(|data| data.open)
|
||||||
|
};
|
||||||
|
|
||||||
let key_is_active = self.model.is_active(key);
|
let key_is_active = self.model.is_active(key);
|
||||||
let key_is_hovered = self.button_is_hovered(state, key);
|
let key_is_focused = self.button_is_focused(state, key);
|
||||||
let key_has_context_menu_open = menu_open && state.show_context == Some(key);
|
let key_is_hovered = LazyCell::new(|| self.button_is_hovered(state, key));
|
||||||
let status_appearance = if self.button_is_focused(state, key) {
|
let status_appearance = if *key_is_hovered || menu_open() {
|
||||||
appearance.focus
|
appearance.hover
|
||||||
} else if key_is_active {
|
} else if key_is_active {
|
||||||
appearance.active
|
appearance.active
|
||||||
} else if key_is_hovered || key_has_context_menu_open {
|
|
||||||
appearance.hover
|
|
||||||
} else {
|
} else {
|
||||||
appearance.inactive
|
appearance.inactive
|
||||||
};
|
};
|
||||||
|
|
@ -1378,29 +1348,45 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
// Render the background of the button.
|
// 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.fill_quad(
|
||||||
renderer::Quad {
|
renderer::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
border: Border {
|
border: if key_is_focused {
|
||||||
radius: button_appearance.border_radius,
|
Border {
|
||||||
..Default::default()
|
width: 1.0,
|
||||||
|
color: appearance.active.text_color,
|
||||||
|
radius: button_appearance.border.radius,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
button_appearance.border
|
||||||
},
|
},
|
||||||
shadow: Shadow::default(),
|
shadow: Shadow::default(),
|
||||||
},
|
},
|
||||||
status_appearance
|
status_appearance
|
||||||
.background
|
.background
|
||||||
.map_or(Background::Color(Color::TRANSPARENT), bg_with_alpha),
|
.unwrap_or(Background::Color(Color::TRANSPARENT)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the bottom border defined for this button.
|
// Draw the active hint on tabs
|
||||||
if let Some((width, background)) = button_appearance.border_bottom {
|
if appearance.active_width > 0.0 {
|
||||||
let mut bounds = bounds;
|
|
||||||
bounds.y = bounds.y + bounds.height - width;
|
|
||||||
bounds.height = width;
|
|
||||||
|
|
||||||
let rad_0 = THEME.lock().unwrap().cosmic().corner_radii.radius_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.fill_quad(
|
||||||
renderer::Quad {
|
renderer::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
|
|
@ -1410,7 +1396,7 @@ where
|
||||||
},
|
},
|
||||||
shadow: Shadow::default(),
|
shadow: Shadow::default(),
|
||||||
},
|
},
|
||||||
bg_with_alpha(background.into()),
|
appearance.active.text_color,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1455,7 +1441,7 @@ where
|
||||||
style,
|
style,
|
||||||
cursor,
|
cursor,
|
||||||
viewport,
|
viewport,
|
||||||
apply_alpha(status_appearance.text_color),
|
status_appearance.text_color,
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width,
|
width,
|
||||||
height: width,
|
height: width,
|
||||||
|
|
@ -1470,7 +1456,7 @@ where
|
||||||
if key_is_active {
|
if key_is_active {
|
||||||
if let crate::theme::SegmentedButton::Control = self.style {
|
if let crate::theme::SegmentedButton::Control = self.style {
|
||||||
let mut image_bounds = bounds;
|
let mut image_bounds = bounds;
|
||||||
image_bounds.y = center_y - 16.0 / 2.0;
|
image_bounds.y = center_y - 8.0;
|
||||||
|
|
||||||
draw_icon::<Message>(
|
draw_icon::<Message>(
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -1478,7 +1464,7 @@ where
|
||||||
style,
|
style,
|
||||||
cursor,
|
cursor,
|
||||||
viewport,
|
viewport,
|
||||||
apply_alpha(status_appearance.text_color),
|
status_appearance.text_color,
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 16.0,
|
width: 16.0,
|
||||||
height: 16.0,
|
height: 16.0,
|
||||||
|
|
@ -1505,7 +1491,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.
|
||||||
|
|
@ -1527,7 +1513,7 @@ where
|
||||||
renderer.fill_paragraph(
|
renderer.fill_paragraph(
|
||||||
state.paragraphs[key].raw(),
|
state.paragraphs[key].raw(),
|
||||||
bounds.position(),
|
bounds.position(),
|
||||||
apply_alpha(status_appearance.text_color),
|
status_appearance.text_color,
|
||||||
Rectangle {
|
Rectangle {
|
||||||
x: bounds.x,
|
x: bounds.x,
|
||||||
width: bounds.width,
|
width: bounds.width,
|
||||||
|
|
@ -1546,7 +1532,7 @@ where
|
||||||
style,
|
style,
|
||||||
cursor,
|
cursor,
|
||||||
viewport,
|
viewport,
|
||||||
apply_alpha(status_appearance.text_color),
|
status_appearance.text_color,
|
||||||
close_button_bounds,
|
close_button_bounds,
|
||||||
self.close_icon.clone(),
|
self.close_icon.clone(),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ where
|
||||||
.button_padding([space_s, 0, space_s, 0])
|
.button_padding([space_s, 0, space_s, 0])
|
||||||
.button_spacing(space_xxs)
|
.button_spacing(space_xxs)
|
||||||
.style(crate::theme::SegmentedButton::Control)
|
.style(crate::theme::SegmentedButton::Control)
|
||||||
.font_active(Some(crate::font::semibold()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A selection of multiple choices appearing as a conjoined button.
|
/// A selection of multiple choices appearing as a conjoined button.
|
||||||
|
|
@ -55,5 +54,4 @@ where
|
||||||
.button_padding([space_s, 0, space_s, 0])
|
.button_padding([space_s, 0, space_s, 0])
|
||||||
.button_spacing(space_xxs)
|
.button_spacing(space_xxs)
|
||||||
.style(crate::theme::SegmentedButton::Control)
|
.style(crate::theme::SegmentedButton::Control)
|
||||||
.font_active(Some(crate::font::semibold()))
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ where
|
||||||
.button_height(44)
|
.button_height(44)
|
||||||
.button_padding([space_s, space_xs, space_s, space_xs])
|
.button_padding([space_s, space_xs, space_s, space_xs])
|
||||||
.style(crate::theme::SegmentedButton::TabBar)
|
.style(crate::theme::SegmentedButton::TabBar)
|
||||||
.font_active(Some(crate::font::semibold()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of tabs for developing a tabbed interface.
|
/// A collection of tabs for developing a tabbed interface.
|
||||||
|
|
@ -52,5 +51,4 @@ where
|
||||||
.button_height(44)
|
.button_height(44)
|
||||||
.button_padding([space_s, space_xs, space_s, space_xs])
|
.button_padding([space_s, space_xs, space_s, space_xs])
|
||||||
.style(crate::theme::SegmentedButton::TabBar)
|
.style(crate::theme::SegmentedButton::TabBar)
|
||||||
.font_active(Some(crate::font::semibold()))
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue