diff --git a/src/theme/style/segmented_button.rs b/src/theme/style/segmented_button.rs index 5306b3bf..b9863c88 100644 --- a/src/theme/style/segmented_button.rs +++ b/src/theme/style/segmented_button.rs @@ -18,6 +18,8 @@ pub enum SegmentedButton { Control, /// Navigation bar style NavBar, + /// File browser + FileNav, /// Or implement any custom theme of your liking. Custom(Box Appearance>), } @@ -69,7 +71,7 @@ impl StyleSheet for Theme { } } - SegmentedButton::NavBar => Appearance { + SegmentedButton::NavBar | SegmentedButton::FileNav => Appearance { active_width: 0.0, ..horizontal::tab_bar(cosmic, container) }, @@ -124,7 +126,7 @@ impl StyleSheet for Theme { } } - SegmentedButton::NavBar => Appearance { + SegmentedButton::NavBar | SegmentedButton::FileNav => Appearance { active_width: 0.0, ..vertical::tab_bar(cosmic, container) }, diff --git a/src/widget/segmented_button/horizontal.rs b/src/widget/segmented_button/horizontal.rs index 724ded96..966f3a7c 100644 --- a/src/widget/segmented_button/horizontal.rs +++ b/src/widget/segmented_button/horizontal.rs @@ -67,7 +67,7 @@ where / num as f32; } - let segmetned_control = matches!(self.style, crate::theme::SegmentedButton::Control); + let is_control = matches!(self.style, crate::theme::SegmentedButton::Control); Box::new( self.model @@ -93,7 +93,7 @@ where let button_bounds = ItemBounds::Button(key, layout_bounds); let mut divider = None; - if self.dividers && segmetned_control && nth + 1 < num { + if self.dividers && is_control && nth + 1 < num { divider = Some(ItemBounds::Divider( Rectangle { width: 1.0, @@ -143,7 +143,7 @@ where let max_size = limits.height(Length::Fixed(max_height)).resolve( Length::Fill, max_height, - Size::new(f32::MAX, max_height), + Size::new(limits.max().width, max_height), ); let mut visible_width = 0.0; @@ -152,7 +152,7 @@ where for (button_size, _actual_size) in &state.internal_layout { visible_width += button_size.width; - if max_size.width >= visible_width { + if max_size.width - spacing >= visible_width { state.buttons_visible += 1; } else { visible_width = max_size.width - max_height; diff --git a/src/widget/segmented_button/widget.rs b/src/widget/segmented_button/widget.rs index d21f409b..685d3b0e 100644 --- a/src/widget/segmented_button/widget.rs +++ b/src/widget/segmented_button/widget.rs @@ -619,20 +619,19 @@ where for key in self.model.order.iter().copied() { if let Some(text) = self.model.text.get(key) { - let (font, button_state) = if self.button_is_focused(state, key) { - (self.font_active, 0) + let font = if self.button_is_focused(state, key) { + self.font_active } else if state.show_context.is_some() || self.button_is_hovered(state, key) { - (self.font_hovered, 1) + self.font_hovered } else if self.model.is_active(key) { - (self.font_active, 2) + self.font_active } else { - (self.font_inactive, 3) + self.font_inactive }; let mut hasher = DefaultHasher::new(); text.hash(&mut hasher); font.hash(&mut hasher); - button_state.hash(&mut hasher); let text_hash = hasher.finish(); if let Some(prev_hash) = state.text_hashes.insert(key, text_hash) { @@ -1293,6 +1292,15 @@ where ); } + let rad_0 = THEME.lock().unwrap().cosmic().corner_radii.radius_0; + + let divider_background = Background::Color( + crate::theme::active() + .cosmic() + .primary_component_divider() + .into(), + ); + // Draw each of the items in the widget. let mut nth = 0; self.variant_bounds(state, bounds).for_each(move |item| { @@ -1337,7 +1345,7 @@ where let key_is_active = self.model.is_active(key); let key_is_focused = state.focused_visible && self.button_is_focused(state, key); let key_is_hovered = self.button_is_hovered(state, key); - let status_appearance = if self.button_is_pressed(state, key) && key_is_hovered { + let status_appearance = if self.button_is_pressed(state, key) { appearance.pressed } else if key_is_hovered || menu_open() { appearance.hover @@ -1355,11 +1363,87 @@ where status_appearance.middle }; + // Draw the active hint on tabs + if appearance.active_width > 0.0 { + let active_width = if key_is_active { + appearance.active_width + } else { + 1.0 + }; + + renderer.fill_quad( + renderer::Quad { + bounds: if Self::VERTICAL { + Rectangle { + x: bounds.x + bounds.width - active_width, + width: active_width, + ..bounds + } + } else { + Rectangle { + y: bounds.y + bounds.height - active_width, + height: active_width, + ..bounds + } + }, + border: Border { + radius: rad_0.into(), + ..Default::default() + }, + shadow: Shadow::default(), + }, + appearance.active.text_color, + ); + } + + let original_bounds = bounds; + bounds.x += f32::from(self.button_padding[0]); + bounds.width -= f32::from(self.button_padding[0]) - f32::from(self.button_padding[2]); + let mut indent_padding = 0.0; + + // Adjust bounds by indent + if let Some(indent) = self.model.indent(key) { + if indent > 0 { + let adjustment = f32::from(indent) * f32::from(self.indent_spacing); + bounds.x += adjustment; + bounds.width -= adjustment; + + // Draw indent line + if let crate::theme::SegmentedButton::FileNav = self.style { + if indent > 1 { + indent_padding = 7.0; + renderer.fill_quad( + renderer::Quad { + bounds: Rectangle { + x: bounds.x - self.indent_spacing as f32 + indent_padding, + width: 1.0, + ..bounds + }, + border: Border { + radius: rad_0.into(), + ..Default::default() + }, + shadow: Shadow::default(), + }, + divider_background, + ); + indent_padding += 4.0; + } + } + } + } + // Render the background of the button. if key_is_focused || status_appearance.background.is_some() { renderer.fill_quad( renderer::Quad { - bounds, + bounds: Rectangle { + x: bounds.x - f32::from(self.button_padding[0]) + indent_padding, + width: bounds.width + f32::from(self.button_padding[0]) + - f32::from(self.button_padding[2]) + - indent_padding, + ..bounds + }, border: if key_is_focused { Border { width: 1.0, @@ -1377,49 +1461,6 @@ where ); } - // 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, - border: Border { - radius: rad_0.into(), - ..Default::default() - }, - shadow: Shadow::default(), - }, - appearance.active.text_color, - ); - } - - let original_bounds = bounds; - - bounds.x += f32::from(self.button_padding[0]); - bounds.width -= f32::from(self.button_padding[0]) - f32::from(self.button_padding[2]); - - // Adjust bounds by indent - if let Some(indent) = self.model.indent(key) { - let adjustment = f32::from(indent) * f32::from(self.indent_spacing); - bounds.x += adjustment; - bounds.width -= adjustment; - } - // Align contents of the button to the requested `button_alignment`. { let actual_width = state.internal_layout[nth].1.width;