From 3b2746e0ba2e8aea6809ecc4b5b3dbcfb3e9e22d Mon Sep 17 00:00:00 2001 From: Ylin Date: Thu, 4 Dec 2025 14:47:11 +0800 Subject: [PATCH] setting: Supplement subscription `InputEvent` for number_input (#1740) --- crates/story/src/settings_story.rs | 8 ++- crates/ui/src/setting/fields/number.rs | 76 ++++++++++++++++++-------- 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/crates/story/src/settings_story.rs b/crates/story/src/settings_story.rs index 2be02603..2968e96b 100644 --- a/crates/story/src/settings_story.rs +++ b/crates/story/src/settings_story.rs @@ -266,7 +266,9 @@ impl SettingsStory { ) .default_value(default_settings.font_size), ) - .description("Adjust the font size for better readability."), + .description( + "Adjust the font size for better readability between 8 and 72.", + ), ) .item( SettingItem::new( @@ -284,7 +286,9 @@ impl SettingsStory { ) .default_value(default_settings.line_height), ) - .description("Adjust the line height for better readability."), + .description( + "Adjust the line height for better readability between 8 and 32.", + ), ), SettingGroup::new().title("Other").items(vec![ SettingItem::render(|options, _, _| { diff --git a/crates/ui/src/setting/fields/number.rs b/crates/ui/src/setting/fields/number.rs index 382807d5..b44712c9 100644 --- a/crates/ui/src/setting/fields/number.rs +++ b/crates/ui/src/setting/fields/number.rs @@ -2,12 +2,12 @@ use std::rc::Rc; use gpui::{ AnyElement, App, AppContext as _, Entity, IntoElement, SharedString, StyleRefinement, Styled, - Window, prelude::FluentBuilder as _, + Subscription, Window, prelude::FluentBuilder as _, }; use crate::{ AxisExt, Sizable, StyledExt, - input::{InputState, NumberInput, NumberInputEvent}, + input::{InputEvent, InputState, NumberInput, NumberInputEvent, StepAction}, setting::{ AnySettingField, RenderOptions, fields::{SettingFieldRender, get_value, set_value}, @@ -48,7 +48,8 @@ impl NumberField { struct State { input: Entity, - _subscription: gpui::Subscription, + initial_value: f64, + _subscriptions: Vec, } impl SettingFieldRender for NumberField { @@ -74,31 +75,62 @@ impl SettingFieldRender for NumberField { |window, cx| { let input = cx.new(|cx| InputState::new(window, cx).default_value(value.to_string())); - let _subscription = cx.subscribe_in(&input, window, { - move |_, input, event: &NumberInputEvent, window, cx| match event { - NumberInputEvent::Step(action) => input.update(cx, |input, cx| { - let value = input.value(); - if let Ok(value) = value.parse::() { - let new_value = - if *action == crate::input::StepAction::Increment { - (value + num_options.step).min(num_options.max) + let _subscriptions = vec![ + cx.subscribe_in(&input, window, { + move |_, input, event: &NumberInputEvent, window, cx| match event { + NumberInputEvent::Step(action) => input.update(cx, |input, cx| { + let value = input.value(); + if let Ok(value) = value.parse::() { + let new_value = if *action == StepAction::Increment { + value + num_options.step } else { - (value - num_options.step).max(num_options.min) + value - num_options.step }; - set_value(new_value, cx); - input.set_value( - SharedString::from(new_value.to_string()), - window, - cx, - ); + input.set_value( + SharedString::from(new_value.to_string()), + window, + cx, + ); + } + }), + } + }), + cx.subscribe_in(&input, window, { + move |state: &mut State, input, event: &InputEvent, window, cx| { + match event { + InputEvent::Change => { + input.update(cx, |input, cx| { + let value = input.value(); + if value == state.initial_value.to_string() { + return; + } + + if let Ok(value) = value.parse::() { + let clamp_value = + value.clamp(num_options.min, num_options.max); + + set_value(clamp_value, cx); + state.initial_value = clamp_value; + if clamp_value != value { + input.set_value( + SharedString::from(clamp_value.to_string()), + window, + cx, + ); + } + } + }); + } + _ => {} } - }), - } - }); + } + }), + ]; State { input, - _subscription, + initial_value: value, + _subscriptions, } }, )