news 2026/10/15 15:37:58

MooTool 加解密/随机工具 P5 操作按钮的 Compose 实现解析(DIFF-102)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MooTool 加解密/随机工具 P5 操作按钮的 Compose 实现解析(DIFF-102)
  • 桌面应用
  • 开发工具

【免费下载链接】MooTool

Handy tool set for developers

项目地址:https://gitcode.com/gh_mirrors/mo/MooTool
点击查看免费下载

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:

按钮守卫
公钥加密publicEncryptpublicEncryptActionEnabled(asymKeys, asymBusy)
私钥解密privateDecryptprivateDecryptActionEnabled(asymKeys, asymBusy)
私钥加密privateEncryptprivateEncryptActionEnabled(仅 RSA,否则抛rsa-only)
公钥解密publicDecryptpublicDecryptActionEnabled(仅 RSA)
签名signsignActionEnabled(asymKeys, asymBusy)
验签verifyverifyActionEnabled(asymKeys, plain, signature, asymBusy)
复制copycipherCopyActionEnabled(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 相关的证据可归纳为三层:

  1. 行为登记:acceptance 的 F14 行明确记录「各 Tab 操作钮与算法下拉p5Toolbar见 DIFF-102」,并列出对称/非对称/摘要/Base 算法下拉、私钥操作输入与生成密码输出写入历史时遮蔽、非 ASCII 密钥拒绝、对称 Tab 实时{current}/{required}UTF-8 字节提示、非对称公钥还原/密钥状态行、摘要文件 digest 走tools.exportDirectory等配套行为;
  2. 像素级焦点帧测试:
    • 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)));
  3. 全量回归: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

项目地址:https://gitcode.com/gh_mirrors/mo/MooTool
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 15:37:51

vDisk一键部署自动化脚本:从设计思路到避坑指南全解析

干这行时间长了,你会发现一件事:很多听起来很高大上的问题,本质上都是重复性体力劳动。vDisk部署就是典型例子——不管你用的是哪家虚拟化平台,还是自己搭的一套东西,虚拟磁盘的创建、分区、格式化、挂载、甚至写引导&…

作者头像 李华
网站建设 2026/10/15 15:37:29

Playwright 元素定位与等待机制:小白也能看懂的稳定自动化指南

目录Playwright 元素定位与等待机制:小白也能看懂的稳定自动化指南一、先理解:Playwright 到底在做什么二、准备一个最小运行环境三、定位元素的核心原则:优先描述“用户看到的东西”1. 用角色和名称定位2. 用标签定位输入框3. 用 placeholde…

作者头像 李华
网站建设 2026/10/15 15:37:20

微信小程序对接团购核销:别手写对接了,无限聚核这组 AI 提示词教大模型接美团、抖音核销

核销服务由无限聚核提供,美团、抖音团购核销一站式接入。要把美团、抖音团购核销接到微信小程序或行业软件服务端,很多人仍在「对着文档抄路径、猜字段、改一版挂一版」。无限聚核把同一套接入纪律写成了文档站上的「AI 接入」提示词:你把流程…

作者头像 李华
网站建设 2026/10/15 15:36:31

从爬虫到可视化:Python豆瓣电影数据分析系统毕设实践

简介:面向python毕业设计及数据可视化课程实践的完整项目资源,整合豆瓣电影真实数据,从爬虫采集、数据清洗、存储到可视化展示形成完整闭环,涵盖pandas分析、Flask后端与ECharts交互图表,采用MySQL存储结果。系统通过E…

作者头像 李华
网站建设 2026/10/15 15:36:24

时间轮定时器原理与实战:单轮、多轮实现及避坑指南

简介:本资源是一套Java时间轮定时器的完整实现代码,面向具备一定Java基础、希望深入理解高效定时任务调度机制的开发者。内容围绕单轮与多轮两种时间轮结构展开,涵盖槽位划分、指针轮询、任务插入与移除等核心环节,可用于心跳检测…

作者头像 李华