122 lines
3.5 KiB
Rust
122 lines
3.5 KiB
Rust
use gpui::{
|
|
App, IntoElement, ParentElement as _, SharedString, StyleRefinement, Styled, Window,
|
|
prelude::FluentBuilder as _,
|
|
};
|
|
|
|
use crate::{
|
|
ActiveTheme, StyledExt,
|
|
group_box::{GroupBox, GroupBoxVariants},
|
|
label::Label,
|
|
setting::{RenderOptions, SettingItem},
|
|
v_flex,
|
|
};
|
|
|
|
/// A setting group that can contain multiple setting items.
|
|
#[derive(Clone)]
|
|
pub struct SettingGroup {
|
|
style: StyleRefinement,
|
|
|
|
pub(super) title: Option<SharedString>,
|
|
pub(super) description: Option<SharedString>,
|
|
pub(super) items: Vec<SettingItem>,
|
|
}
|
|
|
|
impl Styled for SettingGroup {
|
|
fn style(&mut self) -> &mut StyleRefinement {
|
|
&mut self.style
|
|
}
|
|
}
|
|
|
|
impl SettingGroup {
|
|
/// Create a new setting group.
|
|
pub fn new() -> Self {
|
|
Self {
|
|
style: StyleRefinement::default(),
|
|
title: None,
|
|
description: None,
|
|
items: Vec::new(),
|
|
}
|
|
}
|
|
|
|
/// Set the label of the setting group, default is None.
|
|
pub fn title(mut self, title: impl Into<SharedString>) -> Self {
|
|
self.title = Some(title.into());
|
|
self
|
|
}
|
|
|
|
/// Set the description of the setting group, default is None.
|
|
pub fn description(mut self, description: impl Into<SharedString>) -> Self {
|
|
self.description = Some(description.into());
|
|
self
|
|
}
|
|
|
|
/// Add a setting item to the group.
|
|
pub fn item(mut self, item: SettingItem) -> Self {
|
|
self.items.push(item);
|
|
self
|
|
}
|
|
|
|
/// Add multiple setting items to the group.
|
|
pub fn items<I>(mut self, items: I) -> Self
|
|
where
|
|
I: IntoIterator<Item = SettingItem>,
|
|
{
|
|
self.items.extend(items);
|
|
self
|
|
}
|
|
|
|
/// Return true if any of the setting items in the group match the given query.
|
|
pub(super) fn is_match(&self, query: &str) -> bool {
|
|
self.items.iter().any(|item| item.is_match(query))
|
|
}
|
|
|
|
pub(super) fn is_resettable(&self, cx: &App) -> bool {
|
|
self.items.iter().any(|item| item.is_resettable(cx))
|
|
}
|
|
|
|
pub(crate) fn render(
|
|
self,
|
|
query: &str,
|
|
options: &RenderOptions,
|
|
window: &mut Window,
|
|
cx: &mut App,
|
|
) -> impl IntoElement {
|
|
GroupBox::new()
|
|
.id(SharedString::from(format!("group-{}", options.group_ix)))
|
|
.with_variant(options.group_variant)
|
|
.when_some(self.title.clone(), |this, title| {
|
|
this.title(v_flex().gap_1().child(title).when_some(
|
|
self.description.clone(),
|
|
|this, description| {
|
|
this.child(
|
|
Label::new(description)
|
|
.text_sm()
|
|
.text_color(cx.theme().muted_foreground),
|
|
)
|
|
},
|
|
))
|
|
})
|
|
.gap_4()
|
|
.children(self.items.iter().enumerate().filter_map(|(item_ix, item)| {
|
|
if item.is_match(&query) {
|
|
Some(item.clone().render_item(
|
|
&RenderOptions {
|
|
item_ix,
|
|
..*options
|
|
},
|
|
window,
|
|
cx,
|
|
))
|
|
} else {
|
|
None
|
|
}
|
|
}))
|
|
.refine_style(&self.style)
|
|
}
|
|
|
|
pub(crate) fn reset(&self, window: &mut Window, cx: &mut App) {
|
|
for item in &self.items {
|
|
item.reset(window, cx);
|
|
}
|
|
}
|
|
}
|