- 桌面应用
- 开发工具
【免费下载链接】MooTool
Handy tool set for developers
MooTool 的 Compose 桌面实现(next-compose)在将 Electron 加解密工具(F14)迁移为 Jetpack Compose UI 的过程中,针对工具页内容区的操作按钮密度制定了一套「P5 工具栏」策略:对称/Base64 中栏三钮、非对称操作条、摘要文本/文件、随机行生成按钮以及各 Tab 算法下拉触发钮统一走p5Toolbar密度,同时保留摘要/随机结果区的MooGhostButton复制图标。本文结合 DIFF-102 文档 与 CryptoScreen.kt 等源码,梳理按钮布局、密度策略、启用守卫与测试证据,帮助你理解这套样式迁移的落地方式。
一、背景:Electron 原行为与 Compose 本产品行为的对照
DIFF-102 的核心是回答一个问题:Electron 工具页里那批约 30px 的panel-command操作按钮,迁移到 Compose 后应使用哪种按钮密度?原文档给出的对照关系如下:
| 区域 | Electron 原行为 | Compose 本产品行为 |
|---|---|---|
| 对称/Base64 中栏 | 加解密与复制为 P5panel-command(约 30px) | 中栏三钮(加密/解密/复制)均p5Toolbar |
| 非对称操作条 | P5panel-command | 「生成密钥对」与FlowRow全部操作均p5Toolbar |
| 摘要 Tab | 文本/文件摘要为 P5panel-command | 文本摘要(prominent)、文件摘要均p5Toolbar |
| 随机 Tab | 各行「生成」为 P5panel-command | 各行「生成」按钮p5Toolbar |
| 算法紧凑下拉 | 同类密度 | 各 Tab 的CompactChoice触发钮p5Toolbar |
| 摘要/随机结果区 | —— | 仍用MooGhostButton复制图标(非 p5 密度) |
其中p5Toolbar是 Compose 端MooButton的一个布尔参数(next-compose/composeApp/src/desktopMain/kotlin/com/rememberber/mootool/next/compose/ui/components/Controls.kt),它决定了按钮按「P5 工具页内容区」的密度绘制,而不是沿用标题栏按钮或紧凑导航的密度。
二、p5Toolbar密度策略:LayoutPolicy 与 MooButton 的分工
p5Toolbar按钮的实际尺寸并不写死,而是由布局策略对象 LayoutPolicy.kt 按「当前界面风格 + 是否紧凑导航」动态计算,这承接了后续 DIFF-501 的内容密度策略:
fun p5ToolbarDense(compactNavigation: Boolean): Boolean = compactNavigation fun p5ToolbarButtonHeightDp(dense: Boolean, controlHeightDp: Float): Float = if (dense) 26f else controlHeightDp fun p5ToolbarFontSp(dense: Boolean, interfaceStyle: String): Float = when { dense -> 11f interfaceStyle == "modern" || interfaceStyle == "quiet" -> 13f else -> 12f } fun p5ToolbarFontWeightMedium(dense: Boolean, interfaceStyle: String): Boolean = dense || interfaceStyle == "modern" || interfaceStyle == "quiet"对应到MooButton的实现(Controls.kt),p5Toolbar = true时的表现可归纳为:
- 圆角:固定
RoundedCornerShape(6.dp); - 高度:走
LayoutPolicy.p5ToolbarButtonHeightDp——非紧凑导航下跟随MooTheme.dimens.controlHeight(modern/quiet 为 34dp),紧凑导航下为 26dp(即 DIFF-496/497 的 dense 语义); - 字号/字重:modern/quiet 非 dense 为 13sp +
FontWeight.Medium(500),对齐 Electron.tool-page .toolbar-button的font-size: 13px; font-weight: 500;其余风格为 12sp SemiBold;dense 一律 11sp Medium; - 内边距:
p5Toolbar为水平 9dp / 垂直 4dp; - 主按钮阴影:modern/quiet 风格下
p5Toolbar && primary保留 1dp 浅阴影,对齐 Electron.toolbar-button--primary。
从源码结构看,这一策略与 Electron 端--tool-control-height: 34px(见next/src/shared/styles/global.css)对齐,属于 parity-gap 中 P1「外观 / 工具页内容区」的一环,不是为加解密工具单独发明的机制,而是全工具页通用的按钮密度规范。
三、五个 Tab 的 P5 按钮逐项拆解
CryptoScreen.kt 通过CryptoTab枚举(Symmetric/Asymmetric/Digest/Base/Random)组织五个面板。下面按 Tab 说明哪些按钮打了p5Toolbar。
3.1 对称加密 Tab:中栏三钮
中栏是竖直排列的三只按钮,全部p5Toolbar:
- 加密(
crypto.encrypt):prominent = true, p5Toolbar = true,enabled = CryptoWiringPresentation.canSymmetricCrypt(keyLength.valid); - 解密(
crypto.decrypt):p5Toolbar = true,同样受canSymmetricCrypt守卫; - 复制(
crypto.copy):p5Toolbar = true,enabled = CryptoWiringPresentation.cipherCopyActionEnabled(session.symCipher)。
密钥有效性来自CryptoEngine.symmetricKeyUtf8Length:DES 要求 8 个 UTF-8 字节、AES/SM4 要求 16 个 UTF-8 字节,界面实时显示{current}/{required}(CryptoEngine.kt)。算法下拉(AES/DES/SM4)与明文/密文分栏即IoThreePaneRow,中栏比例middleRatio = 0.28f。
3.2 非对称 Tab:生成密钥 + FlowRow 全操作
顶部操作条内,「生成密钥对」为prominent = true, p5Toolbar = true,enabled = canGenerateKeyPair(session.asymBusy);「从私钥恢复公钥」同样p5Toolbar,enabled = canRestorePublicKey(session.privateKey, session.asymBusy)。密钥状态行会实时提示公钥/私钥就绪情况、RSA 模长(bits)或 SM2 公/私钥字节数。
下方FlowRow(修饰符为mooCryptoAsymActions(),即fillMaxWidth().padding(vertical = 12.dp))中,全部 7 个操作按钮均p5Toolbar:
| 按钮 | 守卫 |
|---|---|
公钥加密publicEncrypt | publicEncryptActionEnabled(asymKeys, asymBusy) |
私钥解密privateDecrypt | privateDecryptActionEnabled(asymKeys, asymBusy) |
私钥加密privateEncrypt | privateEncryptActionEnabled(仅 RSA,否则抛rsa-only) |
公钥解密publicDecrypt | publicDecryptActionEnabled(仅 RSA) |
签名sign | signActionEnabled(asymKeys, asymBusy) |
验签verify | verifyActionEnabled(asymKeys, plain, signature, asymBusy) |
复制copy | cipherCopyActionEnabled(session.asymCipher) |
3.3 摘要 Tab:文本/文件摘要 + Ghost 复制图标
- 文本摘要(
crypto.textDigest):prominent = true, p5Toolbar = true,点击后经CryptoWiringPresentation.runDigestText走CryptoEngine.digestText; - 文件摘要(
crypto.fileDigest):p5Toolbar = true,通过chooseFileWithExportDirectory选择文件(并调用persistToolsExportDirectory记录导出目录,见 DIFF-660),也支持把文件直接拖到算法行(desktopFileDropTarget); - 摘要结果区:右侧复制按钮不是
p5Toolbar,而是MooGhostButton(size = 24.dp),enabled = cipherCopyActionEnabled(session.digestOutput),图标为⎘。
摘要算法枚举为 MD5、SHA-1、SHA-256、SHA-384、SHA-512、SM3(digestLabel映射)。
3.4 Base64/Base32 Tab:中栏三钮
与对称 Tab 同构:中栏「编码」(prominent + p5Toolbar,encodeBaseActionEnabled(session.basePlain))、「解码」(p5Toolbar,decodeBaseActionEnabled(session.baseCipher))、「复制」(p5Toolbar,cipherCopyActionEnabled)。算法下拉覆盖 Base64/Base32。
3.5 随机 Tab:每行「生成」+ Ghost 复制
RandomPanel由四行RandomRow组成(UUID、数字、字符串、密码),对齐 Electron.random-row的 124/34/32/84 列布局(见 DIFF-085):
- 标签列固定 124dp;
- 输出区为 34dp 高的等宽文本(
FontFamily.Monospace,圆角 6dp、borderControl描边); - 复制:
MooGhostButton(size = 32.dp),enabled = randomCopyActionEnabled(value); - 生成:
MooButton(prominent = true, p5Toolbar = true, width = 84.dp),enabled = randomGenerateActionEnabled(kind, randomLength)。
MooGhostButton是「仍保留默认密度」的代表——它走 LayoutPolicy.iconGhostCornerRadiusDp(modern 9dp、默认 8dp),尺寸由调用方传入(摘要 24、随机 32),与p5Toolbar的 6dp 圆角/34dp 高度体系刻意区分。
3.6CompactChoice:算法下拉触发钮
CompactChoice是各 Tab 共用的紧凑算法下拉(CryptoScreen.kt):触发钮MooButton(label(current), onClick = { open = true }, p5Toolbar = true),展开的MooMenu内含MooMenuItem(11sp、高 30dp)。这正是 DIFF-102 里「各 TabCompactChoice触发钮均p5Toolbar」的落点——让下拉触发钮与周边操作按钮保持同密度。
四、启用守卫:*ActionEnabled 一揽
P5 按钮不只是「长得紧凑」,其可用性(enabled)全部由 CryptoWiringPresentation.kt 中的守卫函数驱动,分属三个 DIFF 切片:
- DIFF-665:
randomCopyActionEnabled/randomGenerateActionEnabled。UUID 始终可生成;数字/字符串/密码受CryptoEngine.MIN_RANDOM_LENGTH(1)~MAX_RANDOM_LENGTH(4096) 边界约束。同时给MooGhostButton增加了enabled(0.42 透明度、clickable(enabled=),对齐MooButton); - DIFF-666:
cipherCopyActionEnabled(value) = value.isNotBlank(),对称/非对称/摘要/Base 的复制按钮与随机 Tab 复制复用同一守卫; - DIFF-667:非对称
publicEncryptActionEnabled/privateDecryptActionEnabled/privateEncryptActionEnabled(仅 RSA)/publicDecryptActionEnabled(仅 RSA)/signActionEnabled/verifyActionEnabled(密钥就绪 + 验签需明文与签名均非空 +asymBusy),以及 BaseencodeBaseActionEnabled/decodeBaseActionEnabled。
对称加解密按钮还叠加了canSymmetricCrypt(keyValid)——密钥 UTF-8 字节数与算法要求不符时按钮直接禁用,避免用户带着非法密钥执行操作。这类守卫与 DIFF-501 的密度策略共同构成「P5 按钮 = 紧凑密度 + 语义化启用」的完整实现。
五、测试与验收证据
原文档指出「desktopTest 见docs/acceptance.md」,对应仓库中的 next-compose/docs/acceptance.md。与 F14 相关的证据可归纳为三层:
- 行为登记:acceptance 的 F14 行明确记录「各 Tab 操作钮与算法下拉
p5Toolbar见 DIFF-102」,并列出对称/非对称/摘要/Base 算法下拉、私钥操作输入与生成密码输出写入历史时遮蔽、非 ASCII 密钥拒绝、对称 Tab 实时{current}/{required}UTF-8 字节提示、非对称公钥还原/密钥状态行、摘要文件 digest 走tools.exportDirectory等配套行为; - 像素级焦点帧测试:
- CryptoGenerateKeyTabCaptureTest.kt 与 CryptoVerifyTabCaptureTest.kt 在
modern风格下对「生成密钥对」「验签」按钮requestFocus(),captureToImage后断言焦点环颜色0x316DC0的像素数 ≥ 8,并把 PNG 写入docs/evidence/2026-09-15-inspector-screencapture/windows/; - DetachedCompactP5CaptureTest.kt 验证分离窗与主窗共用
AppMooTheme且开启紧凑导航时,p5Toolbar按钮按 dense 尺寸渲染(assertTrue(LayoutPolicy.p5ToolbarDense(compactNavigation = true)));
- CryptoGenerateKeyTabCaptureTest.kt 与 CryptoVerifyTabCaptureTest.kt 在
- 全量回归:acceptance 的工程检查入口给出 JDK 21 下的完整命令链,例如:
cd /path/to/next-compose export JAVA_HOME="$(/usr/libexec/java_home -v 21)" # macOS 示例 ./gradlew :composeApp:desktopTest --offline --no-daemon ./gradlew :composeApp:run按 acceptance 的记录,DIFF-102 落地时的全量desktopTest通过量约在 700+(DIFF-501 时 705/705)之后持续增长至 1342/1344 左右,说明该样式切片没有破坏既有功能回归。
六、已知限制与未做项
原文档「未做」明确列出三项边界,本文如实保留并补充验收文档中的对应上下文:
- 工具标题栏的历史/分离/更多按钮仍为默认密度:
p5Toolbar只作用于工具页内容区按钮,标题栏操作(CryptoScreen顶部的 History/Detach/更多溢出)走的是MooButton默认controlHeight或溢出菜单,不参与本次密度统一; - file-drop:文件拖放条(
FileDropRow等)的完整拖放样式仍未按逐选择器抽组件,相关手工验收未完成; - 系统 IME、三平台安装未测:acceptance 明确「系统 IME 仍未手工验收,不能标 F14 已验收」,且 F14 的「超大文件与哈希中途取消」也尚未测试;三平台安装/升级/卸载/公证未测,当前交付是可运行的 0.1.0 开发切片,而非完整产品验收。
对读者而言,理解 DIFF-102 的正确姿势是:它是「按钮密度」这一横切主题在 F14 加解密工具上的具体落地,配套的p5Toolbar参数、LayoutPolicy密度函数、CryptoWiringPresentation启用守卫以及像素级焦点帧测试,共同保证了 Compose 端操作按钮与 Electron 工具页在视觉密度和交互语义上的对齐。
- 桌面应用
- 开发工具
【免费下载链接】MooTool
Handy tool set for developers
相关推荐
MooTool Next Compose 环境 / 系统信息 / Protobuf 操作按钮 P5 工具栏样式对齐(DIFF-099)实现详解
MooTool Next Compose 环境 / 系统信息 / Protobuf 操作按钮 P5 工具栏样式对齐(DIFF 099)实现详解 导读 本文深入解
桌面应用开发工具MooTool Next-Compose 中 UA 解析操作条(P5 密度)与 SelectedFileName 所选文件组件的 DIFF-096 实现解析
MooTool Next Compose 中 UA 解析操作条(P5 密度)与 SelectedFileName 所选文件组件的 DIFF 096 实现解析 导
桌面应用开发工具MooTool Next Compose 的 UA 工作区 P5 壳与 300dp 最小列宽、环境作用域 Dense 按钮改造(DIFF-093 深度解析)
MooTool Next Compose 的 UA 工作区 P5 壳与 300dp 最小列宽、环境作用域 Dense 按钮改造(DIFF 093 深度解析) 本
桌面应用开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考