原生鸿蒙像素画板实战 21:编辑器设置

发布时间:2026/7/23 17:59:59
原生鸿蒙像素画板实战 21:编辑器设置 编辑器设置最容易变成“每个开关都直接改页面字段”的地方。自动保存间隔、导出格式、放大倍率、历史上限、画布背景和洋葱皮透明度看似没有关联实际上它们有共同要求输入可能非法、变化后需要不同程度的刷新、是否标记项目已修改也不同。bitArt 将默认值、可选范围和应用结果拆开让设置面板不会成为隐藏的业务中心。设置项先有默认值和边界界面只是一个输入端如果输入框直接把字符串写进 autoSaveIntervalSeconds恢复项目或手工输入时就可能出现 NaN、负数或过短周期若导出倍率无上限大图导出会突然占用远超预期的内存。另一个误区是“任何设置变化都完整刷新”。例如导出格式变化不影响画布洋葱皮开关却需要重绘历史上限变化还要裁剪 undo 与 redo 栈。设置面板与设置服务怎样避免互相越界设置项本身不复杂复杂的是它们在变化后的副作用不同。先规范化输入再明确是否刷新、是否标脏、是否重排保存面板就不会变成不可预测的控制中心。改变设置后不一定都要完整重绘EditorSettingsService 把默认值和范围放在同一处自动保存默认 300 秒非零值限制在 60 到 86400 秒导出倍率限制 1 到 4历史数量限制 10 到 100洋葱皮透明度限制 10 到 80。EditorSettingsActionService 再把一次用户动作变成 SettingsApplyResult其中分开表示 changed、requestRefresh、markDirty 和 scheduleAutoSave。这种结构让设置面板不需要猜测副作用。它只调用 applyAutoSaveInterval 或 applyCanvasBackgroundColor再把返回结果交给工作流。保存调度、UI 刷新和项目脏状态因此有明确的触发条件恢复项目时也可以复用相同的规范化逻辑。设置规范化把默认值、关闭语义和边界范围固定在服务层。static normalizeAutoSaveSeconds(value: number): number { const seconds Math.round(Number(value)); if (isNaN(seconds)) return EditorSettingsService.DEFAULT_AUTO_SAVE_SECONDS; if (seconds 0) return 0; return Math.max(EditorSettingsService.MIN_AUTO_SAVE_SECONDS, Math.min(EditorSettingsService.MAX_AUTO_SAVE_SECONDS, seconds)); } static normalizeExportScale(value: number): number { const scale Math.round(Number(value)); if (isNaN(scale)) return EditorSettingsService.DEFAULT_EXPORT_SCALE; return Math.max(EditorSettingsService.MIN_EXPORT_SCALE, Math.min(EditorSettingsService.MAX_EXPORT_SCALE, scale)); }历史上限变化要同步裁剪已有历史设置规范化的顺序是把输入转成数值或小写字符串处理 NaN 和空值再在允许范围内夹紧。0 对自动保存有特殊语义表示关闭所以需要在最小值判断之前分支。历史上限变化不仅更新数字还用 EditorHistoryService.trim 截断 undoStack 和 redoStack防止 UI 显示新上限而内存中仍保留超量快照。static applyAutoSaveInterval(target: SettingsApplyTarget, seconds: number): SettingsApplyResult { const result EditorSettingsActionService.setAutoSaveInterval(target.autoSaveIntervalSeconds, seconds); target.customAutoSaveMinutesText result.minutesText; if (!result.changed) return EditorSettingsActionService.createApplyResult(false); target.autoSaveIntervalSeconds result.value; return EditorSettingsActionService.createApplyResult(true, true, true, true); }设置变化如何通知刷新和保存设置分成两类。导出格式、倍率、自动保存和背景色属于项目配置应在变化时标脏洋葱皮开关和透明度还会修改画布可见效果需要增加 dirtyVersion 或请求刷新。历史上限本身不强制全量画布重绘但要让历史面板读取裁剪后的数组。设置应用结果把刷新、保存和历史裁剪分开让每个控件只触发必要的后续动作。static applyMaxHistoryCount(target: SettingsApplyTarget, count: number): SettingsApplyResult { const result EditorSettingsActionService.setMaxHistoryCount(target.maxHistoryCount, count, target.undoStack, target.redoStack); if (!result.changed) return EditorSettingsActionService.createApplyResult(false); target.maxHistoryCount result.value; target.undoStack result.undoStack; target.redoStack result.redoStack; return EditorSettingsActionService.createApplyResult(true, false, true); }设置面板最容易积累的隐性错误不要只在 UI 控件限制范围项目恢复、文件导入和未来接口同样会绕过控件。自动保存的非正数统一表示关闭NaN 才回退为默认间隔这两条规范化路径要明确区分。历史数量减小时要同步裁剪 undo 和 redo不能只换一个显示数字。设置服务本质上是输入边界和副作用边界的汇合点。它不会替代持久化服务也不会替代渲染服务它负责把“用户想设成什么”变成“项目允许处于什么状态”再清楚地告诉上层哪些后续动作必要。设置项需要一张副作用清单设置项的回归适合做成一张副作用表。每个设置写清楚四件事允许的范围、输入非法时的回退、是否要刷新画布、是否需要保存。比如导出格式改变只需保存配置洋葱皮开关需要刷新画布自动保存间隔还要重排定时器历史上限需要裁剪两个栈。用这张表检查比凭感觉在面板上点一遍更不容易漏掉隐藏副作用。还要验证连续设置。先把历史上限调大并画出多条历史再调小随后调回大值旧快照不应凭空恢复先关闭自动保存再改成自定义分钟数旧定时器应被清除、新定时器按规范化秒数重建。设置系统的稳定性来自这些状态转换而不是静态页面上显示了几个选项。怎样确认设置范围和副作用匹配设置检查的重点是边界值和副作用值正确不代表刷新和保存时机正确。把自动保存输入为 0、30、300、90000 和非数字确认得到关闭、下限、正常值、上限和默认值。将历史上限从较大值降到较小值确认 undo 与 redo 都被裁剪且画布不回退。切换 PNG、JPG、GIF 和不同倍率确认只更新导出配置不无故重绘画布。开启洋葱皮并调整透明度确认画布刷新修改背景色后重新打开项目确认设置可恢复。编辑器设置检查记录 非法数值被规范化而非直接写入 自动保存 0 与非零最小值语义明确 历史上限同步裁剪两个栈 画布相关设置才触发相应刷新设置项暂不覆盖的偏好范围当前设置集中在编辑器功能和项目体验不涵盖账号偏好、云同步策略或系统级主题。对单项目创作而言先保证设置可校验、可恢复、作用范围明确比把所有个性化选项都塞进面板更重要。这一篇的重点是让每一项设置都有可校验的取值和明确的副作用。最后一篇把大屏上的键盘和鼠标输入接到同一套工具与面板状态中为整个系列收束。