diff --git a/src/theme/style/segmented_button.rs b/src/theme/style/segmented_button.rs index 4f7b4a4f..3f5d92db 100644 --- a/src/theme/style/segmented_button.rs +++ b/src/theme/style/segmented_button.rs @@ -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 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 + } +} diff --git a/src/widget/nav_bar.rs b/src/widget/nav_bar.rs index 6923472a..1ae4005d 100644 --- a/src/widget/nav_bar.rs +++ b/src/widget/nav_bar.rs @@ -149,7 +149,7 @@ impl<'a, Message: Clone + 'static> From> .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) diff --git a/src/widget/segmented_button/horizontal.rs b/src/widget/segmented_button/horizontal.rs index ccf4c8ae..724ded96 100644 --- a/src/widget/segmented_button/horizontal.rs +++ b/src/widget/segmented_button/horizontal.rs @@ -36,6 +36,8 @@ where Model: Selectable, SelectionMode: Default, { + const VERTICAL: bool = false; + fn variant_appearance( theme: &crate::Theme, style: &crate::theme::SegmentedButton, diff --git a/src/widget/segmented_button/style.rs b/src/widget/segmented_button/style.rs index 102b3686..f09a74a2 100644 --- a/src/widget/segmented_button/style.rs +++ b/src/widget/segmented_button/style.rs @@ -1,31 +1,24 @@ // Copyright 2022 System76 // 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, - 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. diff --git a/src/widget/segmented_button/vertical.rs b/src/widget/segmented_button/vertical.rs index 3f5d5645..ce9f50fe 100644 --- a/src/widget/segmented_button/vertical.rs +++ b/src/widget/segmented_button/vertical.rs @@ -36,6 +36,8 @@ where Model: Selectable, SelectionMode: Default, { + const VERTICAL: bool = true; + fn variant_appearance( theme: &crate::Theme, style: &crate::theme::SegmentedButton, diff --git a/src/widget/segmented_button/widget.rs b/src/widget/segmented_button/widget.rs index 1c92d0b2..620c8439 100644 --- a/src/widget/segmented_button/widget.rs +++ b/src/widget/segmented_button/widget.rs @@ -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, + pub(super) font_active: crate::font::Font, /// Desired font for hovered tabs. - pub(super) font_hovered: Option, + pub(super) font_hovered: crate::font::Font, /// Desired font for inactive tabs. - pub(super) font_inactive: Option, + 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::() - .inner - .with_data(|data| data.open); + let menu_open = || { + state.show_context == Some(key) + && !tree.children.is_empty() + && tree.children[0] + .state + .downcast_ref::() + .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::( 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(), ); diff --git a/src/widget/segmented_control.rs b/src/widget/segmented_control.rs index 9dbcfc51..0c213b2c 100644 --- a/src/widget/segmented_control.rs +++ b/src/widget/segmented_control.rs @@ -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())) } diff --git a/src/widget/tab_bar.rs b/src/widget/tab_bar.rs index b3def5ca..4f4c6149 100644 --- a/src/widget/tab_bar.rs +++ b/src/widget/tab_bar.rs @@ -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())) }