Detailed changes
@@ -1,6 +1,6 @@
use crate::{
- self as gpui3, hsla, point, px, relative, rems, AlignItems, Display, Fill, FlexDirection, Hsla,
- JustifyContent, Length, Position, SharedString, StyleRefinement,
+ self as gpui3, hsla, point, px, relative, rems, AbsoluteLength, AlignItems, Display, Fill,
+ FlexDirection, Hsla, JustifyContent, Length, Position, Rems, SharedString, StyleRefinement,
};
use crate::{BoxShadow, TextStyleRefinement};
use smallvec::smallvec;
@@ -350,6 +350,16 @@ pub trait Styled {
self
}
+ fn text_size(mut self, size: Rems) -> Self
+ where
+ Self: Sized,
+ {
+ self.text_style()
+ .get_or_insert_with(Default::default)
+ .font_size = Some(size);
+ self
+ }
+
fn text_xs(mut self) -> Self
where
Self: Sized,
@@ -3,10 +3,10 @@ use std::marker::PhantomData;
use gpui3::{div, Div};
use crate::prelude::*;
+use crate::settings::user_settings;
use crate::theme::theme;
use crate::{
- h_stack, token, v_stack, Avatar, Icon, IconColor, IconElement, IconSize, Label, LabelColor,
- LabelSize,
+ h_stack, v_stack, Avatar, Icon, IconColor, IconElement, IconSize, Label, LabelColor, LabelSize,
};
#[derive(Clone, Copy, Default, Debug, PartialEq)]
@@ -94,7 +94,6 @@ impl<S: 'static + Send + Sync + Clone> ListHeader<S> {
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
let theme = theme(cx);
- let token = token();
let system_color = SystemColor::new();
let color = ThemeColor::new(cx);
@@ -166,7 +165,6 @@ impl<S: 'static + Send + Sync + Clone> ListSubHeader<S> {
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
let theme = theme(cx);
- let token = token();
h_stack().flex_1().w_full().relative().py_1().child(
div()
@@ -351,7 +349,6 @@ impl<S: 'static + Send + Sync + Clone> ListEntry<S> {
cx: &mut ViewContext<S>,
) -> Option<impl Element<ViewState = S>> {
let theme = theme(cx);
- let token = token();
let disclosure_control_icon = if let Some(ToggleState::Toggled) = self.toggle {
IconElement::new(Icon::ChevronDown)
@@ -374,9 +371,9 @@ impl<S: 'static + Send + Sync + Clone> ListEntry<S> {
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
let theme = theme(cx);
- let token = token();
let system_color = SystemColor::new();
let color = ThemeColor::new(cx);
+ let setting = user_settings();
let left_content = match self.left_content {
Some(LeftContent::Icon(i)) => Some(
@@ -408,7 +405,7 @@ impl<S: 'static + Send + Sync + Clone> ListEntry<S> {
// .ml(rems(0.75 * self.indent_level as f32))
.children((0..self.indent_level).map(|_| {
div()
- .w(token.list_indent_depth)
+ .w(setting.list_indent_depth())
.h_full()
.flex()
.justify_center()
@@ -484,7 +481,6 @@ impl<S: 'static + Send + Sync + Clone> List<S> {
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
let theme = theme(cx);
- let token = token();
let is_toggleable = self.toggleable != Toggleable::NotToggleable;
let is_toggled = Toggleable::is_toggled(&self.toggleable);
@@ -3,8 +3,9 @@ use std::marker::PhantomData;
use gpui3::{AbsoluteLength, AnyElement};
use smallvec::SmallVec;
+use crate::settings::user_settings;
+use crate::v_stack;
use crate::{prelude::*, theme};
-use crate::{token, v_stack};
#[derive(Default, Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum PanelAllowedSides {
@@ -53,14 +54,14 @@ pub struct Panel<S: 'static + Send + Sync> {
impl<S: 'static + Send + Sync> Panel<S> {
pub fn new(scroll_state: ScrollState) -> Self {
- let token = token();
+ let setting = user_settings();
Self {
state_type: PhantomData,
scroll_state,
current_side: PanelSide::default(),
allowed_sides: PanelAllowedSides::default(),
- initial_width: token.default_panel_size,
+ initial_width: setting.default_panel_size(),
width: None,
children: SmallVec::new(),
}
@@ -96,7 +97,6 @@ impl<S: 'static + Send + Sync> Panel<S> {
}
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
- let token = token();
let theme = theme(cx);
let panel_base;
@@ -4,6 +4,7 @@ use std::sync::Arc;
use gpui3::{view, Context, View};
use crate::prelude::*;
+use crate::settings::user_settings;
use crate::{
random_players_with_call_status, theme, Avatar, Button, Icon, IconButton, IconColor, MicStatus,
PlayerStack, PlayerWithCallStatus, ScreenShareStatus, ToolDivider, TrafficLights,
@@ -93,6 +94,9 @@ impl TitleBar {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
let theme = theme(cx);
+ let color = ThemeColor::new(cx);
+ let setting = user_settings();
+
// let has_focus = cx.window_is_active();
let has_focus = true;
@@ -107,8 +111,7 @@ impl TitleBar {
.items_center()
.justify_between()
.w_full()
- .h_8()
- .bg(theme.lowest.base.default.background)
+ .bg(color.background)
.child(
div()
.flex()
@@ -123,6 +126,9 @@ impl TitleBar {
.flex()
.items_center()
.gap_1()
+ .when(setting.titlebar_show_project_owner(), |this| {
+ this.child(Button::new("iamnbutler"))
+ })
.child(Button::new("zed"))
.child(Button::new("nate/gpui2-ui-components")),
)
@@ -1,7 +1,7 @@
use std::marker::PhantomData;
use crate::prelude::*;
-use crate::{theme, token, SystemColor};
+use crate::{theme, SystemColor};
#[derive(Clone, Copy)]
enum TrafficLightColor {
@@ -62,7 +62,6 @@ impl<S: 'static + Send + Sync> TrafficLights<S> {
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
let theme = theme(cx);
- let token = token();
div()
.flex()
@@ -1,9 +1,10 @@
use std::marker::PhantomData;
use std::sync::Arc;
-use gpui3::{DefiniteLength, Hsla, Interactive, MouseButton, WindowContext};
+use gpui3::{rems, DefiniteLength, Hsla, Interactive, MouseButton, WindowContext};
use crate::prelude::*;
+use crate::settings::user_settings;
use crate::{h_stack, Icon, IconColor, IconElement, Label, LabelColor, LabelSize};
#[derive(Default, PartialEq, Clone, Copy)]
@@ -148,11 +149,11 @@ impl<S: 'static + Send + Sync + Clone> Button<S> {
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
let icon_color = self.icon_color();
let border_color = self.border_color(cx);
+ let setting = user_settings();
let mut el = h_stack()
- .h_6()
- .px_1()
- .items_center()
+ .p_1()
+ .text_size(rems(1.125 * setting.ui_scale()))
.rounded_md()
.border()
.border_color(border_color)
@@ -4,6 +4,7 @@ mod components;
mod element_ext;
mod elements;
pub mod prelude;
+mod settings;
mod static_data;
mod theme;
@@ -9,34 +9,28 @@ use gpui3::{hsla, rems, rgb, AbsoluteLength, Hsla};
use strum::EnumIter;
#[derive(Clone, Copy)]
-pub struct Token {
+pub struct FakeSettings {
pub list_indent_depth: AbsoluteLength,
pub default_panel_size: AbsoluteLength,
- pub state_hover_background: Hsla,
- pub state_active_background: Hsla,
}
-impl Default for Token {
+impl Default for FakeSettings {
fn default() -> Self {
Self {
list_indent_depth: rems(0.3).into(),
default_panel_size: AbsoluteLength::Rems(rems(16.)),
- state_hover_background: hsla(0.0, 0.0, 0.0, 0.08),
- state_active_background: hsla(0.0, 0.0, 0.0, 0.16),
}
}
}
-pub fn token() -> Token {
- Token::default()
-}
-
#[derive(Default)]
pub struct SystemColor {
pub transparent: Hsla,
pub mac_os_traffic_light_red: Hsla,
pub mac_os_traffic_light_yellow: Hsla,
pub mac_os_traffic_light_green: Hsla,
+ pub state_hover_background: Hsla,
+ pub state_active_background: Hsla,
}
impl SystemColor {
@@ -46,6 +40,8 @@ impl SystemColor {
mac_os_traffic_light_red: rgb::<Hsla>(0xEC695E),
mac_os_traffic_light_yellow: rgb::<Hsla>(0xF4BF4F),
mac_os_traffic_light_green: rgb::<Hsla>(0x62C554),
+ state_hover_background: hsla(0.0, 0.0, 0.0, 0.08),
+ state_active_background: hsla(0.0, 0.0, 0.0, 0.16),
}
}
pub fn color(&self) -> Hsla {
@@ -62,6 +58,8 @@ pub struct ThemeColor {
/// The background color of an elevated surface, like a modal, tooltip or toast.
pub elevated_surface: Hsla,
pub surface: Hsla,
+ /// Window background color
+ pub background: Hsla,
/// Default background for elements like filled buttons,
/// text fields, checkboxes, radio buttons, etc.
/// - TODO: Map to step 3.
@@ -99,6 +97,7 @@ impl ThemeColor {
border_transparent: system_color.transparent,
elevated_surface: theme.middle.base.default.background,
surface: theme.middle.base.default.background,
+ background: theme.lowest.base.default.background,
filled_element: theme.lowest.base.default.background,
filled_element_hover: theme.lowest.base.hovered.background,
filled_element_active: theme.lowest.base.active.background,
@@ -251,6 +250,23 @@ pub enum DisclosureControlVisibility {
Always,
}
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
+pub enum DisclosureControlStyle {
+ /// Shows the disclosure control only when hovered where possible.
+ ///
+ /// More compact, but not available everywhere.
+ ChevronOnHover,
+ /// Shows an icon where possible, otherwise shows a chevron.
+ ///
+ /// For example, in a file tree a folder or file icon is shown
+ /// instead of a chevron
+ Icon,
+ /// Always shows a chevron.
+ Chevron,
+ /// Completely hides the disclosure control where possible.
+ None,
+}
+
#[derive(Default, PartialEq, Copy, Clone, EnumIter, strum::Display)]
pub enum InteractionState {
#[default]
@@ -0,0 +1,102 @@
+use gpui3::{rems, AbsoluteLength};
+
+use crate::DisclosureControlStyle;
+
+// This is a fake static example of user settings overriding the default settings
+pub fn user_settings() -> Settings {
+ let mut settings = Settings::new();
+ settings.list_indent_depth = Some(rems(0.5).into());
+ settings
+}
+
+#[derive(Clone, Copy)]
+pub struct TitlebarSettings {
+ pub show_project_owner: Option<bool>,
+ pub show_git_status: Option<bool>,
+ pub show_git_controls: Option<bool>,
+}
+
+impl Default for TitlebarSettings {
+ fn default() -> Self {
+ Self {
+ show_project_owner: Some(true),
+ show_git_status: Some(true),
+ show_git_controls: Some(true),
+ }
+ }
+}
+
+#[derive(Clone, Copy)]
+pub struct Settings {
+ pub default_panel_size: Option<AbsoluteLength>,
+ pub list_disclosure_style: Option<DisclosureControlStyle>,
+ pub list_indent_depth: Option<AbsoluteLength>,
+ pub titlebar: TitlebarSettings,
+ pub ui_scale: Option<f32>,
+}
+
+// These should be merged into settings
+impl Settings {
+ pub fn new() -> Self {
+ Self {
+ titlebar: TitlebarSettings::default(),
+ list_disclosure_style: None,
+ list_indent_depth: None,
+ default_panel_size: None,
+ ui_scale: None,
+ }
+ }
+
+ pub fn titlebar_show_project_owner(&self) -> bool {
+ self.titlebar.show_project_owner.unwrap_or(
+ Settings::default()
+ .titlebar
+ .show_project_owner
+ .expect("titlebar_show_project_owner default not set."),
+ )
+ }
+
+ pub fn list_disclosure_style(&self) -> DisclosureControlStyle {
+ self.list_disclosure_style.unwrap_or(
+ Settings::default()
+ .list_disclosure_style
+ .expect("list_disclosure_style default not set."),
+ )
+ }
+
+ pub fn list_indent_depth(&self) -> AbsoluteLength {
+ self.list_indent_depth.unwrap_or(
+ Settings::default()
+ .list_indent_depth
+ .expect("list_indent_depth default not set."),
+ )
+ }
+
+ pub fn default_panel_size(&self) -> AbsoluteLength {
+ self.default_panel_size.unwrap_or(
+ Settings::default()
+ .default_panel_size
+ .expect("default_panel_size default not set."),
+ )
+ }
+
+ pub fn ui_scale(&self) -> f32 {
+ self.ui_scale.unwrap_or(
+ Settings::default()
+ .ui_scale
+ .expect("ui_scale default not set."),
+ )
+ }
+}
+
+impl Default for Settings {
+ fn default() -> Self {
+ Self {
+ titlebar: TitlebarSettings::default(),
+ list_disclosure_style: Some(DisclosureControlStyle::ChevronOnHover),
+ list_indent_depth: Some(rems(0.3).into()),
+ default_panel_size: Some(rems(16.).into()),
+ ui_scale: Some(1.),
+ }
+ }
+}