From d2e70ea75c012349ea23d3271069df79771c237a Mon Sep 17 00:00:00 2001 From: yenharvey Date: Tue, 20 Oct 2026 17:34:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=82=AC=E6=B5=AE=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9D=A1=E5=A4=A7=E5=B0=8F=E4=B8=8D=E5=86=8D=E8=B7=9F=E5=80=99?= =?UTF-8?q?=E9=80=89=E5=AD=97=E5=8F=B7=EF=BC=8C=E5=8F=A6=E8=AE=BE=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F=E6=BB=91=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 候选字号调大后状态条跟着放大,比候选窗口还显眼(用户群反馈)。 状态条改按主题原样画,大小由 [status_bar] size(60%–150%,缺省 100%)单独定,设置的中英文页加滑块。 百分比滑块挪到共用控件,键位提示与状态条共用。 --- apps/settings/src/view/pages/input.rs | 33 +++--------------- apps/settings/src/view/pages/language.rs | 12 +++++-- apps/settings/src/view/parts/controls.rs | 27 ++++++++++++-- apps/windows/server/src/dispatch/config.rs | 4 +++ .../windows/server/src/dispatch/status/mod.rs | 1 + .../server/src/dispatch/status/view.rs | 3 ++ apps/windows/server/src/ui/painter/mod.rs | 6 ++-- apps/windows/server/src/ui/status/mod.rs | 1 + crates/qingjian-platform/src/config/mod.rs | 2 ++ .../src/config/status_bar.rs | 23 +++++++++++- .../src/renderer/status/mod.rs | 4 +-- crates/qingjian-render/src/theme/mod.rs | 2 +- crates/qingjian-render/tests/snapshots.rs | 9 ----- .../macos/large-text-status-light.png | Bin 12713 -> 0 bytes .../tests/snapshots/macos/metrics.txt | 1 - .../windows/large-text-status-light.png | Bin 12330 -> 0 bytes .../tests/snapshots/windows/metrics.txt | 1 - crates/qingjian-render/tests/theme/status.rs | 23 +++++++++++- docs/design/theme.md | 2 +- docs/user/input/english-mode.md | 2 +- docs/user/settings/preferences.md | 3 +- 21 files changed, 104 insertions(+), 55 deletions(-) delete mode 100644 crates/qingjian-render/tests/snapshots/macos/large-text-status-light.png delete mode 100644 crates/qingjian-render/tests/snapshots/windows/large-text-status-light.png diff --git a/apps/settings/src/view/pages/input.rs b/apps/settings/src/view/pages/input.rs index 71c6e683..63f7a319 100644 --- a/apps/settings/src/view/pages/input.rs +++ b/apps/settings/src/view/pages/input.rs @@ -2,9 +2,7 @@ use bamboo_slip::taffy::LengthPercentage; use bamboo_slip::taffy::{Dimension, FlexDirection, FlexWrap, NodeId, Rect, Size, Style}; -use bamboo_slip::{ - Checkbox, RenderError, SettingRow, Slider, Switch, Ui, Visual, group, section_title, -}; +use bamboo_slip::{Checkbox, RenderError, SettingRow, Switch, Ui, Visual, group, section_title}; use qingjian_platform::{KeyHintMode, Scheme, code_schemes}; use super::shortcuts; @@ -13,7 +11,7 @@ use crate::message::{Message, Popup}; use crate::shortcut::Shortcut; use crate::support::Feature; use crate::view::Page; -use crate::view::parts::controls::{select, toggle_info, toggle_with}; +use crate::view::parts::controls::{percent_slider, select, toggle_info, toggle_with}; use crate::view::parts::lists::{entry_row, import_row}; use crate::view::parts::menus::{CODE_OFF, scheme_options}; @@ -150,7 +148,7 @@ fn key_hint(ui: &mut Ui, page: &Page) -> Result<[NodeId; 3], RenderErro let size = percent_slider( ui, page, - ("键位提示大小", "key_hint_size"), + ("键位提示大小", ("general", "key_hint_size")), general.key_hint_size(), (60.0, 150.0), off, @@ -158,7 +156,7 @@ fn key_hint(ui: &mut Ui, page: &Page) -> Result<[NodeId; 3], RenderErro let opacity = percent_slider( ui, page, - ("键位提示透明度", "key_hint_opacity"), + ("键位提示透明度", ("general", "key_hint_opacity")), general.key_hint_opacity(), (30.0, 100.0), off, @@ -166,29 +164,6 @@ fn key_hint(ui: &mut Ui, page: &Page) -> Result<[NodeId; 3], RenderErro Ok([mode, size, opacity]) } -/// 一行百分比滑块,步长 5%:`ratio` 是当前倍数(1 为 100%),拖到的值按整数百分比写进 `[general]`。 -fn percent_slider( - ui: &mut Ui, - page: &Page, - (title, key): (&str, &'static str), - ratio: f32, - (min, max): (f32, f32), - disabled: bool, -) -> Result { - let percent = (ratio * 100.0).round(); - let text = format!("{percent:.0}%"); - let slider = Slider::new(percent, min, max) - .step(5.0) - .label(&text) - .disabled(disabled) - .build(ui, &page.theme, key, move |value| { - Message::set("general", key, value.round() as i64) - })?; - SettingRow::new(title) - .control(slider) - .build(ui, &page.theme) -} - /// 辅码:开关、显示、触发键,再一组码表(随包的、导入的、导入按钮)。 fn aux_code(ui: &mut Ui, page: &Page) -> Result, RenderError> { let theme = &page.theme; diff --git a/apps/settings/src/view/pages/language.rs b/apps/settings/src/view/pages/language.rs index 8a054f26..408106fa 100644 --- a/apps/settings/src/view/pages/language.rs +++ b/apps/settings/src/view/pages/language.rs @@ -8,7 +8,7 @@ use crate::message::Message; use crate::support::Feature; use crate::view::Page; use crate::view::parts::actions::with_notice; -use crate::view::parts::controls::{choice, toggle, toggle_info}; +use crate::view::parts::controls::{choice, percent_slider, toggle, toggle_info}; /// 全角 / 半角两档,配置里是布尔。 const WIDTHS: [bool; 2] = [true, false]; @@ -162,8 +162,16 @@ pub fn language(ui: &mut Ui, page: &Page) -> Result, Render ("status_bar", "enabled"), config.status_bar.enabled, )?; + let size = percent_slider( + ui, + page, + ("状态条大小", ("status_bar", "size")), + config.status_bar.size(), + (60.0, 150.0), + !config.status_bar.enabled, + )?; out.push(section_title(ui, theme, "状态条")?); - out.push(group(ui, theme, &[status])?); + out.push(group(ui, theme, &[status, size])?); } Ok(out) } diff --git a/apps/settings/src/view/parts/controls.rs b/apps/settings/src/view/parts/controls.rs index f74e3f05..9e586365 100644 --- a/apps/settings/src/view/parts/controls.rs +++ b/apps/settings/src/view/parts/controls.rs @@ -1,7 +1,7 @@ -//! 各页共用的几种设置行:开关、分段选择、下拉框。 +//! 各页共用的几种设置行:开关、分段选择、下拉框、百分比滑块。 use bamboo_slip::taffy::NodeId; -use bamboo_slip::{RenderError, Segmented, Select, SettingRow, Switch, Ui}; +use bamboo_slip::{RenderError, Segmented, Select, SettingRow, Slider, Switch, Ui}; use super::menus::anchor; use crate::message::{Message, Popup}; @@ -98,3 +98,26 @@ pub fn select( .disabled(disabled) .build(ui, &page.theme, anchor(popup), Message::OpenMenu(popup)) } + +/// 一行百分比滑块,步长 5%:`ratio` 是当前倍数(1 为 100%),拖到的值按整数百分比写进 `[section] key`。 +pub fn percent_slider( + ui: &mut Ui, + page: &Page, + (title, (section, key)): (&str, (&'static str, &'static str)), + ratio: f32, + (min, max): (f32, f32), + disabled: bool, +) -> Result { + let percent = (ratio * 100.0).round(); + let text = format!("{percent:.0}%"); + let slider = Slider::new(percent, min, max) + .step(5.0) + .label(&text) + .disabled(disabled) + .build(ui, &page.theme, key, move |value| { + Message::set(section, key, value.round() as i64) + })?; + SettingRow::new(title) + .control(slider) + .build(ui, &page.theme) +} diff --git a/apps/windows/server/src/dispatch/config.rs b/apps/windows/server/src/dispatch/config.rs index 09ba0ac3..2f31c8c2 100644 --- a/apps/windows/server/src/dispatch/config.rs +++ b/apps/windows/server/src/dispatch/config.rs @@ -118,6 +118,9 @@ pub struct RouterConfig { /// 状态条记住的位置(`[status_bar] x` / `y`,内容左上角物理像素)。 pub status_pos: Option<(i32, i32)>, + /// 状态条大小(`[status_bar] size`,百分比,已收到 60–150)。 + pub status_size: u8, + /// 拼音侧方案(`[general] scheme`)。 pub scheme: Scheme, @@ -208,6 +211,7 @@ impl From<&Config> for RouterConfig { predict: config.shortcut.predict, status_enabled: config.status_bar.enabled, status_pos: config.status_bar.x.zip(config.status_bar.y), + status_size: config.status_bar.size.clamp(60, 150), scheme: config.general.scheme(), traditional: config.general.traditional() != TraditionalVariant::Off, aux_code_key: config.general.aux_code_key(), diff --git a/apps/windows/server/src/dispatch/status/mod.rs b/apps/windows/server/src/dispatch/status/mod.rs index dea16398..a21bff3e 100644 --- a/apps/windows/server/src/dispatch/status/mod.rs +++ b/apps/windows/server/src/dispatch/status/mod.rs @@ -130,6 +130,7 @@ impl Router { full_width: self.full_width_for(english), appearance: self.config.appearance, anchor: self.config.status_pos, + size: self.config.status_size, mode: self.input_mode(), }); } diff --git a/apps/windows/server/src/dispatch/status/view.rs b/apps/windows/server/src/dispatch/status/view.rs index aba1d9a1..fd8997df 100644 --- a/apps/windows/server/src/dispatch/status/view.rs +++ b/apps/windows/server/src/dispatch/status/view.rs @@ -22,6 +22,9 @@ pub struct StatusView { /// 配置里记住的内容左上角物理像素;`None` 首次按屏幕右下角摆。 pub anchor: Option<(i32, i32)>, + /// 大小(百分比,100 为原大),与候选字号无关。 + pub size: u8, + /// 输入状态,给节点树画法的主题显示(与候选窗口同一份)。 pub mode: Mode, } diff --git a/apps/windows/server/src/ui/painter/mod.rs b/apps/windows/server/src/ui/painter/mod.rs index ee69d3b9..994c8231 100644 --- a/apps/windows/server/src/ui/painter/mod.rs +++ b/apps/windows/server/src/ui/painter/mod.rs @@ -139,16 +139,18 @@ impl Painter { self.renderer.forget(); } - /// 画状态条。 + /// 画状态条;`size` 是设置里的大小(百分比)。 pub(super) fn render_status( &mut self, cells: &[StatusCell], mode: &Mode, dark: bool, dpi: u32, + size: u8, ) -> Option { + let scale = scale(dpi) * f32::from(size) / 100.0; self.renderer - .render_status(cells, mode, &self.theme.with_dark(dark), scale(dpi)) + .render_status(cells, mode, &self.theme.with_dark(dark), scale) .inspect_err(|error| tracing::warn!(%error, "状态条渲染失败")) .ok() } diff --git a/apps/windows/server/src/ui/status/mod.rs b/apps/windows/server/src/ui/status/mod.rs index 93f1aaea..0af74152 100644 --- a/apps/windows/server/src/ui/status/mod.rs +++ b/apps/windows/server/src/ui/status/mod.rs @@ -243,6 +243,7 @@ impl StatusBar { &view.mode, self.dark.get(), self.dpi.get(), + view.size, ), _ => None, } diff --git a/crates/qingjian-platform/src/config/mod.rs b/crates/qingjian-platform/src/config/mod.rs index b7faa937..7b24ffc6 100644 --- a/crates/qingjian-platform/src/config/mod.rs +++ b/crates/qingjian-platform/src/config/mod.rs @@ -421,6 +421,8 @@ enabled = false # 记住的屏幕位置(物理像素,拖动后自动写入);留空则首次出现在屏幕右下角 # x = 0 # y = 0 +# 大小(百分比,60–150);不跟候选字号走 +size = 100 [update] # 检查更新:每天向官网(qingjian.app)读一次版本索引,有新版在菜单与设置的「关于」页提示;请求不带任何标识,不自动下载安装 diff --git a/crates/qingjian-platform/src/config/status_bar.rs b/crates/qingjian-platform/src/config/status_bar.rs index b7763f9c..b29a123d 100644 --- a/crates/qingjian-platform/src/config/status_bar.rs +++ b/crates/qingjian-platform/src/config/status_bar.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; /// `[status_bar]` 分节:桌面上常驻、可拖动的悬浮状态条(显示当前中 / 英,可选双拼方案)。 /// 与任务栏的中 / 英指示器(语言栏按钮)并存,各是一条。位置记在这里,重启后回到原处。 -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] pub struct StatusBarConfig { /// 是否显示悬浮状态条。缺省关。 @@ -13,4 +13,25 @@ pub struct StatusBarConfig { /// 记住的屏幕纵坐标(内容左上角物理像素)。 pub y: Option, + + /// 大小(百分比,60–150),见 [`Self::size`]。与候选字号无关。 + pub size: u8, +} + +impl Default for StatusBarConfig { + fn default() -> Self { + Self { + enabled: false, + x: None, + y: None, + size: 100, + } + } +} + +impl StatusBarConfig { + /// 缩放倍数,写出范围的收到 60%–150%。 + pub fn size(&self) -> f32 { + f32::from(self.size.clamp(60, 150)) / 100.0 + } } diff --git a/crates/qingjian-render/src/renderer/status/mod.rs b/crates/qingjian-render/src/renderer/status/mod.rs index d74bfe08..87ba42ae 100644 --- a/crates/qingjian-render/src/renderer/status/mod.rs +++ b/crates/qingjian-render/src/renderer/status/mod.rs @@ -66,7 +66,7 @@ impl Metrics<'_> { impl Renderer { /// 画状态条,返回位图与各格右边界(供点击命中)。`mode` 给节点树画法的主题显示中 / 英等状态。 - /// 设置里改了候选字号时整条按同一比例放大缩小。 + /// 不跟设置里的候选字号走(字号调大了状态条会比候选窗还显眼),大小由调用方乘进 `scale`。 /// 固定排法:每格宽 = 内容宽 + 两侧内边距,高 = 行高 + 内边距。 pub fn render_status( &mut self, @@ -75,8 +75,6 @@ impl Renderer { theme: &Theme, scale: f32, ) -> Result { - // 整条按候选字的比例缩放:去掉设置里的字号再整体乘倍数,图标、边距、点击边界跟文字一起变,与用哪个文字样式无关 - let scale = scale * theme.candidate_scale(); let theme = &theme.with_text_sizes(TextSizes::default()); self.stage.text().use_families(theme.families()); let spec = &theme.file().status; diff --git a/crates/qingjian-render/src/theme/mod.rs b/crates/qingjian-render/src/theme/mod.rs index ad6ce05c..dff2a464 100644 --- a/crates/qingjian-render/src/theme/mod.rs +++ b/crates/qingjian-render/src/theme/mod.rs @@ -410,7 +410,7 @@ impl Theme { self.animations } - /// 设置里的候选字号相对主题的比例:表格行高与状态条整体跟着它缩放。 + /// 设置里的候选字号相对主题的比例:表格行高与键位提示键盘跟着它缩放。 pub(crate) fn candidate_scale(&self) -> f32 { self.sizes.ratio("candidate", |name| self.theme_size(name)) } diff --git a/crates/qingjian-render/tests/snapshots.rs b/crates/qingjian-render/tests/snapshots.rs index 66ac0ac1..a08f4a0b 100644 --- a/crates/qingjian-render/tests/snapshots.rs +++ b/crates/qingjian-render/tests/snapshots.rs @@ -171,15 +171,6 @@ fn render_all(mut renderer: Renderer) -> Vec { ); shots.push(shot(format!("{name}-nihao-vertical-light"), rendered, None)); } - // 状态条整条跟候选字号缩放:字、齿轮、边距一起变 - let status = renderer - .render_status(&scenes::status_cells(), &Mode::default(), &large, 2.0) - .unwrap(); - shots.push(shot( - "large-text-status-light".to_owned(), - status.rendered, - Some(&status.cell_edges), - )); shots } diff --git a/crates/qingjian-render/tests/snapshots/macos/large-text-status-light.png b/crates/qingjian-render/tests/snapshots/macos/large-text-status-light.png deleted file mode 100644 index b36f51f6be1b8601a9251dc94e683eff5ac7dc23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12713 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%0ABLz66Mm0krKVjmj_W4yRZJEA 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 f%l|