diff --git a/src/app/mod.rs b/src/app/mod.rs index 96a3f5f6..b713e7c7 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -465,6 +465,11 @@ where None } + /// App-specific actions at the start of the context drawer header + fn context_header_actions(&self) -> Vec>> { + Vec::new() + } + /// Displays a dialog in the center of the application window when `Some`. fn dialog(&self) -> Option> { None @@ -746,6 +751,7 @@ impl ApplicationExt for App { widgets.push( context_drawer( &core.window.context_title, + self.context_header_actions(), Message::Cosmic(cosmic::Message::ContextDrawer(false)), main_content, context.map(Message::App), @@ -779,6 +785,7 @@ impl ApplicationExt for App { widgets.push( crate::widget::ContextDrawer::new_inner( &core.window.context_title, + self.context_header_actions(), context.map(Message::App), Message::Cosmic(cosmic::Message::ContextDrawer(false)), context_width, diff --git a/src/widget/context_drawer/mod.rs b/src/widget/context_drawer/mod.rs index 52b9a007..0581a21b 100644 --- a/src/widget/context_drawer/mod.rs +++ b/src/widget/context_drawer/mod.rs @@ -12,7 +12,8 @@ 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>( - header: &'a str, + title: &'a str, + actions: Vec>, on_close: Message, content: Content, drawer: Drawer, @@ -22,5 +23,5 @@ where Content: Into>, Drawer: Into>, { - ContextDrawer::new(header, content, drawer, on_close, max_width) + ContextDrawer::new(title, actions, content, drawer, on_close, max_width) } diff --git a/src/widget/context_drawer/widget.rs b/src/widget/context_drawer/widget.rs index 487cee53..5f6560cf 100644 --- a/src/widget/context_drawer/widget.rs +++ b/src/widget/context_drawer/widget.rs @@ -1,9 +1,7 @@ // Copyright 2023 System76 // SPDX-License-Identifier: MPL-2.0 -use crate::widget::{ - button, column, container, icon, row, scrollable, text, LayerContainer, Space, -}; +use crate::widget::{button, column, container, icon, row, text, LayerContainer}; use crate::{Apply, Element, Renderer, Theme}; use super::overlay::Overlay; @@ -26,7 +24,8 @@ pub struct ContextDrawer<'a, Message> { impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { pub fn new_inner( - header: &'a str, + title: &'a str, + actions: Vec>, drawer: Drawer, on_close: Message, max_width: f32, @@ -35,15 +34,28 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { Drawer: Into>, { let cosmic_theme::Spacing { - space_m, space_l, .. + space_xxs, + space_m, + space_l, + .. } = crate::theme::active().cosmic().spacing; + let title_opt = if title.is_empty() { + None + } else { + Some(text::heading(title).width(Length::FillPortion(1)).center()) + }; + let header = row::with_capacity(3) .width(Length::Fixed(480.0)) .align_y(Alignment::Center) .padding([space_m, space_l]) - .push(Space::new(Length::FillPortion(1), Length::Fixed(0.0))) - .push(text::heading(header).width(Length::FillPortion(1)).center()) + .push( + row::with_children(actions) + .spacing(space_xxs) + .width(Length::FillPortion(1)), + ) + .push_maybe(title_opt) .push( button::text("Close") .trailing_icon(icon::from_name("go-next-symbolic")) @@ -78,7 +90,8 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { /// Creates an empty [`ContextDrawer`]. pub fn new( - header: &'a str, + title: &'a str, + actions: Vec>, content: Content, drawer: Drawer, on_close: Message, @@ -88,7 +101,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { Content: Into>, Drawer: Into>, { - let drawer = Self::new_inner(header, drawer, on_close, max_width); + let drawer = Self::new_inner(title, actions, drawer, on_close, max_width); ContextDrawer { id: None,