diff --git a/src/widget/settings/item.rs b/src/widget/settings/item.rs index 4e5b56af..90e2a7a8 100644 --- a/src/widget/settings/item.rs +++ b/src/widget/settings/item.rs @@ -4,9 +4,10 @@ use std::borrow::Cow; use crate::{widget::text, Element, Renderer}; -use iced::widget::{horizontal_space, row, Row}; +use derive_setters::Setters; +use iced::widget::{column, horizontal_space, row, Row}; -/// A setting within a settings view section. +/// A settings item aligned in a row #[must_use] #[allow(clippy::module_name_repetitions)] pub fn item<'a, Message: 'static>( @@ -29,3 +30,60 @@ pub fn item_row(children: Vec>) -> Row(title: impl Into>) -> Item<'a, Message> { + Item { + title: title.into(), + description: None, + icon: None, + } +} + +/// A builder for a settings item. +#[derive(Setters)] +pub struct Item<'a, Message> { + /// Describes the item being controlled. + title: Cow<'a, str>, + + /// A description to display beneath the title. + #[setters(strip_option, into)] + description: Option>, + + /// A custom icon to display before the text. + #[setters(strip_option, into)] + icon: Option>, +} + +impl<'a, Message: 'static> Item<'a, Message> { + /// Assigns a control to the item. + pub fn control(self, widget: impl Into>) -> Row<'a, Message, Renderer> { + let mut contents = Vec::with_capacity(4); + + if let Some(icon) = self.icon { + contents.push(icon); + } + + if let Some(description) = self.description { + let title = text(self.title).size(18); + let desc = text(description).size(12); + + contents.push(column!(title, desc).spacing(2).into()); + } else { + contents.push(text(self.title).into()); + } + + contents.push(horizontal_space(iced::Length::Fill).into()); + contents.push(widget.into()); + + item_row(contents) + } + + pub fn toggler( + self, + is_checked: bool, + message: impl Fn(bool) -> Message + 'static, + ) -> Row<'a, Message, Renderer> { + self.control(crate::widget::toggler(None, is_checked, message)) + } +} diff --git a/src/widget/settings/mod.rs b/src/widget/settings/mod.rs index e21236d5..26ab3d4f 100644 --- a/src/widget/settings/mod.rs +++ b/src/widget/settings/mod.rs @@ -1,7 +1,7 @@ // Copyright 2022 System76 // SPDX-License-Identifier: MPL-2.0 -mod item; +pub mod item; mod section; pub use self::item::{item, item_row};