046097918d
回放页 v1.0 建的键处理返回 true(接管全部键),但从未调 ui_content_page_invalidate():框架只在 key_cb 返回 false 时才替页面 失效,于是「键送达、状态已切、屏上纹丝不动」。该病被枚举缺陷完全 遮住(整页恒空、没有可切的画面),随本波枚举修复首次上板才暴露: 真机按 ←/→/↑/↓ 帧字节完全不变(同帧哈希),布局与状态机无问题。 - 上/下切通道、左/右切段成功路径、空态再探路径,各补一次 ui_content_page_invalidate()(与 ui_page_clock / ui_page_password 等已接管键的页面同纪律); - 切段失败仍保持「按了没动」的诚实语义(不重绘、不把忙态清成空); - 修改记录 v1.1。 /keil-build 0 错误 0 警告(Code 247,288 B,+4 B),RAM 不变; 台账 / 同码凭证同批刷新。 Refs #38
446 lines
18 KiB
C
446 lines
18 KiB
C
/*
|
||
* 模块名称:UI Page wave_play (录波回放内容页)
|
||
* 模块功能:记录查询 → 录波回放 叶子的内容页——单通道阶梯波形回放(设计
|
||
* docs/子系统设计/故障录波设计说明.md §8.1 元素表逐条落地):
|
||
* 顶行 = 通道名 + 段号 + 触发源字母(M 手动 / P 保护 / T 定时);
|
||
* 波形区 = 两周波 40 点、每点占 3 px 的**阶梯线**(1 bpp 下平滑
|
||
* 折线的过零平缓段会被阈值吃掉,ui_deco.h 实测口径;阶梯线每段
|
||
* 非水平即垂直,天然绕开,也更贴近「离散采样」的事实);
|
||
* 参考线 = 0 线(虚线)+ 窗口峰值标注(定点 mV,ASCII);
|
||
* 底行 = 单位徽标(只读段头 eng,eng 绝不参与算式——§6.3 钉死,
|
||
* PC 道同一口径);形状受限通道右上打「削」徽标;
|
||
* 空态显式文案「无录波段」/「该段不可读」——画成一条直线等于
|
||
* 伪造证据(§8.1 空态行,此判据优先于「页面上总得画点东西」)。
|
||
* 键位:上下切通道、左右切段(key_intercept=1 才能把 LEFT 从
|
||
* 「关页」手里要来);ESC 关页。
|
||
* 取数纪律:本文件零 App include——段号/段头/窗口码值/峰值 mV 全部经
|
||
* ui_data.h 录波注入表进来(波形算式与定点换算在执行侧,页面
|
||
* 连 b_codes 都不碰,收到的码值已并偏移);首帧绘制才懒取数
|
||
* (开页链零 I/O,绘制定律不破)。
|
||
* 显示窗口与光标(与落盘道/PC 道的同一裁定,写在这里免得两头漂):
|
||
* 窗口 = 触发点前一周波 + 后一周波共 40 点,窗口起点 = 段内点号
|
||
* 「预窗点数 减 二十」(即执行侧 seg_win 的固定窗);虚线竖光标
|
||
* 落在窗内第 二十 与第 廿一 点之间(0 基第 19/20 点边界,即
|
||
* 波形区正中 x)——依据 = 设计 §4.2 触发点位置 + App/algo/
|
||
* wave_ring.h 的点序注释(触发 tick 采样 = 预窗最后一点),
|
||
* 页面不复述任何换算式。
|
||
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
|
||
* 作者:DTU 项目组
|
||
* 创建日期:2026-10-29
|
||
* 修改记录:
|
||
* v1.0 2026-10-29 DTU 项目组 创建(故障录波道 UI 侧)
|
||
* v1.1 2026-11-02 DTU 项目组 按键切通道/切段补 ui_content_page_invalidate:
|
||
* 本页 key_cb 返回 true(接管键),框架不再替本页失效重绘,状态变了
|
||
* 屏上却纹丝不动——该病在枚举修复前整页恒空、从未有键可切,故随
|
||
* 2026-11-02 回放页修复首次上板才暴露(真机实证见 PR #67)。
|
||
*/
|
||
|
||
/* 头文件包含区 */
|
||
#include "ui_page_wave_play.h"
|
||
|
||
#include <string.h>
|
||
|
||
#include "ui_content_page.h"
|
||
#include "ui_data.h"
|
||
#include "ui_tokens.h"
|
||
|
||
/* 私有宏定义区 */
|
||
|
||
/* 绘制区几何(屏宽 160:波形区左右各留 20 px 边;高 90 px) */
|
||
#define WP_WX0 20 /* 波形区左边界 x */
|
||
#define WP_PX_PER_PT 3 /* 每点占宽(§8.1 阶梯线口径) */
|
||
#define WP_WTOP 34 /* 波形区顶 y(信息行下方) */
|
||
#define WP_WBOT 124 /* 波形区底 y(0 线最多贴到这里) */
|
||
#define WP_WSPANS 90 /* 纵向可用像素 = WP_WBOT - WP_WTOP */
|
||
#define WP_CUR_X (WP_WX0 + (UI_WAVE_WIN_PTS / 2u) * WP_PX_PER_PT)
|
||
/* 触发虚线光标 x(窗口正中,理由见文件头) */
|
||
#define WP_INFO_Y 20 /* 顶行(通道/段号/触发 + 削徽标)条带 y */
|
||
#define WP_HINT_Y 128 /* 倒数第二行(峰值/键位提示)条带 y */
|
||
#define WP_ENG_Y 143 /* 底行(单位徽标)条带 y(页脚已隐藏) */
|
||
#define WP_EMPTY_Y 60 /* 空态文案条带 y(近屏中部) */
|
||
|
||
/* 页面数据态:未取数前不画任何波形元素 */
|
||
#define WP_ST_IDLE 0u /* 未取数/无段(空态文案) */
|
||
#define WP_ST_OK 1u /* 段完整,可画波形 */
|
||
#define WP_ST_BAD 2u /* 段不可读(显式文案,绝不画线) */
|
||
|
||
/* 私有函数声明区 */
|
||
|
||
static void wp_load_seg(void);
|
||
static void wp_ensure(void);
|
||
static void wp_draw_text(lv_layer_t *a_layer, const char *a_text,
|
||
int32_t a_x, int32_t a_y, uint8_t a_align,
|
||
const lv_area_t *a_clip);
|
||
static int32_t wp_map_y(int32_t a_v, int32_t a_dmin, int32_t a_span);
|
||
|
||
/* 私有变量定义区 */
|
||
|
||
/*
|
||
* 通道名(ASCII 段名 = 语义取数层的通道语义名,页面自带表避免为了
|
||
* 六个字母再开一条注入边;与段头通道表的语义顺序一致:三相电压/零序/
|
||
* 三相电流在前,形状受限路按段头 conv 位区分——名字本身两端一致)
|
||
*/
|
||
static const char *const s_ch_names[UI_WAVE_CH_CNT] = {
|
||
"UA", "UB", "UC", "UN", "IA", "IB", "IC", "IN"
|
||
};
|
||
|
||
/* 触发源字母(值域 = 段头 trig_src;未识别给 '?' 不给猜) */
|
||
static const char s_trig_letters[] = { '?', 'M', 'P', 'T' };
|
||
#define WP_TRIG_MAX ((uint8_t)(sizeof(s_trig_letters) - 1u))
|
||
|
||
static uint8_t s_state; /* WP_ST_* 三态 */
|
||
static uint8_t s_idx; /* 当前段号(盘上编号,0..99) */
|
||
static uint8_t s_ch; /* 当前通道(上下键切) */
|
||
static uint8_t s_eng; /* 段头单位口径(只读徽标) */
|
||
static uint8_t s_trig; /* 段头触发源 */
|
||
static uint8_t s_clip; /* 段头形状受限位图(位号=通道) */
|
||
static int16_t s_codes[UI_WAVE_WIN_PTS]; /* 当前窗码值(执行侧已并偏移) */
|
||
static int32_t s_peak_milli; /* 窗口峰值 mV(执行侧算好) */
|
||
|
||
/* 函数定义区 */
|
||
|
||
/*
|
||
* 函数功能:取当前段的头与窗口(三态落到 s_state,坏态一律显式文案)
|
||
* 入口参数:无(读 s_idx / s_ch)
|
||
* 返回值:无
|
||
* 限定条件:仅在 uiTask 绘制/按键链内调用(经注入表触到执行侧)
|
||
* 函数说明:头都读不成时连顶行都不画——通道名以外的字段全来自段头,
|
||
* 缺一半字段还硬凑顶行等于把「读不到」伪装成「读到了」
|
||
*/
|
||
static void wp_load_seg(void) {
|
||
int rc = ui_data_wave_seg_head(s_idx, &s_eng, &s_trig, &s_clip);
|
||
|
||
if (rc != UI_WAVE_OK) {
|
||
s_state = (rc == UI_WAVE_BAD) ? WP_ST_BAD : WP_ST_IDLE;
|
||
return;
|
||
}
|
||
rc = ui_data_wave_seg_win(s_idx, s_ch, s_codes, &s_peak_milli);
|
||
if (rc != UI_WAVE_OK) {
|
||
s_state = (rc == UI_WAVE_BAD) ? WP_ST_BAD : WP_ST_IDLE;
|
||
return;
|
||
}
|
||
s_state = WP_ST_OK;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:首帧懒取数(开页链零 I/O 的落地方式:真正的卷读取推迟到
|
||
* 第一次绘制——模拟器截图与真机重绘走同一条链,行为一致)
|
||
* 入口参数:无
|
||
* 返回值:无
|
||
* 限定条件:draw_cb 开头调用
|
||
* 函数说明:取不到段就停在空态;此后再按左右键仍会重试(手动录波从
|
||
* 触发到成段有一秒级延迟,页开着等段出现是回放页的正常用法,
|
||
* 不做「试过就没有了」的缓存)
|
||
*/
|
||
static void wp_ensure(void) {
|
||
uint8_t idx = 0u;
|
||
int rc;
|
||
|
||
if (s_state != WP_ST_IDLE) {
|
||
return;
|
||
}
|
||
rc = ui_data_wave_seg_first(&idx);
|
||
if (rc == UI_WAVE_OK) {
|
||
s_idx = idx;
|
||
wp_load_seg();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 函数功能:单行文本绘制(对齐可选;ui_page_action 私有拷贝同法,此处
|
||
* 多一个左/右对齐是因为顶行要把「削」徽标钉到右上角)
|
||
* 入口参数:a_layer - 绘制层;a_text - Flash 字面量;a_x - 锚点 x(对齐
|
||
* 含义:左=起点 中=屏宽轴 右=终点);a_y - 条带顶;
|
||
* a_align - 0 左 / 1 中 / 2 右;a_clip - 重绘区
|
||
* 返回值:无
|
||
* 限定条件:a_text 非空;条带与 clip 不相交即返回(culling)
|
||
* 函数说明:lv_text_get_width 必须传 strlen(传 0 不测量、传 -1 死循环,
|
||
* 框架同款警示);本 LVGL 版条带矩形给 lv_draw_label 做底色无关
|
||
* 文本定位用,字模颜色固定 UI_COL_FG
|
||
*/
|
||
static void wp_draw_text(lv_layer_t *a_layer, const char *a_text,
|
||
int32_t a_x, int32_t a_y, uint8_t a_align,
|
||
const lv_area_t *a_clip) {
|
||
lv_area_t band;
|
||
lv_draw_label_dsc_t ld;
|
||
int32_t w = (int32_t)lv_text_get_width(a_text, (uint32_t)strlen(a_text),
|
||
LV_FONT_DEFAULT, 0);
|
||
|
||
band.x1 = 0;
|
||
band.x2 = UI_SCREEN_W - 1;
|
||
band.y1 = a_y;
|
||
band.y2 = a_y + UI_TEXT_BAND_H - 1;
|
||
if ((band.x1 > a_clip->x2) || (band.x2 < a_clip->x1) ||
|
||
(band.y1 > a_clip->y2) || (band.y2 < a_clip->y1)) {
|
||
return;
|
||
}
|
||
lv_draw_label_dsc_init(&ld);
|
||
ld.base.layer = a_layer;
|
||
ld.text = a_text;
|
||
ld.text_static = 1u;
|
||
ld.color = UI_COL_FG;
|
||
ld.ofs_x = (a_align == 1u) ? (a_x - (w / 2))
|
||
: ((a_align == 2u) ? (a_x - w) : a_x);
|
||
ld.ofs_y = 0;
|
||
lv_draw_label(a_layer, &ld, &band);
|
||
}
|
||
|
||
/*
|
||
* 函数功能:顶行触发字母(越界值给 '?' 不猜)
|
||
* 入口参数:a_trig - 段头 trig_src 原值
|
||
* 返回值:字母 ASCII char
|
||
* 限定条件:仅绘制路径
|
||
*/
|
||
static char wp_trig_letter(uint8_t a_trig) {
|
||
return (a_trig <= WP_TRIG_MAX) ? s_trig_letters[a_trig] : '?';
|
||
}
|
||
|
||
/*
|
||
* 函数功能:码值域到屏幕 y 的线性映射(0 基线必在域内:域取
|
||
* 「min(0, 窗最小) .. max(0, 窗最大)」,削顶钉下轨的通道也能
|
||
* 一眼看出贴的是 0 线还是别的什么)
|
||
* 入口参数:a_v - 码值;a_dmin - 域底;a_span - 域高(域宽,恒 >0)
|
||
* 返回值:波形区内 y 像素(WP_WBOT = 域底,WP_WTOP = 域顶) int32_t
|
||
* 限定条件:绘制路径纯算术,零除由调用侧钳 span 保证
|
||
* 函数说明:整数乘除即可——域高不超过 65534,先乘后除无溢出风险
|
||
*/
|
||
static int32_t wp_map_y(int32_t a_v, int32_t a_dmin, int32_t a_span) {
|
||
return WP_WBOT - (((a_v - a_dmin) * WP_WSPANS) / a_span);
|
||
}
|
||
|
||
/*
|
||
* 函数功能:波形区自绘——阶梯线 + 0 线(虚线)+ 触发点虚线竖光标
|
||
* 入口参数:a_layer / a_clip - 契约见 ui_content_page.h
|
||
* 返回值:无
|
||
* 限定条件:仅 s_state == WP_ST_OK 时被调用;s_codes 已备
|
||
* 函数说明:阶梯 = 每点先画 3 px 水平段、再在点边界补一段垂直连线,
|
||
* 全程只有水平与垂直两种线段(1 bpp 抗阈值裁定的直接落地);
|
||
* 0 线与光标用 dash(ui_deco 先例只画过实线,dash 字段是 LVGL
|
||
* 线段 dsc 自带的,单色层同样按位落墨);整区一次 cull,区内
|
||
* 不再逐线判交——波形区就 120x90,逐线判交省不了多少,判错
|
||
* 反而留下半截线
|
||
*/
|
||
static void wp_draw_wave(lv_layer_t *a_layer, const lv_area_t *a_clip) {
|
||
lv_area_t band;
|
||
lv_draw_line_dsc_t ld;
|
||
int32_t vmin = s_codes[0];
|
||
int32_t vmax = s_codes[0];
|
||
int32_t dmin;
|
||
int32_t dmax;
|
||
int32_t span;
|
||
int32_t i;
|
||
int32_t y;
|
||
int32_t y_prev = 0;
|
||
|
||
band.x1 = 0;
|
||
band.x2 = UI_SCREEN_W - 1;
|
||
band.y1 = WP_WTOP;
|
||
band.y2 = WP_WBOT;
|
||
if ((band.x1 > a_clip->x2) || (band.x2 < a_clip->x1) ||
|
||
(band.y1 > a_clip->y2) || (band.y2 < a_clip->y1)) {
|
||
return;
|
||
}
|
||
for (i = 1; i < (int32_t)UI_WAVE_WIN_PTS; i++) {
|
||
int32_t v = s_codes[i];
|
||
if (v < vmin) {
|
||
vmin = v;
|
||
}
|
||
if (v > vmax) {
|
||
vmax = v;
|
||
}
|
||
}
|
||
dmin = (vmin < 0) ? vmin : 0;
|
||
dmax = (vmax > 0) ? vmax : 0;
|
||
span = dmax - dmin;
|
||
if (span < 1) {
|
||
span = 1; /* 全零窗:0 线与波形线重合贴在区底,诚实且无除零 */
|
||
}
|
||
|
||
lv_draw_line_dsc_init(&ld);
|
||
ld.base.layer = a_layer;
|
||
ld.color = UI_COL_FG;
|
||
ld.width = 1;
|
||
|
||
/* 0 线(虚线):恒在域内,永远画得出来 */
|
||
ld.dash_width = 2;
|
||
ld.dash_gap = 2;
|
||
y = wp_map_y(0, dmin, span);
|
||
ld.p1.x = WP_WX0 - 2;
|
||
ld.p1.y = y;
|
||
ld.p2.x = WP_WX0 + ((int32_t)UI_WAVE_WIN_PTS * WP_PX_PER_PT) + 1;
|
||
ld.p2.y = y;
|
||
lv_draw_line(a_layer, &ld);
|
||
|
||
/* 触发点竖光标(虚线):第 二十/廿一 点之间的点边界(见文件头裁定) */
|
||
ld.p1.x = WP_CUR_X;
|
||
ld.p1.y = WP_WTOP;
|
||
ld.p2.x = WP_CUR_X;
|
||
ld.p2.y = WP_WBOT;
|
||
lv_draw_line(a_layer, &ld);
|
||
|
||
/* 阶梯线(实线) */
|
||
ld.dash_width = 0;
|
||
ld.dash_gap = 0;
|
||
for (i = 0; i < (int32_t)UI_WAVE_WIN_PTS; i++) {
|
||
int32_t x;
|
||
|
||
x = WP_WX0 + (i * WP_PX_PER_PT);
|
||
y = wp_map_y((int32_t)s_codes[i], dmin, span);
|
||
ld.p1.x = x;
|
||
ld.p1.y = y;
|
||
ld.p2.x = x + WP_PX_PER_PT - 1;
|
||
ld.p2.y = y;
|
||
lv_draw_line(a_layer, &ld);
|
||
if ((i > 0) && (y != y_prev)) {
|
||
ld.p1.x = x;
|
||
ld.p1.y = y_prev;
|
||
ld.p2.x = x;
|
||
ld.p2.y = y;
|
||
lv_draw_line(a_layer, &ld);
|
||
}
|
||
y_prev = y;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 函数功能:单位徽标取词(只读 eng 选词,eng 不进任何算式——§6.3 口径;
|
||
* 未识别值按最保守的「引脚域」渲染,不猜高口径)
|
||
* 入口参数:a_eng - 段头 eng 原值
|
||
* 返回值:徽标文案(Flash 字面量) const char *
|
||
* 限定条件:仅绘制路径
|
||
*/
|
||
static const char *wp_eng_word(uint8_t a_eng) {
|
||
if (a_eng == (uint8_t)UI_DATA_ENG_SEC) {
|
||
return "二次值";
|
||
}
|
||
if (a_eng == (uint8_t)UI_DATA_ENG_PRI) {
|
||
return "一次值";
|
||
}
|
||
return "引脚域";
|
||
}
|
||
|
||
/*
|
||
* 函数功能:开页复位(框架 init_cb)——通道回到 UA、数据回到未取态
|
||
* 入口参数:无
|
||
* 返回值:无
|
||
* 限定条件:框架开页链内;只清状态零 I/O(懒取数在首帧绘制)
|
||
*/
|
||
static void pg_init(void) {
|
||
s_state = WP_ST_IDLE;
|
||
s_ch = 0u;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:自绘(框架 draw_cb)
|
||
* 入口参数:a_layer / a_clip - 契约见 ui_content_page.h
|
||
* 返回值:无
|
||
* 限定条件:框架绘制链末尾调用
|
||
*/
|
||
static void pg_draw(lv_layer_t *a_layer, const lv_area_t *a_clip) {
|
||
char buf[UI_BUF_STRLEN];
|
||
|
||
wp_ensure();
|
||
if (s_state == WP_ST_BAD) {
|
||
wp_draw_text(a_layer, "该段不可读", UI_SCREEN_W / 2, WP_EMPTY_Y, 1u,
|
||
a_clip);
|
||
return;
|
||
}
|
||
if (s_state != WP_ST_OK) {
|
||
wp_draw_text(a_layer, "无录波段", UI_SCREEN_W / 2, WP_EMPTY_Y, 1u,
|
||
a_clip);
|
||
return;
|
||
}
|
||
|
||
/* 顶行:左 = 通道 + 段号 + 触发字母;右 = 形状受限「削」徽标 */
|
||
(void)lv_snprintf(buf, sizeof(buf), "%s SEG%u %c", s_ch_names[s_ch],
|
||
(unsigned int)s_idx, wp_trig_letter(s_trig));
|
||
wp_draw_text(a_layer, buf, UI_LIST_LEFT_X, WP_INFO_Y, 0u, a_clip);
|
||
if ((s_clip & (uint8_t)(1u << s_ch)) != 0u) {
|
||
wp_draw_text(a_layer, "削", UI_SCREEN_W - 1, WP_INFO_Y, 2u, a_clip);
|
||
}
|
||
|
||
wp_draw_wave(a_layer, a_clip);
|
||
|
||
/* 倒数第二行:左 = 键位提示(ASCII);右 = 窗口峰值 mV(定点,ASCII) */
|
||
wp_draw_text(a_layer, "UD=CH LR=SEG", UI_LIST_LEFT_X, WP_HINT_Y, 0u,
|
||
a_clip);
|
||
(void)lv_snprintf(buf, sizeof(buf), "PK%dmV", (int)s_peak_milli);
|
||
wp_draw_text(a_layer, buf, UI_SCREEN_W - 1, WP_HINT_Y, 2u, a_clip);
|
||
|
||
/* 底行:单位徽标(eng) */
|
||
wp_draw_text(a_layer, wp_eng_word(s_eng), UI_SCREEN_W / 2, WP_ENG_Y, 1u,
|
||
a_clip);
|
||
}
|
||
|
||
/*
|
||
* 函数功能:按键处理(框架 key_cb)——上下切通道、左右切段
|
||
* 入口参数:a_key - LVGL 键值 lv_key_t
|
||
* 返回值:true = 本页已消费;false = 交回框架 bool
|
||
* 限定条件:框架按键链内(ESC 不到这里;LEFT 因 key_intercept=1 先到这里)
|
||
* 函数说明:环游语义 = 上下在八路间绕回、左右在现存段间绕回;切段失败
|
||
* (卷忙/无邻段)保持当前画面不动——「按了没动」比「画面被
|
||
* 忙态清成空」诚实,忙不忙在回放页本来就不是用户要的答案
|
||
*/
|
||
static bool pg_key(lv_key_t a_key) {
|
||
uint8_t next;
|
||
int rc;
|
||
|
||
switch (a_key) {
|
||
case LV_KEY_UP:
|
||
case LV_KEY_DOWN:
|
||
next = (a_key == LV_KEY_UP)
|
||
? (uint8_t)((s_ch + UI_WAVE_CH_CNT - 1u) % UI_WAVE_CH_CNT)
|
||
: (uint8_t)((s_ch + 1u) % UI_WAVE_CH_CNT);
|
||
s_ch = next;
|
||
if (s_state == WP_ST_OK) {
|
||
rc = ui_data_wave_seg_win(s_idx, s_ch, s_codes, &s_peak_milli);
|
||
if (rc != UI_WAVE_OK) {
|
||
s_state = (rc == UI_WAVE_BAD) ? WP_ST_BAD : WP_ST_IDLE;
|
||
}
|
||
}
|
||
/* 状态已变必须显式失效:框架只在 key_cb 返回 false 时自己 invalidate,
|
||
* 本页接管了键(true),不失效就永远画旧画面(2026-11-02 真机实证:
|
||
* 键送达、状态已切、屏上纹丝不动——该病随枚举修复首次上板才暴露) */
|
||
ui_content_page_invalidate();
|
||
return true;
|
||
case LV_KEY_LEFT:
|
||
case LV_KEY_RIGHT:
|
||
if (s_state == WP_ST_IDLE) {
|
||
wp_ensure(); /* 空态下按左右 = 再探一次盘(新段可能已落) */
|
||
ui_content_page_invalidate();
|
||
return true;
|
||
}
|
||
rc = (a_key == LV_KEY_RIGHT) ? ui_data_wave_seg_next(s_idx, &next)
|
||
: ui_data_wave_seg_prev(s_idx, &next);
|
||
if (rc == UI_WAVE_OK) {
|
||
s_idx = next;
|
||
s_state = WP_ST_IDLE; /* 先回空态再载,坏段不会留着旧画面 */
|
||
wp_load_seg();
|
||
ui_content_page_invalidate(); /* 理由同上:切段成功要重绘 */
|
||
}
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 页面描述符(外部链接:生成物 ui_page_registry.c 按菜单树 #page=wave_play 绑定引用)
|
||
* 查看页形态:无浅 V、无页脚(段号在顶行,页脚「共 N 页」与段号两套计数
|
||
* 反而打架)、不可选(单元素自绘页)、可编辑位 0(本页零写动作);
|
||
* key_intercept=1 是本页存在的理由级配置:LEFT 要拿来切上一段,不能让
|
||
* 框架默认的「LEFT 关页」吃掉
|
||
*/
|
||
const content_page_def_t ui_page_wave_play_desc = {
|
||
.id = "wave_play",
|
||
.title = "录波回放",
|
||
.hide_deco = 1u,
|
||
.hide_footer = 1u,
|
||
.selectable = 0u,
|
||
.key_intercept = 1u,
|
||
.edit_capable = 0u,
|
||
.init_cb = pg_init,
|
||
.draw_cb = pg_draw,
|
||
.key_cb = pg_key,
|
||
};
|