cosmic/app/
context_drawer.rs

1// Copyright 2024 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3//
4use std::borrow::Cow;
5
6use crate::Element;
7
8pub struct ContextDrawer<'a, Message: Clone + 'static> {
9    pub title: Option<Cow<'a, str>>,
10    pub actions: Option<Element<'a, Message>>,
11    pub header: Option<Element<'a, Message>>,
12    pub content: Element<'a, Message>,
13    pub footer: Option<Element<'a, Message>>,
14    pub on_close: Message,
15}
16
17#[cfg(feature = "about")]
18pub fn about<'a, Message: Clone + 'static>(
19    about: &'a crate::widget::about::About,
20    on_url_press: impl Fn(&'a str) -> Message + 'a,
21    on_close: Message,
22) -> ContextDrawer<'a, Message> {
23    context_drawer(crate::widget::about(about, on_url_press), on_close)
24}
25
26pub fn context_drawer<'a, Message: Clone + 'static>(
27    content: impl Into<Element<'a, Message>>,
28    on_close: Message,
29) -> ContextDrawer<'a, Message> {
30    ContextDrawer {
31        title: None,
32        actions: None,
33        header: None,
34        content: content.into(),
35        footer: None,
36        on_close,
37    }
38}
39
40impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
41    /// Set a context drawer title
42    pub fn title(mut self, title: impl Into<Cow<'a, str>>) -> Self {
43        self.title = Some(title.into());
44        self
45    }
46
47    /// App-specific actions at the top-left corner of the context drawer
48    pub fn actions(mut self, actions: impl Into<Element<'a, Message>>) -> Self {
49        self.actions = Some(actions.into());
50        self
51    }
52
53    /// Elements placed above the context drawer scrollable
54    pub fn header(mut self, header: impl Into<Element<'a, Message>>) -> Self {
55        self.header = Some(header.into());
56        self
57    }
58
59    /// Elements placed below the context drawer scrollable
60    pub fn footer(mut self, footer: impl Into<Element<'a, Message>>) -> Self {
61        self.footer = Some(footer.into());
62        self
63    }
64
65    pub fn map<Out: Clone + 'static>(
66        self,
67        on_message: fn(Message) -> Out,
68    ) -> ContextDrawer<'a, Out> {
69        ContextDrawer {
70            title: self.title,
71            actions: self.actions.map(|el| el.map(on_message)),
72            header: self.header.map(|el| el.map(on_message)),
73            content: self.content.map(on_message),
74            footer: self.footer.map(|el| el.map(on_message)),
75            on_close: on_message(self.on_close),
76        }
77    }
78}