ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Serial Studio 手动布局模式:Figma 式对齐辅助线与 48×48 密集小窗口支持(Spec 0010)实现解析

Serial Studio 手动布局模式:Figma 式对齐辅助线与 48×48 密集小窗口支持(Spec 0010)实现解析 Serial Studio 手动布局模式Figma 式对齐辅助线与 48×48 密集小窗口支持Spec 0010实现解析【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio手动布局模式关闭自动布局是 Serial Studio 中最终仪表盘版式编排的场所——冻结功能Spec 0007的存在正是为了让手工排好的版式被锁定并交付给操作员。但过去这一模式没有任何精度工具拖动窗口时唯一的辅助是靠近画布边缘时出现的半屏/四分之一屏 Aero 式吸附矩形既没有窗口与窗口之间的边缘/中心对齐也没有等距辅助、尺寸匹配和位置读数。本文以仓库中的设计规格文档 doc/claude/specs/0010-manual-layout-guides/spec.md 为核心骨架结合源码实现系统讲解该特性的需求定义R1–R11、验收标准AC1–AC12、约束不变量以及它在 QML 与 C 层的真实落地方式帮助你掌握在 Serial Studio 中快速拼出像素级整齐仪表盘的操作方法与原理。一、背景与动机为什么手动布局需要精度工具规格文档开篇点明了两个并存的问题手动模式缺乏精度工具。自动布局关闭后手工拼版是最终版式的产出环节但拖动时唯一的辅助是 Aero 风格吸附——仅在画布边缘提供半屏/四分之一屏矩形。没有窗口与邻居之间的边缘或中心吸附、没有等距辅助、没有位置和尺寸读数。排一排仪表只能靠肉眼估像素偏移在最需要精致的交付环节反而最容易排得参差不齐。356×320 的最小尺寸限制了密集面板。当时每个仪表盘窗口强制 356×320 的最小尺寸而仪表盘面板instrument panel需要小瓦片——紧凑的 LED 簇、窄条、小数字读数——现有的尺寸下限让密集面板无法实现。值得注意的是窗口部件自身已经具备降级渲染能力标题条在宽度低于 96 px 时隐藏工具栏在高度低于某个阈值时隐藏因此限制来自窗口外壳delegate而非部件内容。从源码看这一论断完全成立app/qml/MainWindow/Panes/Dashboard/WidgetDelegate.qml 中窗口的最小尺寸直接由布局模式决定minimumWidth/minimumHeight在自动布局时为356/320手动模式则放宽到48/48。二、目标与非目标2.1 目标Goals规格为手动模式定义了完整的精度工具集拖动窗口时任意窗口的边缘/中心可与其他窗口的边缘/中心、画布边缘、画布水平/垂直中心线对齐并在对齐发生时以辅助线guide line可视化确认——移动与缩放都生效构建行/列时获得等距辅助当新产生的间距与相邻间距一致时拖动吸附到该间距并高亮匹配的间距缩放时可将一个窗口的宽/高匹配到另一个窗口尺寸相等时给出视觉提示通过画布上的x/y/w×h像素读数徽章badge随时获知被操作窗口的精确几何可选的背景网格开启后移动/缩放吸附到网格线满足固定节奏的排版需求按住修饰键可完全自由放置本次手势内挂起全部吸附手动模式下窗口最小可缩放到 48×48 px足以容纳密集仪表瓦片同时仍显示标题栏按钮。2.2 非目标Non-Goals明确划清的边界同样重要不改自动布局模式其 packing、sizing、拖动重排行为保持现状包括既有最小尺寸假设不改外部弹窗窗口其 356×320 最小尺寸与操作系统管理行为保持不变Aero 吸附被移除而非改造半屏/四分之一屏矩形从手动模式彻底删除不重设计、不藏在修饰键后面——手动模式变为纯自由放置 智能辅助线不做 Figma 式可拖拽标尺线用户可放置的持久参考线也不做多选/分组对齐辅助线只作用于正在操作的单个窗口不重设计小尺寸下的部件渲染部件保持既有降级行为隐藏标题、工具栏、标签48×48 下看起来极简是可接受的冻结模式不变冻结时所有操纵保持完全禁用。三、核心功能需求详解R1–R11规格共定义了 11 条需求是特性的完整行为契约。R1 / R2移动与缩放时的边缘/中心吸附拖动窗口移动时拖动位置在小阈值内吸附到以下目标集其他可见窗口的边缘/中心画布边缘画布水平/垂直中心线。吸附成立时沿对齐的全长渲染一条辅助线。缩放时R2移动中的边对同一目标集吸附反馈相同不移动的边在整个手势中绝不位移。源码层面吸附核心实现在 core/Ui/UI/SnapGuides.hkSnapThreshold 6第 34 行——吸附阈值即候选对齐线捕获手势的像素距离6 px 意味着轻微靠近即可吸附但日常拖动依然顺滑GuideKindEdge/Center与GuideLine——每条辅助线表达为画布坐标中的 1 px 矩形resolveMoveSnap()/resolveResizeSnap()第 102–103 行——分别解析移动与缩放吸附输出SnapResult吸附后的几何 证明它的可视化信息辅助线、间距、尺寸匹配窗口。缩放时的不移动边绝不位移由 core/Ui/UI/WindowManager/WindowGeometry.h 中的MovingEdges与computeResizedGeometry()保证每次只按手势增量重新计算被移动的边固定边不参与计算。R3等间距吸附拖动时若被拖动窗口与邻居之间的间距可以匹配该邻居沿同轴与下一个窗口之间的既有间距则位置吸附到等分间距并可视化指示匹配的间距。规格明确该特性仅限移动手势Figma 同样将其限定在移动见未决问题。实现上SpacingIndicatorcore/Ui/UI/SnapGuides.h携带gap像素值渲染时在每个间距条上显示具体像素数。R4尺寸匹配吸附缩放时若进行中的宽度或高度进入另一可见窗口宽度/高度的阈值范围则尺寸吸附到相等并高亮匹配窗口。SnapResult中的sizeMatch字段承载这一信息SnapOverlay将其发布为sizeMatchRectsizeMatchVisible属性。R5实时几何读数徽章任何手动移动/缩放手势期间一个紧凑徽章实时显示窗口当前 x、y、宽度、高度的画布像素值手势结束即消失。WindowManager的manualGestureGeometry属性提供该数据SnapOverlay::publishManualGesture()负责发布。这一徽章同时也是验收手段——AC1/AC4/AC5 都依赖它来核对最终落点是否与目标对齐相差 0 px。R6可选背景网格用户可开启手动模式下的渲染背景网格并可配置单元格大小开启后移动与缩放吸附到网格线。网格吸附与智能辅助线可组合两者都在范围内时智能辅助线优先。该偏好跨会话持久化。实现落点非常具体网格绘制在 app/qml/MainWindow/Panes/Dashboard/DashboardCanvas.qml一个Canvas元素垫在窗口之下、壁纸之上仅在尺寸/网格大小/主题变化时重绘颜色取自主题色canvas_grid开关与尺寸位于画布右键菜单同文件第 356–402 行Show Grid菜单项网格尺寸提供8 / 16 / 24 / 32 / 64 px五档持久化在 core/Ui/UI/WindowManager.cpp通过QSettings读写WindowManager_GridEnabled默认false与WindowManager_GridSize默认16取值被qBound(2, …, 256)钳制网格吸附的量化函数是SnapGuides::snapToGrid(value, gridSize)。R7Alt 键临时绕过吸附移动或缩放时按住 Alt 挂起全部吸附辅助线、等距、尺寸匹配、网格手势中途松开 Alt 立即恢复。这是精度不粘手设计约束的关键出口——吸附必须让像素级对齐成为轻松默认但绝不允许与用户对抗。R8移除 Aero 半屏/四分之一屏吸附半屏/四分之一屏吸附矩形不再出现在手动模式把窗口拖到画布边缘附近时就停在被可能已吸附的拖动所放置的确切位置。画布上仍保留了snapIndicator属性与渲染代码DashboardCanvas.qml但其职责已转为真实吸附几何的指示框按被触碰边内缩 1 px而非旧的占位吸附矩形。R948×48 手动最小尺寸手动模式下窗口最小可缩放到 48×48 px 且不能更小在该尺寸下标题栏按钮依然可见可点。自动布局与外部窗口保持既有下限将小尺寸版式切回自动布局不得破坏 packing。WidgetDelegate.qml 中的实现就是一句话的分支windowManager.autoLayoutEnabled ? 356 : 48。标题栏按钮在 48 px 下的可用性由MiniWindow外壳的 chrome 折叠逻辑保证见约束与不变量。R10辅助线仅限手动模式任何辅助线、徽章、网格、吸附行为都不出现在自动布局模式或冻结状态仅悬停时也不出现只活跃于移动/缩放手势进行中。DashboardCanvas.qml 中手势叠加层的可见性条件即为_wm.manualGestureActive !_wm.autoLayoutEnabled !_wm.frozen网格同理第 496 行。R11布局持久化保持既有结构保存的手动几何包括小于 356×320 的尺寸按既有方式持久化与恢复按项目、按画布尺寸桶旧版保存的布局原样加载。这由 core/Ui/UI/WindowManager/WindowLayoutStore.h 承担它拥有手动布局的参考形态——每个窗口的矩形、测量时的画布尺寸、等待窗口注册的待定几何并以稳定的(widgetType, relativeIndex)身份为键因此布局能在项目重载导致窗口重新编号后依然正确恢复。四、源码级实现剖析规格文档是WHAT 与 WHYPhase 1 of 4实现细节由 plan 承载。当前仓库中该特性状态为done全部 12 条验收标准已勾选。以下按层拆解真实代码。4.1 SnapGuides吸附核心core/Ui/UI/SnapGuides.h 是纯算法的吸附引擎核心数据结构SnapInput一次吸附解析的输入——候选几何、画布范围、兄弟窗口矩形集、阈值、最小尺寸仅限缩放、网格开关与尺寸、siblingSpacing与邻居齐平吸附的间隙、smartGuidesEnabled关闭时只做网格量化SnapResult输出——吸附后的矩形、尺寸匹配矩形、辅助线列表、等距指示列表snapToFraction()/fractionLabel()分数吸附与标签——除规格需求外源码还实现了扳手分数缩放预览footprint 上标注以画布分数表示的宽/高属于同一精度工具家族的额外落地。4.2 SnapOverlay 与 WindowManager手势状态机与可视化发布core/Ui/UI/WindowManager/SnapOverlay.h 拥有手动移动/缩放手势的全部视觉反馈对齐辅助线、等距指示、尺寸匹配兄弟、分数预览与实时徽章。设计上强调按需发布——每个发布器只在其值真正变化时发信号因此解析结果与上次相同的视觉不会触发无谓的 QML 重新求值。core/Ui/UI/WindowManager.h 中的WindowManagerQQuickItem则拥有窗口注册表、交互状态机与 QML 表面把 QML 绑定的叠加层属性全部转发出去alignmentGuides/spacingIndicators/sizeMatchRect/sizeMatchVisible/fractionPreviewRect/fractionPreviewLabel—— 手势叠加层数据manualGestureActive/manualGestureGeometry—— 手势活跃状态与徽章几何gridEnabled/gridSize—— 网格开关与尺寸snapIndicator/snapIndicatorVisible—— 吸附指示框。窗口几何工具WindowGeometry.h提供了关键常量与函数kResizeMargin 8窗口边缘 8 px 像素带内开始缩放而非拖动、ResizeEdge八方向枚举、computeResizedGeometry()、clampResizeToCanvas()、constrainGeometry()。缩放时固定边不移位的保证、画布边界钳制都在此层完成。4.3 DashboardCanvas网格、吸附指示与手势叠加层app/qml/MainWindow/Panes/Dashboard/DashboardCanvas.qml 是特性在 QML 侧的集中展示区网格见 R6 章节Canvas用Cpp_ThemeManager.colors[canvas_grid]画 1 px 网格线吸附指示框第 632–655 行_snapIndicator按真实吸附几何渲染边框按触碰边内缩 1 px颜色取主题snap_indicator_background/snap_indicator_border手势叠加层第 661–775 行_gestureOverlay仅在手动模式且非冻结时可见内含四个视觉族——辅助线Repeater遍历_wm.alignmentGuides用主题色highlight渲染每条线统一透明度 0.8等距指示遍历_wm.spacingIndicators半透明高亮 居中显示间距像素数尺寸匹配2 px 描边的sizeMatchRect高亮匹配兄弟分数预览标注落点 footprint 的宽/高画布分数标签允许溢出 footprint 并被钳制在画布内。所有颜色均来自Cpp_ThemeManager满足视觉跟随主题、无硬编码颜色的约束也保证在用户自定义背景图片上依然可读。4.4 WidgetDelegate48×48 的落地如 R9 所述WidgetDelegate.qml 用一行三元表达式区分两种模式的最小尺寸。规格约束要求标题栏与按钮在 48 px 宽度下保持可用放不下的 chrome 必须优雅折叠而非溢出或不可点击——这是MiniWindow外壳caption 栏的职责按钮保持可见可点是 AC9 验收的核心。4.5 WindowLayoutStore持久化存储形态如 R11 所述WindowLayoutStore.h 以(widgetType, relativeIndex)稳定身份为键保存手动几何与参考画布尺寸serialize()/applyManualLayout()/applySavedGeometries()构成保存-恢复链路preload()处理几何先于窗口注册到达的时序问题。旧布局字节级兼容加载小窗口布局在旧版 356×320 下限上最多被钳制放大不会崩溃或错位恢复。五、验收标准AC1–AC12规格附带的验收标准全部为已勾选状态是手动验证与回归的完整清单编号验收内容应用内AC1拖动窗口缓慢经过另一窗口左边缘、上边缘与水平中心各自产生可见吸附 辅助线落点与目标对齐相差 0 px用 R5 徽章核对AC2缩放右边缘靠近邻居右边缘吸附齐平且左边缘整个手势不移动AC3三窗口一行拖动第三个直到间距匹配第一对的间距间距指示出现落点后两个间距像素级相等AC4缩放窗口宽度匹配兄弟宽度尺寸匹配提示出现徽章中两者宽度读数一致AC5徽章手势开始即出现、实时跟踪、与最终保存几何一致、松开即消失AC6开启指定单元格的网格移动落在网格线上关闭后恢复自由放置开关状态在应用重启后保留AC7拖动过程中按住 Alt 经过已知吸附对齐不产生吸附与辅助线手势内松开 Alt 重新启用AC8手动模式下贴画布四边拖动从不出现旧的半屏/四分之一屏吸附矩形AC9窗口精确缩到 48×48 并停住关闭/最小化/最大化按钮在该尺寸下可见可点48×48 窗口以相同几何保存/重载AC10存在多个小于 356×320 窗口时切回自动布局packing 成功、无重叠或零尺寸窗口切回恢复保存的手动几何既有往返行为AC11冻结开启时任何手势/辅助线/徽章/网格交互均不可用自动布局开启时新视觉永不出现AC12回归--benchmark-hotpath门控不变该特性仅为交互期 UI帧路径上无任何运行代码其中 AC6 的重启后保留在源码中由 WindowManager.cpp 的QSettings读写落实AC12 是架构约束的回归兜底——吸附与网格计算只发生在手势期间telemetry 帧路径完全不受影响。对应的单元测试可见 app/tests/tst_snap_overlay.cpp钉死 SnapOverlay 的发布契约每个发布器存储什么、触发哪个变更信号、重复发布不变值保持静默与 app/tests/tst_window_geometry.cpp几何计算与边界行为。六、约束与不变量决定性约束精度但不粘手。吸附必须让像素级对齐成为轻松默认同时保持普通拖动的流畅——小阈值、即时视觉反馈、可靠的旁路Alt。一个与用户对抗的吸附系统不如没有。性能边界。辅助线计算与渲染只运行于活跃手势期间、交互频率下不向遥测帧路径添加任何工作30 窗口的面板在拖动时不得卡顿。冻结输入门控绝对化。冻结继续中止/拒绝所有操纵路径任何新手势逻辑不得改变它。持久化兼容。手动几何沿用既有存储形态按画布尺寸桶、按项目旧布局字节级兼容加载小窗口布局在旧版 356×320 下限上只做钳制放大。48 px 下的 chrome。标题栏、按钮与命中区域在 48 px 宽度下必须可用放不下的 chrome 优雅折叠不溢出、不可点击失禁。主题与可读性。辅助线/网格视觉跟随当前主题无硬编码颜色且在用户设置背景图片上保持可读。免费功能。该特性的任何部分均不设 Pro/版本门槛。RTL 兼容。辅助线与徽章须在LayoutMirroring生效时正确渲染。七、未决问题Open Questions规格保留了两个开放决策均已由实现给出答案网格默认单元格大小与开关位置——规格让 plan 提议、维护者选择。实现选择了画布右键菜单承载开关Show Grid与五档尺寸8/16/24/32/64 px默认 16 px见 WindowManager.cpp 与 DashboardCanvas.qml。等间距吸附是否扩展至缩放——规格跟随 Figma仅限移动手势当前实现保持一致。八、总结如何用好这套精度工具从使用视角归纳Spec 0010 让手动布局模式具备了完整的设计工具体验对齐拖动或缩放窗口靠近另一窗口的边缘/中心、画布边缘/中心线时6 px 阈值内自动吸附辅助线即时确认——AC1/AC2 是它的操作范本等距与尺寸排行/列时让新间距匹配既有间距R3缩放时让宽度/高度匹配兄弟R4读数任何手势中都可用徽章核对精确 x/y/w×hR5网格右键画布 →Show Grid选 8–64 px 档位获得固定节奏的吸附R6偏好跨会话保留自由放置按住 Alt 挂起全部吸附R7密集面板手动模式下把窗口缩到 48×48拼出 LED 簇、窄条、小数字读数等紧凑瓦片R9切回自动布局或冻结模式时所有辅助视觉自动消失、布局按既有结构安全往返R10/R11。这套特性是设计工具式精度与运行时仪表盘结合的范例规格把行为契约写到验收标准级实现则用SnapGuides的纯算法核心 SnapOverlay/WindowManager的按需发布 DashboardCanvas的主题化渲染三层结构落地并通过 tst_snap_overlay.cpp 与 tst_window_geometry.cpp 钉死行为边界值得作为 Qt Quick 桌面应用交互精度设计的参考实现。【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表