From 4b429033e74e8b6f5721d87ca9cd80af33d275e3 Mon Sep 17 00:00:00 2001 From: Delvin <64721581+delvin02@users.noreply.github.com> Date: Wed, 22 Oct 2025 05:50:42 +1030 Subject: [PATCH] settings_ui: Correct stepper increment and enforce max value for Centered Layout Padding (#40751) Closes #40748 This PR improves the Centered Layout Padding in settings ui by limiting the numeric stepper to be within valid values and adding a custom schema generated to improve the JSON LSP completions and warnings when editing the setting field manually. Release Notes: - settings ui: limit stepper increment for centered padding between 0 and 0.4 and increment by 0.05 now --------- Co-authored by: Anthony Eid --- .../settings/src/settings_content/editor.rs | 62 +++++++++++++++++++ .../src/settings_content/workspace.rs | 12 ++-- crates/settings_ui/src/settings_ui.rs | 1 + crates/ui_input/src/number_field.rs | 10 ++- crates/workspace/src/workspace.rs | 20 +++--- 5 files changed, 89 insertions(+), 16 deletions(-) diff --git a/crates/settings/src/settings_content/editor.rs b/crates/settings/src/settings_content/editor.rs index f5ec805c72d054744477c73cefa50b9bc3fcc7d1..920f02a0f6597454c82d421247787e8ad6f7f74b 100644 --- a/crates/settings/src/settings_content/editor.rs +++ b/crates/settings/src/settings_content/editor.rs @@ -850,3 +850,65 @@ impl From for InactiveOpacity { Self(x) } } + +/// Centered layout related setting (left/right). +/// +/// Valid range: 0.0 to 0.4 +/// Default: 2.0 +#[derive( + Clone, + Copy, + Debug, + Serialize, + Deserialize, + MergeFrom, + PartialEq, + PartialOrd, + derive_more::FromStr, +)] +#[serde(transparent)] +pub struct CenteredPaddingSettings( + #[serde(serialize_with = "serialize_f32_with_two_decimal_places")] pub f32, +); + +impl CenteredPaddingSettings { + pub const MIN_PADDING: f32 = 0.0; + // This is an f64 so serde_json can give a type hint without random numbers in the back + pub const DEFAULT_PADDING: f64 = 0.2; + pub const MAX_PADDING: f32 = 0.4; +} + +impl Display for CenteredPaddingSettings { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:.2}", self.0) + } +} + +impl From for CenteredPaddingSettings { + fn from(x: f32) -> Self { + Self(x) + } +} + +impl Default for CenteredPaddingSettings { + fn default() -> Self { + Self(Self::DEFAULT_PADDING as f32) + } +} + +impl schemars::JsonSchema for CenteredPaddingSettings { + fn schema_name() -> std::borrow::Cow<'static, str> { + "CenteredPaddingSettings".into() + } + + fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + use schemars::json_schema; + json_schema!({ + "type": "number", + "minimum": Self::MIN_PADDING, + "maximum": Self::MAX_PADDING, + "default": Self::DEFAULT_PADDING, + "description": "Centered layout related setting (left/right)." + }) + } +} diff --git a/crates/settings/src/settings_content/workspace.rs b/crates/settings/src/settings_content/workspace.rs index a76a1347d4431d9479abed6ab7aa5a893f0a438e..c901d7010b37c685180ca67a3c4775da41be87ee 100644 --- a/crates/settings/src/settings_content/workspace.rs +++ b/crates/settings/src/settings_content/workspace.rs @@ -7,8 +7,8 @@ use serde_with::skip_serializing_none; use settings_macros::MergeFrom; use crate::{ - DelayMs, DockPosition, DockSide, InactiveOpacity, ScrollbarSettingsContent, ShowIndentGuides, - serialize_optional_f32_with_two_decimal_places, + CenteredPaddingSettings, DelayMs, DockPosition, DockSide, InactiveOpacity, + ScrollbarSettingsContent, ShowIndentGuides, serialize_optional_f32_with_two_decimal_places, }; #[skip_serializing_none] @@ -463,22 +463,20 @@ pub enum PaneSplitDirectionVertical { Right, } -#[skip_serializing_none] #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Default)] #[serde(rename_all = "snake_case")] +#[skip_serializing_none] pub struct CenteredLayoutSettings { /// The relative width of the left padding of the central pane from the /// workspace when the centered layout is used. /// /// Default: 0.2 - #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")] - pub left_padding: Option, + pub left_padding: Option, // The relative width of the right padding of the central pane from the // workspace when the centered layout is used. /// /// Default: 0.2 - #[serde(serialize_with = "serialize_optional_f32_with_two_decimal_places")] - pub right_padding: Option, + pub right_padding: Option, } #[derive( diff --git a/crates/settings_ui/src/settings_ui.rs b/crates/settings_ui/src/settings_ui.rs index 0c287a16fa6fce5182eb01040571ee8ac68624b7..e4b92464766e4d87e9f3afe6d1d639716b5ac5ab 100644 --- a/crates/settings_ui/src/settings_ui.rs +++ b/crates/settings_ui/src/settings_ui.rs @@ -420,6 +420,7 @@ fn init_renderers(cx: &mut App) { .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) + .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_number_field) .add_basic_renderer::(render_dropdown) diff --git a/crates/ui_input/src/number_field.rs b/crates/ui_input/src/number_field.rs index 3ae1d77c0400ea474864087bf3a4a5f4705a2e41..929b3851a9127f7ba8f44d954f32ddedcdfa68b6 100644 --- a/crates/ui_input/src/number_field.rs +++ b/crates/ui_input/src/number_field.rs @@ -8,7 +8,7 @@ use std::{ use editor::{Editor, EditorStyle}; use gpui::{ClickEvent, Entity, FocusHandle, Focusable, FontWeight, Modifiers}; -use settings::{CodeFade, DelayMs, InactiveOpacity, MinimumContrast}; +use settings::{CenteredPaddingSettings, CodeFade, DelayMs, InactiveOpacity, MinimumContrast}; use ui::prelude::*; #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] @@ -71,6 +71,14 @@ impl_newtype_numeric_stepper!(CodeFade, 0.1, 0.2, 0.05, 0.0, 0.9); impl_newtype_numeric_stepper!(InactiveOpacity, 0.1, 0.2, 0.05, 0.0, 1.0); impl_newtype_numeric_stepper!(MinimumContrast, 1., 10., 0.5, 0.0, 106.0); impl_newtype_numeric_stepper!(DelayMs, 100, 500, 10, 0, 2000); +impl_newtype_numeric_stepper!( + CenteredPaddingSettings, + 0.05, + 0.2, + 0.1, + CenteredPaddingSettings::MIN_PADDING, + CenteredPaddingSettings::MAX_PADDING +); macro_rules! impl_numeric_stepper_int { ($type:ident) => { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 3dc3b781175cd2f533184735d7759cb27c34930a..2c0a024158733860b6adf956e617382b16e74b16 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -83,7 +83,7 @@ use remote::{ use schemars::JsonSchema; use serde::Deserialize; use session::AppSession; -use settings::{Settings, SettingsLocation, update_settings_file}; +use settings::{CenteredPaddingSettings, Settings, SettingsLocation, update_settings_file}; use shared_screen::SharedScreen; use sqlez::{ bindable::{Bind, Column, StaticColumnCount}, @@ -1199,9 +1199,6 @@ struct FollowerView { } impl Workspace { - const DEFAULT_PADDING: f32 = 0.2; - const MAX_PADDING: f32 = 0.4; - pub fn new( workspace_id: Option, project: Entity, @@ -5938,8 +5935,11 @@ impl Workspace { fn adjust_padding(padding: Option) -> f32 { padding - .unwrap_or(Self::DEFAULT_PADDING) - .clamp(0.0, Self::MAX_PADDING) + .unwrap_or(CenteredPaddingSettings::default().0) + .clamp( + CenteredPaddingSettings::MIN_PADDING, + CenteredPaddingSettings::MAX_PADDING, + ) } fn render_dock( @@ -6423,8 +6423,12 @@ impl Render for Workspace { let paddings = if centered_layout { let settings = WorkspaceSettings::get_global(cx).centered_layout; ( - render_padding(Self::adjust_padding(settings.left_padding)), - render_padding(Self::adjust_padding(settings.right_padding)), + render_padding(Self::adjust_padding( + settings.left_padding.map(|padding| padding.0), + )), + render_padding(Self::adjust_padding( + settings.right_padding.map(|padding| padding.0), + )), ) } else { (None, None)