From 352bf8e401392cac651b43b76503d5ac884f37d0 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Mon, 9 Jan 2023 22:59:39 +0100 Subject: [PATCH] improv: use current design for nav bar toggle button --- examples/cosmic-sctk/src/window.rs | 4 +- examples/cosmic/src/window.rs | 5 +-- res/sidebar-active.svg | 4 ++ src/widget/icon.rs | 26 +++++++----- src/widget/mod.rs | 4 +- src/widget/nav_bar_toggle.rs | 54 +++++++++++++++++++++++++ src/widget/nav_button.rs | 63 ------------------------------ 7 files changed, 81 insertions(+), 79 deletions(-) create mode 100644 res/sidebar-active.svg create mode 100644 src/widget/nav_bar_toggle.rs delete mode 100644 src/widget/nav_button.rs diff --git a/examples/cosmic-sctk/src/window.rs b/examples/cosmic-sctk/src/window.rs index e1a2a844..b20b6be0 100644 --- a/examples/cosmic-sctk/src/window.rs +++ b/examples/cosmic-sctk/src/window.rs @@ -16,7 +16,7 @@ use cosmic::{ iced_native::window, theme::{self, Theme}, widget::{ - button, header_bar, nav_bar, nav_button, + button, header_bar, nav_bar, nav_bar_toggle, rectangle_tracker::{rectangle_tracker_subscription, RectangleTracker, RectangleUpdate}, scrollable, segmented_button, settings, toggler, IconSource, }, @@ -284,7 +284,7 @@ impl Application for Window { .on_close(Message::Close) .on_drag(Message::Drag) .start( - nav_button("Settings") + nav_bar_toggle() .on_nav_bar_toggled(nav_bar_message) .nav_bar_active(nav_bar_toggled) .into(), diff --git a/examples/cosmic/src/window.rs b/examples/cosmic/src/window.rs index 88f76bd6..18e90aae 100644 --- a/examples/cosmic/src/window.rs +++ b/examples/cosmic/src/window.rs @@ -7,12 +7,11 @@ use cosmic::{ event::{self, Event}, keyboard, Application, Command, Length, Subscription, }, - iced_native, iced_native::{subscription, window}, iced_winit::window::{close, drag, minimize, toggle_maximize}, theme::{self, Theme}, 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, }, Element, ElementExt, @@ -427,7 +426,7 @@ impl Application for Window { .on_close(Message::Close) .on_drag(Message::Drag) .start( - nav_button("Settings") + nav_bar_toggle() .on_nav_bar_toggled(nav_bar_message) .nav_bar_active(nav_bar_toggled) .into(), diff --git a/res/sidebar-active.svg b/res/sidebar-active.svg new file mode 100644 index 00000000..1bfcea78 --- /dev/null +++ b/res/sidebar-active.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/widget/icon.rs b/src/widget/icon.rs index f6709861..af85a677 100644 --- a/src/widget/icon.rs +++ b/src/widget/icon.rs @@ -23,7 +23,8 @@ pub enum Handle { pub enum IconSource<'a> { Path(Cow<'a, Path>), Name(Cow<'a, str>), - Embedded(Image), + Embedded(image::Handle), + EmbeddedSvg(svg::Handle), } impl<'a> IconSource<'a> { @@ -32,8 +33,8 @@ impl<'a> IconSource<'a> { pub fn load(&self, size: u16, theme: Option<&str>, svg: bool) -> Handle { let name_path_buffer: Option; let icon: Option<&Path> = match self { - IconSource::Path(path) => Some(path), - IconSource::Name(name) => { + IconSource::Path(ref path) => Some(path), + IconSource::Name(ref name) => { let icon = crate::settings::DEFAULT_ICON_THEME.with(|default_theme| { let default_theme: &str = &default_theme.borrow(); freedesktop_icons::lookup(name) @@ -54,7 +55,8 @@ impl<'a> IconSource<'a> { 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 @@ -116,9 +118,15 @@ impl<'a> From<&'a str> for IconSource<'a> { } } -impl<'a> From for IconSource<'a> { - fn from(value: Image) -> Self { - Self::Embedded(value) +impl From for IconSource<'static> { + fn from(handle: image::Handle) -> Self { + Self::Embedded(handle) + } +} + +impl From for IconSource<'static> { + fn from(handle: svg::Handle) -> Self { + Self::EmbeddedSvg(handle) } } @@ -158,8 +166,8 @@ pub fn icon<'a>(source: impl Into>, size: u16) -> Icon<'a> { impl<'a> Icon<'a> { #[must_use] fn into_element(self) -> Element<'a, Message> { - if let IconSource::Embedded(mut image) = self.source { - image = image + if let IconSource::Embedded(image) = self.source { + let mut image = iced::widget::image(image) .width(self.width.unwrap_or(Length::Units(self.size))) .height(self.height.unwrap_or(Length::Units(self.size))); if let Some(content_fit) = self.content_fit { diff --git a/src/widget/mod.rs b/src/widget/mod.rs index e5c1ed74..05a9ff01 100644 --- a/src/widget/mod.rs +++ b/src/widget/mod.rs @@ -16,8 +16,8 @@ pub use self::list::*; pub mod nav_bar; pub use nav_bar::nav_bar; -pub mod nav_button; -pub use self::nav_button::{nav_button, NavButton}; +pub mod nav_bar_toggle; +pub use self::nav_bar_toggle::{nav_bar_toggle, NavBarToggle}; mod toggler; pub use toggler::toggler; diff --git a/src/widget/nav_bar_toggle.rs b/src/widget/nav_bar_toggle.rs new file mode 100644 index 00000000..4871d287 --- /dev/null +++ b/src/widget/nav_bar_toggle.rs @@ -0,0 +1,54 @@ +// Copyright 2022 System76 +// 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 { + nav_bar_active: bool, + #[setters(strip_option)] + on_nav_bar_toggled: Option, +} + +#[must_use] +pub fn nav_bar_toggle() -> NavBarToggle { + NavBarToggle { + nav_bar_active: false, + on_nav_bar_toggled: None, + } +} + +impl From> for Element<'static, Message> { + fn from(nav_bar_toggle: NavBarToggle) -> 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() + } +} diff --git a/src/widget/nav_button.rs b/src/widget/nav_button.rs deleted file mode 100644 index ea5f5963..00000000 --- a/src/widget/nav_button.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2022 System76 -// 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, -} - -#[must_use] -pub fn nav_button(title: &str) -> NavButton { - NavButton { - title, - nav_bar_active: false, - on_nav_bar_toggled: None, - } -} - -impl<'a, Message: 'static + Clone> From> 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() - } -}