From 5949eb8d89824851f79724ff9e1d5dab9a00ee77 Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Sat, 8 Oct 2022 21:38:30 -0700 Subject: [PATCH] Initial implementation of Expander widget --- examples/cosmic/src/main.rs | 25 ++++++++++-- src/widget/expander.rs | 81 +++++++++++++++++++++++++++++++++++++ src/widget/mod.rs | 5 ++- src/widget/navbar.rs | 8 ++-- 4 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 src/widget/expander.rs diff --git a/examples/cosmic/src/main.rs b/examples/cosmic/src/main.rs index 3464f896..d900baec 100644 --- a/examples/cosmic/src/main.rs +++ b/examples/cosmic/src/main.rs @@ -7,7 +7,7 @@ use cosmic::{ list_view, nav_button, toggler, - HeaderBar, nav_bar_style, + HeaderBar, nav_bar_style, Expander, ExpanderMsg, }, settings, iced::{self, theme, Alignment, Application, Color, Command, Element, Length, Theme}, @@ -41,6 +41,7 @@ pub fn main() -> cosmic::iced::Result { #[derive(Default)] struct Window { headerbar: HeaderBar, + expander: Expander, page: u8, debug: bool, theme: Theme, @@ -61,7 +62,8 @@ enum Message { CheckboxToggled(bool), TogglerToggled(bool), PickListSelected(&'static str), - Window(WindowMsg) + Window(WindowMsg), + Expander(ExpanderMsg) } impl From for Message { @@ -70,6 +72,12 @@ impl From for Message { } } +impl From for Message { + fn from(message: ExpanderMsg) -> Self { + Self::Expander(message) + } +} + impl Application for Window { type Executor = iced::executor::Default; type Flags = (); @@ -109,6 +117,9 @@ impl Application for Window { WindowMsg::Minimize => {} WindowMsg::Maximize => {} } + Message::Expander(msg) => match msg { + ExpanderMsg::Expand => self.expander.expanded = !self.expander.expanded, + } } iced::Command::none() @@ -116,6 +127,7 @@ impl Application for Window { fn view(&self) -> Element { let mut header = self.headerbar.render(); + // let expander = self.expander.render(); if self.debug { header = header.explain(Color::WHITE); } @@ -137,7 +149,14 @@ impl Application for Window { , nav_button!("system-software-update", "OS Upgrade & Recovery", condensed) .on_press(Message::Page(2)) - .style(if self.page == 2 { theme::Button::Primary } else { theme::Button::Text }) + .style(if self.page == 2 { theme::Button::Primary } else { theme::Button::Text }), + self.expander.render( + vec![ + text("Content").into(), + text("Content 2").into(), + text("Content 3").into() + ] + ), ] .active(self.headerbar.sidebar_active) .condensed(condensed) diff --git a/src/widget/expander.rs b/src/widget/expander.rs new file mode 100644 index 00000000..450b8d11 --- /dev/null +++ b/src/widget/expander.rs @@ -0,0 +1,81 @@ +use std::vec; + +use apply::Apply; +use iced::{ + Element, + Length, + widget::{ + row, + horizontal_space, button, container, text, Column + }, alignment::{Vertical, Horizontal}, theme +}; +use iced_native::widget::column; + +#[derive(Default)] +pub struct Expander +{ + pub expanded: bool +} + +#[derive(Clone, Copy, Debug)] +pub enum ExpanderMsg { + Expand, +} + +impl Expander { + pub fn new() -> Self { + Self::default() + } + + pub fn render<'a, T>(&self, children: Vec>) -> Element<'a, T> + where T: Clone + From + 'static + { + let title = text("Title") + .size(18) + .vertical_alignment(Vertical::Center) + .horizontal_alignment(Horizontal::Center) + .into(); + let subtitle = iced::widget::text("Subtitle") + .size(14) + .vertical_alignment(Vertical::Center) + .horizontal_alignment(Horizontal::Center) + .into(); + let header = column( + vec![title, subtitle] + ).into(); + let space = horizontal_space(Length::Fill).into(); + let icon = super::icon( + if self.expanded { + "go-down-symbolic" + } else { + "go-next-symbolic" + }, + 16 + ) + .apply(button) + .on_press(T::from(ExpanderMsg::Expand)) + .width(Length::Units(25)) + .into(); + + container( + column( + if self.expanded { + vec![ + row(vec![header, space, icon]).into(), + container( + Column::with_children(children) + ) + .style(theme::Container::Transparent) + .padding(5) + .into() + ] + } else { + vec![row(vec![header, space, icon]).into()] + } + ) + .padding(5) + ) + .style(theme::Container::Box) + .into() + } +} \ No newline at end of file diff --git a/src/widget/mod.rs b/src/widget/mod.rs index e612af92..ca6aca30 100644 --- a/src/widget/mod.rs +++ b/src/widget/mod.rs @@ -20,4 +20,7 @@ mod toggler; pub use toggler::*; mod scrollable; -pub use scrollable::*; \ No newline at end of file +pub use scrollable::*; + +mod expander; +pub use expander::*; diff --git a/src/widget/navbar.rs b/src/widget/navbar.rs index 42fff10f..d8f04d12 100644 --- a/src/widget/navbar.rs +++ b/src/widget/navbar.rs @@ -321,14 +321,14 @@ where Renderer: iced_native::Renderer + 'a, Renderer::Theme: StyleSheet, { - fn from(row: NavBar<'a, Message, Renderer>) -> Self { - Self::new(row) + fn from(navbar: NavBar<'a, Message, Renderer>) -> Self { + Self::new(navbar) } } -/// Creates a [Row`] with the given children. +/// Creates a [NavBar`] with the given children. /// -/// [`Row`]: widget::Row +/// [`NavBar`]: widget::NavBar #[macro_export] macro_rules! navbar { ($($x:expr),+ $(,)?) => (