PixelUI框架自带的几种 Popup 适合用来显示短消息、进度或输入一个固定位数的整数。
信息弹窗
1 | if (!ui.showPopupInfo("Saved", "Settings", 80, 30, 1500)) { |
进度弹窗
重载接受 int32_t&,固定使用 step 1 和百分比格式,编辑语义使用 CommitOnConfirm
1 | int32_t progress_ = 0; // 持久的 App 成员 |
百分比、原始值、缩放值或带单位文本都由 NumericFormatter 选择。
需要自定义 step 或实时编辑时,把 range 和 formatter 配置保存成持久成员:
1 | NumericRange progressRange_{}; |
进度弹窗的输入会按下述编辑策略处理:
| 输入 | CommitOnConfirm |
Live |
|---|---|---|
| LEFT/RIGHT | 只按 range.step() 修改 draft |
每次成功步进都立即写回并通知 |
| SELECT | 值有变化时写回并通知,然后关闭 | 关闭,不额外通知 |
| BACK | 丢弃 draft 并关闭 | 值有变化时恢复并通知 original value,然后关闭 |
Binding 写入失败时,弹窗保持打开,并维持一致的 draft。Session 契约详见通用数值层。
固定位数整数输入
1 | int32_t setpoint = 25; |
构造和排队都不会修改 setpoint。位数可以是 1 到 PIXELUI_MAX_INT_FIXED_WIDTH。
编辑器分为两层交互。焦点会在所有数字位、OK 和 CANCEL 之间移动。选中数字位会进入该位的局部编辑态;再次按 SELECT 只退出这一位的编辑态,弹窗继续保持打开。
| 状态与输入 | 结果 |
|---|---|
| 数字位获得焦点 + SELECT | 进入该位的局部编辑态 |
| 活动数字位 + LEFT/RIGHT | 只修改这一位 |
| 活动数字位 + SELECT | 结束这一位的编辑;不提交,也不关闭 |
| OK + SELECT | 汇总所有数字、提交并关闭 |
| CANCEL + SELECT,或任意状态下 BACK | 取消整个 Session 并关闭 |
超时、clearPopups() 或析构 |
取消尚未完成的 Session |
兼容重载使用 CommitOnConfirm:只有在 OK 提交且组合值确实变化时,回调才执行一次;CANCEL 和 BACK 不调用它。使用 ValueEditorBinding 重载并选择 ValueEditPolicy::Live 时,每次成功修改数字都会立即写回并通知;任何取消路径都会在值发生变化时恢复并通知 original value。
默认布局为 100x56。最小高度是 56;最小宽度取数字行与 OK/CANCEL 操作行中较宽者。低于这些限制或大于实际 display 的请求会在入队前被拒绝。默认编辑器无法在 96x40 display 上打开。
返回值 false 表示 Binding、位数、请求布局、display 边界、队列容量或受保护 dispatch 状态拒绝了请求;true 只表示请求已接受,非 owning 数据仍须覆盖 pending 和 active 的完整寿命。
队列和容量
PopupManager 是固定容量 FIFO:
1 | active Popup -> pending request 1 -> pending request 2 |
- 只有 active Popup 会被构造、绘制和接收输入。
- pending 项是入队前完成类型校验的
etl::variant<InfoRequest, ProgressRequest, ValueDigitsRequest>描述符,按先进先出处理。 PIXELUI_MAX_POPUP_NUM包含 active 和 pending。- 没有 priority 和抢占;队列满时新请求返回
false。 - active Popup 存在单槽
etl::variant_pool中,完成后销毁,再在同一个稳定槽位构造下一个。 - 请求回调沿队列移动到 active Popup,不会复制。
- 销毁 Popup 只停止自己的动画,不会清理无关的 App 动画。
生命周期与重入
text/title/font 指针、Binding context、Formatter context 及其引用的 suffix/range、注入的 Session,以及回调捕获的引用都是非拥有的。排队会把寿命要求延长到 pending 和 active 两个阶段全部结束,而不只是 showPopup...() 返回之后。
App pop 时会清理 active 和 pending Popup。若数据来自寿命更短的 owner,应提前调用 clearPopups()。
PopupManager 在构造、销毁、更新、绘制和派发输入期间拒绝 enqueue 和 clear。因此这些回调里不要同步打开或清理 Popup;记下 pending action,等当前 dispatch 返回后再做。保护区之外的普通连续调用,只要容量足够,仍按 FIFO 接受。


