improv: use current design for nav bar toggle button

This commit is contained in:
Michael Aaron Murphy 2023-01-09 22:59:39 +01:00 committed by Michael Murphy
parent c4bd0fa3d8
commit 352bf8e401
7 changed files with 81 additions and 79 deletions

View file

@ -16,7 +16,7 @@ use cosmic::{
iced_native::window, iced_native::window,
theme::{self, Theme}, theme::{self, Theme},
widget::{ widget::{
button, header_bar, nav_bar, nav_button, button, header_bar, nav_bar, nav_bar_toggle,
rectangle_tracker::{rectangle_tracker_subscription, RectangleTracker, RectangleUpdate}, rectangle_tracker::{rectangle_tracker_subscription, RectangleTracker, RectangleUpdate},
scrollable, segmented_button, settings, toggler, IconSource, scrollable, segmented_button, settings, toggler, IconSource,
}, },
@ -284,7 +284,7 @@ impl Application for Window {
.on_close(Message::Close) .on_close(Message::Close)
.on_drag(Message::Drag) .on_drag(Message::Drag)
.start( .start(
nav_button("Settings") nav_bar_toggle()
.on_nav_bar_toggled(nav_bar_message) .on_nav_bar_toggled(nav_bar_message)
.nav_bar_active(nav_bar_toggled) .nav_bar_active(nav_bar_toggled)
.into(), .into(),

View file

@ -7,12 +7,11 @@ use cosmic::{
event::{self, Event}, event::{self, Event},
keyboard, Application, Command, Length, Subscription, keyboard, Application, Command, Length, Subscription,
}, },
iced_native,
iced_native::{subscription, window}, iced_native::{subscription, window},
iced_winit::window::{close, drag, minimize, toggle_maximize}, iced_winit::window::{close, drag, minimize, toggle_maximize},
theme::{self, Theme}, theme::{self, Theme},
widget::{ widget::{
header_bar, icon, list, nav_bar, nav_button, scrollable, segmented_button, settings, header_bar, icon, list, nav_bar, nav_bar_toggle, scrollable, segmented_button, settings,
IconSource, IconSource,
}, },
Element, ElementExt, Element, ElementExt,
@ -427,7 +426,7 @@ impl Application for Window {
.on_close(Message::Close) .on_close(Message::Close)
.on_drag(Message::Drag) .on_drag(Message::Drag)
.start( .start(
nav_button("Settings") nav_bar_toggle()
.on_nav_bar_toggled(nav_bar_message) .on_nav_bar_toggled(nav_bar_message)
.nav_bar_active(nav_bar_toggled) .nav_bar_active(nav_bar_toggled)
.into(), .into(),

4
res/sidebar-active.svg Normal file
View file

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 4C10 3.446 9.554 3 9 3H4C3.446 3 3 3.446 3 4C3 4.554 3.446 5 4 5H9C9.554 5 10 4.554 10 4ZM7 8C7 7.446 6.554 7 6 7H4C3.446 7 3 7.446 3 8C3 8.554 3.446 9 4 9H6C6.554 9 7 8.554 7 8ZM10 12C10 11.446 9.554 11 9 11H4C3.446 11 3 11.446 3 12C3 12.554 3.446 13 4 13H9C9.554 13 10 12.554 10 12Z" fill="#94EBEB"/>
<path d="M12 5L9 8L12 11" stroke="#94EBEB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 528 B

View file

@ -23,7 +23,8 @@ pub enum Handle {
pub enum IconSource<'a> { pub enum IconSource<'a> {
Path(Cow<'a, Path>), Path(Cow<'a, Path>),
Name(Cow<'a, str>), Name(Cow<'a, str>),
Embedded(Image), Embedded(image::Handle),
EmbeddedSvg(svg::Handle),
} }
impl<'a> IconSource<'a> { impl<'a> IconSource<'a> {
@ -32,8 +33,8 @@ impl<'a> IconSource<'a> {
pub fn load(&self, size: u16, theme: Option<&str>, svg: bool) -> Handle { pub fn load(&self, size: u16, theme: Option<&str>, svg: bool) -> Handle {
let name_path_buffer: Option<PathBuf>; let name_path_buffer: Option<PathBuf>;
let icon: Option<&Path> = match self { let icon: Option<&Path> = match self {
IconSource::Path(path) => Some(path), IconSource::Path(ref path) => Some(path),
IconSource::Name(name) => { IconSource::Name(ref name) => {
let icon = crate::settings::DEFAULT_ICON_THEME.with(|default_theme| { let icon = crate::settings::DEFAULT_ICON_THEME.with(|default_theme| {
let default_theme: &str = &default_theme.borrow(); let default_theme: &str = &default_theme.borrow();
freedesktop_icons::lookup(name) freedesktop_icons::lookup(name)
@ -54,7 +55,8 @@ impl<'a> IconSource<'a> {
name_path_buffer.as_deref() name_path_buffer.as_deref()
} }
IconSource::Embedded(_) => unimplemented!(), IconSource::Embedded(handle) => return Handle::Image(handle.clone()),
IconSource::EmbeddedSvg(handle) => return Handle::Svg(handle.clone()),
}; };
let is_svg = svg let is_svg = svg
@ -116,9 +118,15 @@ impl<'a> From<&'a str> for IconSource<'a> {
} }
} }
impl<'a> From<Image> for IconSource<'a> { impl From<image::Handle> for IconSource<'static> {
fn from(value: Image) -> Self { fn from(handle: image::Handle) -> Self {
Self::Embedded(value) Self::Embedded(handle)
}
}
impl From<svg::Handle> for IconSource<'static> {
fn from(handle: svg::Handle) -> Self {
Self::EmbeddedSvg(handle)
} }
} }
@ -158,8 +166,8 @@ pub fn icon<'a>(source: impl Into<IconSource<'a>>, size: u16) -> Icon<'a> {
impl<'a> Icon<'a> { impl<'a> Icon<'a> {
#[must_use] #[must_use]
fn into_element<Message: 'static>(self) -> Element<'a, Message> { fn into_element<Message: 'static>(self) -> Element<'a, Message> {
if let IconSource::Embedded(mut image) = self.source { if let IconSource::Embedded(image) = self.source {
image = image let mut image = iced::widget::image(image)
.width(self.width.unwrap_or(Length::Units(self.size))) .width(self.width.unwrap_or(Length::Units(self.size)))
.height(self.height.unwrap_or(Length::Units(self.size))); .height(self.height.unwrap_or(Length::Units(self.size)));
if let Some(content_fit) = self.content_fit { if let Some(content_fit) = self.content_fit {

View file

@ -16,8 +16,8 @@ pub use self::list::*;
pub mod nav_bar; pub mod nav_bar;
pub use nav_bar::nav_bar; pub use nav_bar::nav_bar;
pub mod nav_button; pub mod nav_bar_toggle;
pub use self::nav_button::{nav_button, NavButton}; pub use self::nav_bar_toggle::{nav_bar_toggle, NavBarToggle};
mod toggler; mod toggler;
pub use toggler::toggler; pub use toggler::toggler;

View file

@ -0,0 +1,54 @@
// Copyright 2022 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0
use crate::{theme, Element};
use apply::Apply;
use derive_setters::Setters;
use iced::Length;
use super::IconSource;
#[derive(Setters)]
pub struct NavBarToggle<Message> {
nav_bar_active: bool,
#[setters(strip_option)]
on_nav_bar_toggled: Option<Message>,
}
#[must_use]
pub fn nav_bar_toggle<Message>() -> NavBarToggle<Message> {
NavBarToggle {
nav_bar_active: false,
on_nav_bar_toggled: None,
}
}
impl<Message: 'static + Clone> From<NavBarToggle<Message>> for Element<'static, Message> {
fn from(nav_bar_toggle: NavBarToggle<Message>) -> Self {
let mut widget = super::icon(
if nav_bar_toggle.nav_bar_active {
IconSource::EmbeddedSvg(iced::widget::svg::Handle::from_memory(
&include_bytes!("../../res/sidebar-active.svg")[..],
))
} else {
IconSource::Name("open-menu-symbolic".into())
},
16,
)
.style(theme::Svg::SymbolicActive)
.apply(iced::widget::container)
.apply(iced::widget::button)
.padding([8, 16, 8, 16])
.style(theme::Button::Text);
if let Some(message) = nav_bar_toggle.on_nav_bar_toggled {
widget = widget.on_press(message);
}
widget
.apply(iced::widget::container)
.center_y()
.height(Length::Fill)
.into()
}
}

View file

@ -1,63 +0,0 @@
// Copyright 2022 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0
use crate::{theme, Element};
use apply::Apply;
use derive_setters::Setters;
use iced::{alignment::Vertical, Length};
#[derive(Setters)]
pub struct NavButton<'a, Message> {
title: &'a str,
nav_bar_active: bool,
#[setters(strip_option)]
on_nav_bar_toggled: Option<Message>,
}
#[must_use]
pub fn nav_button<Message>(title: &str) -> NavButton<Message> {
NavButton {
title,
nav_bar_active: false,
on_nav_bar_toggled: None,
}
}
impl<'a, Message: 'static + Clone> From<NavButton<'a, Message>> for Element<'a, Message> {
fn from(nav_button: NavButton<'a, Message>) -> Self {
let text = iced::widget::text(&nav_button.title)
.style(theme::Text::Accent)
.vertical_alignment(Vertical::Center)
.width(Length::Shrink)
.height(Length::Fill);
let icon = super::icon(
if nav_button.nav_bar_active {
"go-previous-symbolic"
} else {
"go-next-symbolic"
},
24,
)
.force_svg(true)
.style(theme::Svg::SymbolicActive)
.width(Length::Units(24))
.height(Length::Fill);
let mut widget = iced::widget::row!(text, crate::widget::vertical_rule(4), icon)
.padding(4)
.spacing(4)
.apply(iced::widget::button)
.style(theme::Button::Secondary);
if let Some(message) = nav_button.on_nav_bar_toggled.clone() {
widget = widget.on_press(message);
}
widget
.apply(iced::widget::container)
.center_y()
.height(Length::Fill)
.into()
}
}