diff --git a/src/app/context_drawer.rs b/src/app/context_drawer.rs index b33d2ba..ac9d567 100644 --- a/src/app/context_drawer.rs +++ b/src/app/context_drawer.rs @@ -7,7 +7,7 @@ use crate::Element; pub struct ContextDrawer<'a, Message: Clone + 'static> { pub title: Option>, - pub header_actions: Vec>, + pub actions: Option>, pub header: Option>, pub content: Element<'a, Message>, pub footer: Option>, @@ -29,29 +29,28 @@ pub fn context_drawer<'a, Message: Clone + 'static>( ) -> ContextDrawer<'a, Message> { ContextDrawer { title: None, + actions: None, + header: None, content: content.into(), - header_actions: vec![], footer: None, on_close, - header: None, } } impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { - /// Set a context drawer header title + /// Set a context drawer title pub fn title(mut self, title: impl Into>) -> Self { self.title = Some(title.into()); self } - /// App-specific actions at the start of the context drawer header - pub fn header_actions( - mut self, - header_actions: impl IntoIterator>, - ) -> Self { - self.header_actions = header_actions.into_iter().collect(); + + /// App-specific actions at the top-left corner of the context drawer + pub fn actions(mut self, actions: impl Into>) -> Self { + self.actions = Some(actions.into()); self } - /// Non-scrolling elements placed below the context drawer title row + + /// Elements placed above the context drawer scrollable pub fn header(mut self, header: impl Into>) -> Self { self.header = Some(header.into()); self @@ -64,20 +63,16 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { } pub fn map( - mut self, + self, on_message: fn(Message) -> Out, ) -> ContextDrawer<'a, Out> { ContextDrawer { title: self.title, - content: self.content.map(on_message), + actions: self.actions.map(|el| el.map(on_message)), header: self.header.map(|el| el.map(on_message)), + content: self.content.map(on_message), footer: self.footer.map(|el| el.map(on_message)), on_close: on_message(self.on_close), - header_actions: self - .header_actions - .into_iter() - .map(|el| el.map(on_message)) - .collect(), } } } diff --git a/src/app/mod.rs b/src/app/mod.rs index eaf0bae..090698d 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -603,7 +603,7 @@ impl ApplicationExt for App { widgets.push( crate::widget::context_drawer( context.title, - context.header_actions, + context.actions, context.header, context.footer, context.on_close, @@ -640,7 +640,7 @@ impl ApplicationExt for App { widgets.push( crate::widget::ContextDrawer::new_inner( context.title, - context.header_actions, + context.actions, context.header, context.footer, context.content, diff --git a/src/widget/context_drawer/mod.rs b/src/widget/context_drawer/mod.rs index f162122..107c1ff 100644 --- a/src/widget/context_drawer/mod.rs +++ b/src/widget/context_drawer/mod.rs @@ -15,9 +15,9 @@ use crate::Element; /// An overlayed widget that attaches a toggleable context drawer to the view. pub fn context_drawer<'a, Message: Clone + 'static, Content, Drawer>( title: Option>, - header_actions: Vec>, - header_opt: Option>, - footer_opt: Option>, + actions: Option>, + header: Option>, + footer: Option>, on_close: Message, content: Content, drawer: Drawer, @@ -28,13 +28,6 @@ where Drawer: Into>, { ContextDrawer::new( - title, - header_actions, - header_opt, - footer_opt, - content, - drawer, - on_close, - max_width, + title, actions, header, footer, content, drawer, on_close, max_width, ) } diff --git a/src/widget/context_drawer/widget.rs b/src/widget/context_drawer/widget.rs index c65fe08..cb4b7f9 100644 --- a/src/widget/context_drawer/widget.rs +++ b/src/widget/context_drawer/widget.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 use super::overlay::Overlay; -use crate::widget::{LayerContainer, button, column, container, icon, row, scrollable, text}; +use crate::widget::{self, LayerContainer, button, column, container, icon, row, scrollable, text}; use crate::{Apply, Element, Renderer, Theme, fl}; use std::borrow::Cow; @@ -25,9 +25,9 @@ pub struct ContextDrawer<'a, Message> { impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { pub fn new_inner( title: Option>, - header_actions: Vec>, - header_opt: Option>, - footer_opt: Option>, + actions: Option>, + header: Option>, + footer: Option>, drawer: Drawer, on_close: Message, max_width: f32, @@ -38,7 +38,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { #[inline(never)] fn inner<'a, Message: Clone + 'static>( title: Option>, - header_actions: Vec>, + actions_opt: Option>, header_opt: Option>, footer_opt: Option>, drawer: Element<'a, Message>, @@ -53,68 +53,57 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { .. } = crate::theme::spacing(); - let (horizontal_padding, title_portion, side_portion) = if max_width < 392.0 { - (space_s, 1, 1) - } else { - (space_l, 2, 1) - }; + let horizontal_padding = if max_width < 392.0 { space_s } else { space_l }; let title = title.map(|title| { - text::heading(title) + text::title4(title) .apply(container) - .center_x(Length::FillPortion(title_portion)) + .padding([if actions_opt.is_some() { space_m } else { 0 }, 0, 0, 0]) + .width(Length::Fill) }); - - let (actions_width, close_width) = if title.is_some() { - ( - Length::FillPortion(side_portion), - Length::FillPortion(side_portion), - ) + let actions = if let Some(actions) = actions_opt { + actions + .apply(container) + .width(Length::Fill) + .apply(Element::from) } else { - (Length::Fill, Length::Shrink) + widget::horizontal_space().apply(Element::from) }; - let header_row = row::with_capacity(3) - .width(Length::Fixed(480.0)) + let header_row = row::with_capacity(2) .align_y(Alignment::Center) - .push( - row::with_children(header_actions) - .spacing(space_xxs) - .width(actions_width), - ) - .push_maybe(title) + .push(actions) .push( button::text(fl!("close")) .trailing_icon(icon::from_name("go-next-symbolic")) - .on_press(on_close) - .apply(container) - .width(close_width) - .align_x(Alignment::End), + .on_press(on_close), ); - let header = column::with_capacity(2) - .width(Length::Fixed(480.0)) + let header_element = + header_opt.map(|el| el.apply(container).padding([space_m, 0, 0, 0])); + + let header = column::with_capacity(3) .align_x(Alignment::Center) - .spacing(space_m) .padding([space_m, horizontal_padding]) .push(header_row) - .push_maybe(header_opt); + .push_maybe(title) + .push_maybe(header_element); let footer = footer_opt.map(|element| { container(element) - .width(Length::Fixed(480.0)) .align_y(Alignment::Center) .padding([space_xxs, horizontal_padding]) }); let pane = column::with_capacity(3) .push(header) .push( - scrollable(container(drawer).padding([ - 0, - horizontal_padding, - if footer.is_some() { 0 } else { space_l }, - horizontal_padding, - ])) - .height(Length::Fill) - .width(Length::Shrink), + container(drawer) + .padding([ + 0, + horizontal_padding, + if footer.is_some() { 0 } else { space_l }, + horizontal_padding, + ]) + .apply(scrollable) + .height(Length::Fill), ) .push_maybe(footer); @@ -136,9 +125,9 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { inner( title, - header_actions, - header_opt, - footer_opt, + actions, + header, + footer, drawer.into(), on_close, max_width, @@ -148,9 +137,9 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { /// Creates an empty [`ContextDrawer`]. pub fn new( title: Option>, - header_actions: Vec>, - header_opt: Option>, - footer_opt: Option>, + actions: Option>, + header: Option>, + footer: Option>, content: Content, drawer: Drawer, on_close: Message, @@ -160,15 +149,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { Content: Into>, Drawer: Into>, { - let drawer = Self::new_inner( - title, - header_actions, - header_opt, - footer_opt, - drawer, - on_close, - max_width, - ); + let drawer = Self::new_inner(title, actions, header, footer, drawer, on_close, max_width); ContextDrawer { id: None, @@ -188,7 +169,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { /// Map the message type of the context drawer to another #[inline] pub fn map( - mut self, + self, on_message: fn(Message) -> Out, ) -> ContextDrawer<'a, Out> { ContextDrawer {