Skip to content

Commit b152860

Browse files
authored
settings ui: Add some light design tweaks (#38934)
Release Notes: - N/A
1 parent ee357e8 commit b152860

File tree

1 file changed

+80
-72
lines changed

1 file changed

+80
-72
lines changed

crates/settings_ui/src/settings_ui.rs

Lines changed: 80 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use editor::Editor;
44
use feature_flags::{FeatureFlag, FeatureFlagAppExt as _};
55
use gpui::{
66
App, AppContext as _, Context, Div, Entity, Global, IntoElement, ReadGlobal as _, Render,
7-
UniformListScrollHandle, Window, WindowHandle, WindowOptions, actions, div, px, size,
8-
uniform_list,
7+
TitlebarOptions, UniformListScrollHandle, Window, WindowHandle, WindowOptions, actions, div,
8+
point, px, size, uniform_list,
99
};
1010
use project::WorktreeId;
1111
use settings::{CursorShape, SaturatingBool, SettingsContent, SettingsStore};
@@ -17,12 +17,7 @@ use std::{
1717
rc::Rc,
1818
sync::Arc,
1919
};
20-
use ui::{
21-
ActiveTheme as _, AnyElement, BorrowAppContext as _, Button, Clickable as _, Color, Divider,
22-
DropdownMenu, FluentBuilder as _, Icon, IconName, InteractiveElement as _, Label,
23-
LabelCommon as _, LabelSize, ListItem, ParentElement, SharedString,
24-
StatefulInteractiveElement as _, Styled, StyledTypography, Switch, h_flex, v_flex,
25-
};
20+
use ui::{Divider, DropdownMenu, ListItem, Switch, prelude::*};
2621
use util::{paths::PathStyle, rel_path::RelPath};
2722

2823
use crate::components::SettingsEditor;
@@ -292,11 +287,16 @@ fn init_renderers(cx: &mut App) {
292287
pub fn open_settings_editor(cx: &mut App) -> anyhow::Result<WindowHandle<SettingsWindow>> {
293288
cx.open_window(
294289
WindowOptions {
295-
titlebar: None,
290+
titlebar: Some(TitlebarOptions {
291+
title: Some("Settings Window".into()),
292+
appears_transparent: true,
293+
traffic_light_position: Some(point(px(12.0), px(12.0))),
294+
}),
296295
focus: true,
297296
show: true,
298297
kind: gpui::WindowKind::Normal,
299-
window_min_size: Some(size(px(300.), px(500.))), // todo(settings_ui): Does this min_size make sense?
298+
window_background: cx.theme().window_background_appearance(),
299+
window_min_size: Some(size(px(800.), px(600.))), // 4:3 Aspect Ratio
300300
..Default::default()
301301
},
302302
|window, cx| cx.new(|cx| SettingsWindow::new(window, cx)),
@@ -342,40 +342,40 @@ enum SettingsPageItem {
342342
impl SettingsPageItem {
343343
fn render(&self, _file: SettingsFile, window: &mut Window, cx: &mut App) -> AnyElement {
344344
match self {
345-
SettingsPageItem::SectionHeader(header) => div()
345+
SettingsPageItem::SectionHeader(header) => v_flex()
346346
.w_full()
347+
.gap_0p5()
347348
.child(Label::new(SharedString::new_static(header)).size(LabelSize::Large))
348349
.child(Divider::horizontal().color(ui::DividerColor::BorderVariant))
349350
.into_any_element(),
350351
SettingsPageItem::SettingItem(setting_item) => {
351352
let renderer = cx.default_global::<SettingFieldRenderer>().clone();
352-
div()
353+
h_flex()
353354
.id(setting_item.title)
355+
.w_full()
356+
.gap_2()
357+
.flex_wrap()
358+
.justify_between()
354359
.child(
355-
Label::new(SharedString::new_static(setting_item.title))
356-
.size(LabelSize::Default),
357-
)
358-
.child(
359-
h_flex()
360-
.justify_between()
360+
v_flex()
361+
.max_w_1_2()
362+
.flex_shrink()
361363
.child(
362-
div()
363-
.child(
364-
Label::new(SharedString::new_static(
365-
setting_item.description,
366-
))
367-
.size(LabelSize::Small)
368-
.color(Color::Muted),
369-
)
370-
.max_w_1_2(),
364+
Label::new(SharedString::new_static(setting_item.title))
365+
.size(LabelSize::Default),
371366
)
372-
.child(renderer.render(
373-
setting_item.field.as_ref(),
374-
setting_item.metadata.as_deref(),
375-
window,
376-
cx,
377-
)),
367+
.child(
368+
Label::new(SharedString::new_static(setting_item.description))
369+
.size(LabelSize::Small)
370+
.color(Color::Muted),
371+
),
378372
)
373+
.child(renderer.render(
374+
setting_item.field.as_ref(),
375+
setting_item.metadata.as_deref(),
376+
window,
377+
cx,
378+
))
379379
.into_any_element()
380380
}
381381
}
@@ -423,7 +423,7 @@ impl SettingsWindow {
423423
let current_file = SettingsFile::User;
424424
let search = cx.new(|cx| {
425425
let mut editor = Editor::single_line(window, cx);
426-
editor.set_placeholder_text("Search Settings", window, cx);
426+
editor.set_placeholder_text("Search settings…", window, cx);
427427
editor
428428
});
429429
let mut this = Self {
@@ -526,29 +526,38 @@ impl SettingsWindow {
526526
}
527527

528528
fn render_files(&self, _window: &mut Window, cx: &mut Context<SettingsWindow>) -> Div {
529-
div()
530-
.flex()
531-
.flex_row()
529+
h_flex()
532530
.gap_1()
533531
.children(self.files.iter().enumerate().map(|(ix, file)| {
534532
Button::new(ix, file.name())
535533
.on_click(cx.listener(move |this, _, _window, cx| this.change_file(ix, cx)))
536534
}))
537535
}
538536

539-
fn render_search(&self, _window: &mut Window, _cx: &mut App) -> Div {
537+
fn render_search(&self, _window: &mut Window, cx: &mut App) -> Div {
540538
h_flex()
541-
.child(Icon::new(IconName::MagnifyingGlass))
539+
.pt_1()
540+
.px_1p5()
541+
.gap_1p5()
542+
.rounded_sm()
543+
.bg(cx.theme().colors().editor_background)
544+
.border_1()
545+
.border_color(cx.theme().colors().border)
546+
.child(Icon::new(IconName::MagnifyingGlass).color(Color::Muted))
542547
.child(self.search.clone())
543548
}
544549

545550
fn render_nav(&self, window: &mut Window, cx: &mut Context<SettingsWindow>) -> Div {
546551
v_flex()
552+
.w_64()
553+
.p_2p5()
554+
.pt_10()
555+
.gap_3()
556+
.flex_none()
557+
.border_r_1()
558+
.border_color(cx.theme().colors().border)
547559
.bg(cx.theme().colors().panel_background)
548-
.p_3()
549-
.child(div().h_10()) // Files spacer;
550560
.child(self.render_search(window, cx).pb_1())
551-
.gap_3()
552561
.child(
553562
uniform_list(
554563
"settings-ui-nav-bar",
@@ -559,12 +568,25 @@ impl SettingsWindow {
559568
.map(|ix| {
560569
let entry = &this.navbar_entries[ix];
561570

562-
div()
571+
h_flex()
563572
.id(("settings-ui-section", ix))
573+
.w_full()
574+
.pl_2p5()
575+
.py_0p5()
576+
.rounded_sm()
577+
.border_1()
578+
.border_color(cx.theme().colors().border_transparent)
579+
.text_color(cx.theme().colors().text_muted)
580+
.when(this.is_navbar_entry_selected(ix), |this| {
581+
this.text_color(cx.theme().colors().text)
582+
.bg(cx.theme().colors().element_selected.opacity(0.2))
583+
.border_color(cx.theme().colors().border)
584+
})
564585
.child(
565586
ListItem::new(("settings-ui-navbar-entry", ix))
566587
.selectable(true)
567-
.indent_step_size(px(10.))
588+
.inset(true)
589+
.indent_step_size(px(1.))
568590
.indent_level(if entry.is_root { 1 } else { 3 })
569591
.when(entry.is_root, |item| {
570592
item.toggle(
@@ -579,26 +601,13 @@ impl SettingsWindow {
579601
}))
580602
})
581603
.child(
582-
div()
604+
h_flex()
583605
.text_ui(cx)
584-
.size_full()
585-
.child(entry.title)
586-
.hover(|style| {
587-
style.bg(cx.theme().colors().element_hover)
606+
.truncate()
607+
.hover(|s| {
608+
s.bg(cx.theme().colors().element_hover)
588609
})
589-
.when(!entry.is_root, |this| {
590-
this.text_color(
591-
cx.theme().colors().text_muted,
592-
)
593-
})
594-
.when(
595-
this.is_navbar_entry_selected(ix),
596-
|this| {
597-
this.text_color(
598-
Color::Selected.color(cx),
599-
)
600-
},
601-
),
610+
.child(entry.title),
602611
),
603612
)
604613
.on_click(cx.listener(move |this, _, _, cx| {
@@ -610,7 +619,6 @@ impl SettingsWindow {
610619
}),
611620
)
612621
.track_scroll(self.list_handle.clone())
613-
.gap_1_5()
614622
.size_full()
615623
.flex_grow(),
616624
)
@@ -622,7 +630,7 @@ impl SettingsWindow {
622630
window: &mut Window,
623631
cx: &mut Context<SettingsWindow>,
624632
) -> Div {
625-
v_flex().gap_4().py_4().children(
633+
v_flex().gap_4().children(
626634
page.items
627635
.iter()
628636
.map(|item| item.render(self.current_file.clone(), window, cx)),
@@ -655,21 +663,21 @@ impl SettingsWindow {
655663
impl Render for SettingsWindow {
656664
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
657665
div()
658-
.size_full()
659-
.bg(cx.theme().colors().background)
660666
.flex()
661667
.flex_row()
668+
.size_full()
669+
.bg(cx.theme().colors().background)
662670
.text_color(cx.theme().colors().text)
663-
.child(self.render_nav(window, cx).w(px(300.0)))
664-
.child(Divider::vertical().color(ui::DividerColor::BorderVariant))
671+
.child(self.render_nav(window, cx))
665672
.child(
666673
v_flex()
667-
.bg(cx.theme().colors().editor_background)
674+
.w_full()
675+
.pt_4()
668676
.px_6()
669-
.py_2()
677+
.gap_4()
678+
.bg(cx.theme().colors().editor_background)
670679
.child(self.render_files(window, cx))
671-
.child(self.render_page(self.current_page(), window, cx))
672-
.w_full(),
680+
.child(self.render_page(self.current_page(), window, cx)),
673681
)
674682
}
675683
}

0 commit comments

Comments
 (0)