use gpui::prelude::*;
use gpui::{div, px, AnyElement, App, ElementId, IntoElement, SharedString, Window};
use crate::devtools::Probed;
use crate::icon::IconName;
use crate::input::ClickHandler;
use crate::theme::{theme, Size};
use crate::ActionIcon;
#[derive(IntoElement)]
pub struct SettingsRow {
id: ElementId,
label: SharedString,
description: Option<SharedString>,
modified: bool,
on_reset: Option<ClickHandler>,
control: Option<AnyElement>,
divider: bool,
}
impl SettingsRow {
pub fn new(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
SettingsRow {
id: id.into(),
label: label.into(),
description: None,
modified: false,
on_reset: None,
control: None,
divider: true,
}
}
pub fn description(mut self, description: impl Into<SharedString>) -> Self {
self.description = Some(description.into());
self
}
pub fn modified(mut self, modified: bool) -> Self {
self.modified = modified;
self
}
pub fn on_reset(
mut self,
handler: impl Fn(&gpui::ClickEvent, &mut Window, &mut App) + 'static,
) -> Self {
self.on_reset = Some(Box::new(handler));
self
}
pub fn control(mut self, control: impl IntoElement) -> Self {
self.control = Some(control.into_any_element());
self
}
pub fn divider(mut self, divider: bool) -> Self {
self.divider = divider;
self
}
}
impl RenderOnce for SettingsRow {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
let t = theme(cx);
let text = t.text().hsla();
let dimmed = t.dimmed().hsla();
let border = t.border().hsla();
let accent = t.primary().hsla();
let font_sm = t.font_size(Size::Sm);
let font_xs = t.font_size(Size::Xs);
let mut name = div()
.flex()
.items_center()
.gap(px(6.0))
.text_size(px(font_sm))
.text_color(text)
.child(self.label.clone());
if self.modified {
name = match self.on_reset {
Some(handler) => name.child(
ActionIcon::new(self.id.clone(), IconName::RotateCcw)
.label("Reset")
.size(Size::Xs)
.variant(crate::style::Variant::Subtle)
.on_click(handler),
),
None => name.child(
div()
.flex_none()
.w(px(5.0))
.h(px(5.0))
.rounded_full()
.bg(accent),
),
};
}
let mut left = div()
.flex()
.flex_col()
.flex_1()
.min_w(px(0.0))
.gap(px(2.0))
.child(name);
if let Some(description) = self.description {
left = left.child(
div()
.text_size(px(font_xs))
.text_color(dimmed)
.child(description),
);
}
div()
.flex()
.items_center()
.justify_between()
.gap(px(16.0))
.w_full()
.py(px(12.0))
.when(self.divider, |el| el.border_b_1().border_color(border))
.child(left)
.child(
div()
.flex()
.items_center()
.flex_none()
.children(self.control),
)
.probe("SettingsRow")
.attr_if("modified", self.modified)
}
}