test(app-iced)+docs(appearance): 强调色「已提交」那一档的出图开关

D30 要拍「回车之后」的样子,但出图通道没有键盘(渲染第 3~4 帧就落盘)。所以把强调色
的两档取证开关(ULL_APPEARANCE_ACCENT / …_COMMIT)收进 accent 自己的模块:第二档在灌值
之后补一次 Accent::commit(),它做的正是回车那条消息(Change::AccentCommit)在状态层做的事
(State::apply 开头的 commit)。拍的因此是同一个状态,不是另一条渲染分支。

顺带两处口径订正:
- state.rs 少了 3 行(它贴 400 行硬线),强调色的 env 开关不再散在 state 里;
- rows.rs 的模块文档把「名字规则」指到 core 的
  game/saves/write/boundary::check_name(原来写的是 presenter)。
This commit is contained in:
AskaEth committed 2026-11-11 19:55:21 +08:00
1 parent f7cfc8ded6
commit ebce41b2c5
3 files changed
+29 -7

No files matched your search

@@ -38,6 +38,14 @@ use unlucky_presenter::prefs::{AccentChoice, AccentError};
/// 属于强调色自己,跟 `Accent` 放一起也更好找。语义与其它 `ULL_APPEARANCE_*` 一致——只影响这次进程。 /// 属于强调色自己,跟 `Accent` 放一起也更好找。语义与其它 `ULL_APPEARANCE_*` 一致——只影响这次进程。
pub const ENV_ACCENT: &str = "ULL_APPEARANCE_ACCENT"; pub const ENV_ACCENT: &str = "ULL_APPEARANCE_ACCENT";
/// 出图矩阵的第二档(`ULL_APPEARANCE_ACCENT_COMMIT=1`):把 [`ENV_ACCENT`] 灌进来的值当作
/// **已提交**([`Accent::commit`])。
///
/// P18 / M252:「打了一半就放着」的 `#12` 平时**不**亮红,按回车才亮。出图通道没有键盘,所以用这个
/// 开关把那一帧拍下来——它拍的是 `commit()` 之后的**同一个状态**,不是另一条渲染分支。
/// 语义同族:只影响这次进程,产品路径不读它。
pub const ENV_ACCENT_COMMIT: &str = "ULL_APPEARANCE_ACCENT_COMMIT";
/// 强调色的运行期状态(`App` 经 `pages::appearance::State` 持有一份)。 /// 强调色的运行期状态(`App` 经 `pages::appearance::State` 持有一份)。
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct Accent { pub struct Accent {
@@ -91,6 +99,20 @@ impl Accent {
} }
} }
/// 把 `ULL_APPEARANCE_ACCENT` / `ULL_APPEARANCE_ACCENT_COMMIT` 灌进来(不设 = 不动)。
///
/// 第一档 = 「像刚敲进去的」(走输入中规则);再给它 `…_COMMIT=1` 就等于「刚按下回车」。
/// 两档合起来才拍得出 P18 的对照:同一条 `#12`,回车前不亮、回车后亮红。
pub fn apply_env(&mut self) {
let Ok(value) = std::env::var(ENV_ACCENT) else {
return;
};
self.set(&value);
if std::env::var_os(ENV_ACCENT_COMMIT).is_some_and(|flag| flag != "0") {
self.commit();
}
}
/// 输入框原文。 /// 输入框原文。
#[must_use] #[must_use]
pub fn text(&self) -> &str { pub fn text(&self) -> &str {
@@ -24,7 +24,7 @@ use unlucky_presenter::prefs::{
use crate::Backend; use crate::Backend;
use super::accent::{Accent, ENV_ACCENT}; use super::accent::Accent;
use super::alpha::{self, effective_glass, effective_panel_alpha, panel_is_forced_opaque}; use super::alpha::{self, effective_glass, effective_panel_alpha, panel_is_forced_opaque};
use super::background::{self, Image, Note}; use super::background::{self, Image, Note};
use super::palette::{self, Resolved, Source}; use super::palette::{self, Resolved, Source};
@@ -135,10 +135,9 @@ impl State {
if let Some(value) = std::env::var_os(ENV_PALETTE) { if let Some(value) = std::env::var_os(ENV_PALETTE) {
self.palette_source = PaletteSource::from_key_value(&value.to_string_lossy()); self.palette_source = PaletteSource::from_key_value(&value.to_string_lossy());
} }
if let Some(value) = std::env::var_os(ENV_ACCENT) { // 强调色的两档开关(`ULL_APPEARANCE_ACCENT` / `…_COMMIT`)收在 `accent` 自己的模块里:
// 取证开关 = 「像刚敲进去的」(走输入中规则),不是配置读回。 // 本文件贴 400 行硬线,而那两个开关与 `Accent` 的状态机是一件事(见 `Accent::apply_env`)。
self.accent.set(&value.to_string_lossy()); self.accent.apply_env();
}
self.refresh_background(); self.refresh_background();
self.refresh_palette(); self.refresh_palette();
} }
@@ -16,8 +16,9 @@
//! //!
//! 输入框用 `components::inputs::text_field`(与启动参数区同一个控件)。**回车 = 点「改名」** //! 输入框用 `components::inputs::text_field`(与启动参数区同一个控件)。**回车 = 点「改名」**
//! (M252 / P18):`Field::on_submit` 与右边那枚按钮共用 [`commit_rename`] 这一个消息产地, //! (M252 / P18):`Field::on_submit` 与右边那枚按钮共用 [`commit_rename`] 这一个消息产地,
//! 所以空名 / 原名不变 / 非法字符走的仍是原来那条校验(`app/update/instances.rs` 的 //! 所以空名 / 原名不变 / 非法字符走的仍是原来那条校验(`app/update/instances.rs` 的空名与
//! 空名与「没改」两条短路 + presenter 那边的目录名规则),**回车没有绕开任何一道边界**。 //! 「没改」两条短路 + `core::game::saves::write::boundary::check_name` 的路径规则),
//! **回车没有绕开任何一道边界**。
use iced::widget::{column, row}; use iced::widget::{column, row};
use iced::{Alignment, Element, Length}; use iced::{Alignment, Element, Length};