feat(context_drawer): add actions to header

This commit is contained in:
Vukašin Vojinović 2024-11-09 20:50:21 +01:00 committed by Michael Murphy
parent d8357d0ea3
commit c310f4ca24
3 changed files with 32 additions and 11 deletions

View file

@ -465,6 +465,11 @@ where
None None
} }
/// App-specific actions at the start of the context drawer header
fn context_header_actions(&self) -> Vec<Element<Message<Self::Message>>> {
Vec::new()
}
/// Displays a dialog in the center of the application window when `Some`. /// Displays a dialog in the center of the application window when `Some`.
fn dialog(&self) -> Option<Element<Self::Message>> { fn dialog(&self) -> Option<Element<Self::Message>> {
None None
@ -746,6 +751,7 @@ impl<App: Application> ApplicationExt for App {
widgets.push( widgets.push(
context_drawer( context_drawer(
&core.window.context_title, &core.window.context_title,
self.context_header_actions(),
Message::Cosmic(cosmic::Message::ContextDrawer(false)), Message::Cosmic(cosmic::Message::ContextDrawer(false)),
main_content, main_content,
context.map(Message::App), context.map(Message::App),
@ -779,6 +785,7 @@ impl<App: Application> ApplicationExt for App {
widgets.push( widgets.push(
crate::widget::ContextDrawer::new_inner( crate::widget::ContextDrawer::new_inner(
&core.window.context_title, &core.window.context_title,
self.context_header_actions(),
context.map(Message::App), context.map(Message::App),
Message::Cosmic(cosmic::Message::ContextDrawer(false)), Message::Cosmic(cosmic::Message::ContextDrawer(false)),
context_width, context_width,

View file

@ -12,7 +12,8 @@ use crate::Element;
/// An overlayed widget that attaches a toggleable context drawer to the view. /// An overlayed widget that attaches a toggleable context drawer to the view.
pub fn context_drawer<'a, Message: Clone + 'static, Content, Drawer>( pub fn context_drawer<'a, Message: Clone + 'static, Content, Drawer>(
header: &'a str, title: &'a str,
actions: Vec<Element<'a, Message>>,
on_close: Message, on_close: Message,
content: Content, content: Content,
drawer: Drawer, drawer: Drawer,
@ -22,5 +23,5 @@ where
Content: Into<Element<'a, Message>>, Content: Into<Element<'a, Message>>,
Drawer: Into<Element<'a, Message>>, Drawer: Into<Element<'a, Message>>,
{ {
ContextDrawer::new(header, content, drawer, on_close, max_width) ContextDrawer::new(title, actions, content, drawer, on_close, max_width)
} }

View file

@ -1,9 +1,7 @@
// Copyright 2023 System76 <info@system76.com> // Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use crate::widget::{ use crate::widget::{button, column, container, icon, row, text, LayerContainer};
button, column, container, icon, row, scrollable, text, LayerContainer, Space,
};
use crate::{Apply, Element, Renderer, Theme}; use crate::{Apply, Element, Renderer, Theme};
use super::overlay::Overlay; use super::overlay::Overlay;
@ -26,7 +24,8 @@ pub struct ContextDrawer<'a, Message> {
impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> { impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
pub fn new_inner<Drawer>( pub fn new_inner<Drawer>(
header: &'a str, title: &'a str,
actions: Vec<Element<'a, Message>>,
drawer: Drawer, drawer: Drawer,
on_close: Message, on_close: Message,
max_width: f32, max_width: f32,
@ -35,15 +34,28 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
Drawer: Into<Element<'a, Message>>, Drawer: Into<Element<'a, Message>>,
{ {
let cosmic_theme::Spacing { let cosmic_theme::Spacing {
space_m, space_l, .. space_xxs,
space_m,
space_l,
..
} = crate::theme::active().cosmic().spacing; } = 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) let header = row::with_capacity(3)
.width(Length::Fixed(480.0)) .width(Length::Fixed(480.0))
.align_y(Alignment::Center) .align_y(Alignment::Center)
.padding([space_m, space_l]) .padding([space_m, space_l])
.push(Space::new(Length::FillPortion(1), Length::Fixed(0.0))) .push(
.push(text::heading(header).width(Length::FillPortion(1)).center()) row::with_children(actions)
.spacing(space_xxs)
.width(Length::FillPortion(1)),
)
.push_maybe(title_opt)
.push( .push(
button::text("Close") button::text("Close")
.trailing_icon(icon::from_name("go-next-symbolic")) .trailing_icon(icon::from_name("go-next-symbolic"))
@ -78,7 +90,8 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
/// Creates an empty [`ContextDrawer`]. /// Creates an empty [`ContextDrawer`].
pub fn new<Content, Drawer>( pub fn new<Content, Drawer>(
header: &'a str, title: &'a str,
actions: Vec<Element<'a, Message>>,
content: Content, content: Content,
drawer: Drawer, drawer: Drawer,
on_close: Message, on_close: Message,
@ -88,7 +101,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
Content: Into<Element<'a, Message>>, Content: Into<Element<'a, Message>>,
Drawer: Into<Element<'a, Message>>, Drawer: Into<Element<'a, Message>>,
{ {
let drawer = Self::new_inner(header, drawer, on_close, max_width); let drawer = Self::new_inner(title, actions, drawer, on_close, max_width);
ContextDrawer { ContextDrawer {
id: None, id: None,