Initial implementation of Expander widget

This commit is contained in:
Eduardo Flores 2022-10-08 21:38:30 -07:00 committed by Michael Murphy
parent b092157f26
commit 5949eb8d89
4 changed files with 111 additions and 8 deletions

View file

@ -7,7 +7,7 @@ use cosmic::{
list_view, list_view,
nav_button, nav_button,
toggler, toggler,
HeaderBar, nav_bar_style, HeaderBar, nav_bar_style, Expander, ExpanderMsg,
}, },
settings, settings,
iced::{self, theme, Alignment, Application, Color, Command, Element, Length, Theme}, iced::{self, theme, Alignment, Application, Color, Command, Element, Length, Theme},
@ -41,6 +41,7 @@ pub fn main() -> cosmic::iced::Result {
#[derive(Default)] #[derive(Default)]
struct Window { struct Window {
headerbar: HeaderBar, headerbar: HeaderBar,
expander: Expander,
page: u8, page: u8,
debug: bool, debug: bool,
theme: Theme, theme: Theme,
@ -61,7 +62,8 @@ enum Message {
CheckboxToggled(bool), CheckboxToggled(bool),
TogglerToggled(bool), TogglerToggled(bool),
PickListSelected(&'static str), PickListSelected(&'static str),
Window(WindowMsg) Window(WindowMsg),
Expander(ExpanderMsg)
} }
impl From<WindowMsg> for Message { impl From<WindowMsg> for Message {
@ -70,6 +72,12 @@ impl From<WindowMsg> for Message {
} }
} }
impl From<ExpanderMsg> for Message {
fn from(message: ExpanderMsg) -> Self {
Self::Expander(message)
}
}
impl Application for Window { impl Application for Window {
type Executor = iced::executor::Default; type Executor = iced::executor::Default;
type Flags = (); type Flags = ();
@ -109,6 +117,9 @@ impl Application for Window {
WindowMsg::Minimize => {} WindowMsg::Minimize => {}
WindowMsg::Maximize => {} WindowMsg::Maximize => {}
} }
Message::Expander(msg) => match msg {
ExpanderMsg::Expand => self.expander.expanded = !self.expander.expanded,
}
} }
iced::Command::none() iced::Command::none()
@ -116,6 +127,7 @@ impl Application for Window {
fn view(&self) -> Element<Message> { fn view(&self) -> Element<Message> {
let mut header = self.headerbar.render(); let mut header = self.headerbar.render();
// let expander = self.expander.render();
if self.debug { if self.debug {
header = header.explain(Color::WHITE); header = header.explain(Color::WHITE);
} }
@ -137,7 +149,14 @@ impl Application for Window {
, ,
nav_button!("system-software-update", "OS Upgrade & Recovery", condensed) nav_button!("system-software-update", "OS Upgrade & Recovery", condensed)
.on_press(Message::Page(2)) .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) .active(self.headerbar.sidebar_active)
.condensed(condensed) .condensed(condensed)

81
src/widget/expander.rs Normal file
View file

@ -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>>) -> Element<'a, T>
where T: Clone + From<ExpanderMsg> + '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()
}
}

View file

@ -20,4 +20,7 @@ mod toggler;
pub use toggler::*; pub use toggler::*;
mod scrollable; mod scrollable;
pub use scrollable::*; pub use scrollable::*;
mod expander;
pub use expander::*;

View file

@ -321,14 +321,14 @@ where
Renderer: iced_native::Renderer + 'a, Renderer: iced_native::Renderer + 'a,
Renderer::Theme: StyleSheet, Renderer::Theme: StyleSheet,
{ {
fn from(row: NavBar<'a, Message, Renderer>) -> Self { fn from(navbar: NavBar<'a, Message, Renderer>) -> Self {
Self::new(row) 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_export]
macro_rules! navbar { macro_rules! navbar {
($($x:expr),+ $(,)?) => ( ($($x:expr),+ $(,)?) => (