docs: explain host widget interaction and visual states

This commit is contained in:
2026-11-12 19:28:49 +08:00
parent 0971d08e1b
commit ca5bc863c1
4 changed files with 70 additions and 2 deletions
+9
View File
@@ -5,6 +5,7 @@ use crate::display_list::Color;
pub const BG: Color = Color::rgb(255, 255, 255);
// A visibly separate chrome layer against the warm, near-white content canvas.
pub const BAR: Color = Color::rgb(230, 233, 237);
// 控件边框与未悬停分隔线共用,强调状态由 Theme.accent 覆盖而不是改写这个常量。
pub const BORDER: Color = Color::rgb(226, 226, 226);
pub const TEXT: Color = Color::rgb(35, 42, 53);
pub const MUTED: Color = Color::rgb(103, 114, 130);
@@ -22,10 +23,12 @@ pub const PALETTE: [Color; 6] = [
#[derive(Clone, Copy, Debug)]
/// 当前管理界面的配色基础,派生状态颜色由方法统一计算。
pub struct Theme {
// 由 new 先做简单亮度限制,soft/hover/pressed 使用同一份调整后颜色生成状态背景。
pub accent: Color,
}
impl Theme {
/// 保存经过亮度限制的强调色,所有控件状态色都从该色与管理界面背景混合得到。
// 每帧 sidebar/DeveloperTools 的 Ui 初始化调用,设置页输入也可显式使用 readable_accent。
pub fn new(accent: Color) -> Self {
// 构造时统一压低过亮强调色,之后 hover/pressed 等样式都从调整后的 accent 派生。
Self {
@@ -33,19 +36,23 @@ impl Theme {
}
}
/// 以 10% 强调色混合背景,得到未悬停的柔和选中底色。
// widgets::surface 处理选中态、Painter 画静态已选行时使用,背景固定为宿主 BG。
pub fn soft(self) -> Color {
mix(BG, self.accent, 0.10)
}
/// 以 17% 强调色混合背景,得到比 soft 更明显的悬停底色。
// 控件 hover 底色与源码选区高亮共用,比 soft 更明显但仍是与白底混合的浅色。
pub fn hover(self) -> Color {
mix(BG, self.accent, 0.17)
}
/// 以 29% 强调色混合背景,增强按下状态;混色输出始终不透明。
// widgets::surface 的按压优先分支使用,比例最高以区分普通悬停。
pub fn pressed(self) -> Color {
mix(BG, self.accent, 0.29)
}
}
/// 按比例混合颜色通道,作为状态颜色的基础运算。
// 状态背景、按压色块与悬停滚动手柄调用;只混 RGB,不按输入 alpha 做源覆盖合成。
pub fn mix(a: Color, b: Color, amount: f32) -> Color {
// 逐 RGB 通道线性插值并四舍五入,amount 钳到 [0,1];结果使用 rgb,输出 alpha 固定为 255。
let channel =
@@ -57,9 +64,11 @@ pub fn mix(a: Color, b: Color, amount: f32) -> Color {
)
}
/// 根据背景选择可读的强调色,供选中与焦点状态使用。
// Theme::new 与 Settings 的 Enter 应用路径调用,不依赖当前业务页面背景,也不执行通用主题持久化。
pub fn readable_accent(mut c: Color) -> Color {
// 用 299/587/114 加权亮度做简单阈值判断,过亮时每轮各通道乘 0.94 变暗。
// 这是启发式规则,不是对任意背景执行通用对比度求解。
// 整数通道每轮变小直至阈值以内;进入循环时 Color::rgb 会将输出 alpha 设为不透明,未进入则原样返回。
while (c.red as u32 * 299 + c.green as u32 * 587 + c.blue as u32 * 114) / 1000 > 155 {
c = Color::rgb(
(c.red as f32 * 0.94) as u8,