cosmic/widget/settings/
section.rs

1// Copyright 2022 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4use crate::Element;
5use crate::widget::list_column::IntoListItem;
6use crate::widget::{ListColumn, column, list_column, text};
7use std::borrow::Cow;
8
9/// A section within a settings view column.
10pub fn section<'a, Message: Clone + 'static>() -> Section<'a, Message> {
11    with_column(ListColumn::default())
12}
13
14/// A section with a pre-defined list column of a given capacity.
15pub fn with_capacity<'a, Message: Clone + 'static>(capacity: usize) -> Section<'a, Message> {
16    with_column(list_column::with_capacity(capacity))
17}
18
19/// A section with a pre-defined list column.
20pub fn with_column<Message: Clone + 'static>(
21    children: ListColumn<'_, Message>,
22) -> Section<'_, Message> {
23    Section {
24        header: None,
25        children,
26    }
27}
28
29#[must_use]
30pub struct Section<'a, Message> {
31    header: Option<Element<'a, Message>>,
32    children: ListColumn<'a, Message>,
33}
34
35impl<'a, Message: Clone + 'static> Section<'a, Message> {
36    /// Define an optional title for the section.
37    pub fn title(self, title: impl Into<Cow<'a, str>>) -> Self {
38        self.header(text::heading(title.into()))
39    }
40
41    /// Define an optional custom header for the section.
42    pub fn header(mut self, header: impl Into<Element<'a, Message>>) -> Self {
43        self.header = Some(header.into());
44        self
45    }
46
47    /// Add a child element to the section's list column.
48    #[allow(clippy::should_implement_trait)]
49    pub fn add(mut self, item: impl IntoListItem<'a, Message>) -> Self {
50        self.children = self.children.add(item);
51        self
52    }
53
54    /// Add a child element to the section's list column, if `Some`.
55    pub fn add_maybe(self, item: Option<impl IntoListItem<'a, Message>>) -> Self {
56        if let Some(item) = item {
57            self.add(item)
58        } else {
59            self
60        }
61    }
62
63    /// Extends the [`Section`] with the given children.
64    pub fn extend(
65        self,
66        children: impl IntoIterator<Item = impl IntoListItem<'a, Message>>,
67    ) -> Self {
68        children.into_iter().fold(self, Self::add)
69    }
70}
71
72impl<'a, Message: Clone + 'static> From<Section<'a, Message>> for Element<'a, Message> {
73    fn from(data: Section<'a, Message>) -> Self {
74        column::with_capacity(2)
75            .spacing(8)
76            .push_maybe(data.header)
77            .push(data.children)
78            .into()
79    }
80}