新增加了 交流量 直流量 遥信量的查看 YC页面的基础编写
This commit is contained in:
@@ -1,45 +1,365 @@
|
||||
#include "Drv/pages/YC/view.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
static const PageRenderPort *s_port = NULL;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 宏定义:遥测页面布局常量
|
||||
* ------------------------------------------------------------------------- */
|
||||
#define YC_TOP_BAND_MAX_Y (24u) /* 顶栏最大 Y 坐标 */
|
||||
#define YC_CONTENT_BASE_Y (24u) /* 内容区起始 Y 坐标 */
|
||||
#define YC_NAME_X (6u) /* 名称显示 X 坐标 */
|
||||
#define YC_VALUE_X (100u) /* 数值显示 X 坐标 */
|
||||
#define YC_ROW_PAD_X0 (2u) /* 行内容左侧留白 */
|
||||
#define YC_ROW_PAD_X1 (2u) /* 行内容右侧留白 */
|
||||
#define YC_FOOTER_Y_FROM_BOTTOM (16u) /* 底栏距底部距离(与 PageRenderer_LcdShowInfoPage 一致)*/
|
||||
#define YC_FOOTER_GAP_PX (2u) /* 内容区与底栏之间的留白间隙 */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_ShowInfoPage
|
||||
* 功能:
|
||||
* 显示当前页码和总页数信息到底栏。
|
||||
*
|
||||
* 参数:
|
||||
* wPageNum - 当前页码(从 1 开始)
|
||||
* wPageMax - 总页数
|
||||
*
|
||||
* 边界处理:
|
||||
* - 本函数不做参数合法性校验,直接传递给渲染端口显示。
|
||||
*
|
||||
* 说明:
|
||||
* - 该函数通过 s_port->show_info_page() 调用底层渲染接口显示页码信息。
|
||||
* - 通常在内容区绘制完成后调用,用于告知用户当前浏览位置。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
static void YCView_ShowInfoPage(uint16_t wPageNum, uint16_t wPageMax)
|
||||
{
|
||||
s_port->show_info_page(wPageNum, wPageMax);
|
||||
}
|
||||
|
||||
static void YCView_ShowTerminalInfo(void)
|
||||
{
|
||||
uint8_t *context[] = {
|
||||
"终端类型 : F30",
|
||||
"终端型号 : F30",
|
||||
"软件版本 : SV0.010",
|
||||
"硬件版本 : HW0.010",
|
||||
"软件校验 : 4454",
|
||||
"程序日期 : 2024.08.27"
|
||||
};
|
||||
s_port->show_str(32, 26, "馈线自动化终端");
|
||||
for(uint8_t index = 0; index < 6; index++ )
|
||||
{
|
||||
s_port->show_str(6, 26 + (index + 1) * (s_port->get_ascii_height() + s_port->get_row_space()), context[index]);
|
||||
}
|
||||
s_port->show_info_page(wPageNum, wPageMax);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_ShowTopName
|
||||
* 功能:
|
||||
* 在页面顶栏居中显示顶部名称,并绘制装饰性箭头。
|
||||
*
|
||||
* 参数:
|
||||
* name - 要显示的顶部名称字符串(UTF-8 编码)
|
||||
*
|
||||
* 边界处理:
|
||||
* - 本函数不对 name 做空指针校验,调用方需保证 name 有效。
|
||||
* - 若名称过长导致居中计算偏移为负数,显示位置可能异常,由底层渲染处理。
|
||||
*
|
||||
* 说明:
|
||||
* - 首先填充整个屏幕为背景色,实现清屏效果。
|
||||
* - 通过 s_port->get_utf8_len() 和 s_port->get_ascii_width() 计算字符串显示宽度。
|
||||
* - 使用居中公式 (screen_width - text_width) / 2 确定 X 坐标。
|
||||
* - 在 Y=3 位置绘制名称,并在固定位置 (18, 2) 绘制箭头装饰(draw_meitou)。
|
||||
* - 顶栏高度为 0-23 像素,名称显示于第 3 行以确保视觉美观。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
static void YCView_ShowTopName(const uint8_t *name)
|
||||
{
|
||||
uint16_t wLen = s_port->get_utf8_len(name) * s_port->get_ascii_width();
|
||||
uint16_t wLen = s_port->get_utf8_len(name) * s_port->get_ascii_width();
|
||||
s_port->fill_rect(0, 0, s_port->get_size_x() - 1, s_port->get_size_y() - 1, s_port->get_color_back());
|
||||
/* 显示顶部名称,居中显示 */
|
||||
/* 显示顶部名称,居中显示 */
|
||||
s_port->show_str((s_port->get_size_x() - wLen) / 2, 3, name);
|
||||
s_port->draw_meitou(18, 2);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_RowY
|
||||
* 功能:
|
||||
* 根据行号计算该行在屏幕上的实际 Y 坐标。
|
||||
*
|
||||
* 参数:
|
||||
* row - 行号(从 0 开始)
|
||||
*
|
||||
* 边界处理:
|
||||
* - 本函数不做行号范围校验,调用方应保证 row 有效。
|
||||
*
|
||||
* 说明:
|
||||
* - 计算公式:row_y = YC_CONTENT_BASE_Y + row × (字符高度 + 行间距)
|
||||
* - YC_CONTENT_BASE_Y 为内容区起始 Y 坐标(24 像素)。
|
||||
* - 每行高度由 s_port->get_ascii_height() 和 s_port->get_row_space() 决定。
|
||||
* - 该函数确保所有遥测数据显示在内容区内,从第 24 像素开始向下排列。
|
||||
*
|
||||
* 返回值:
|
||||
* - 该行在屏幕上的 Y 坐标
|
||||
* ------------------------------------------------------------------------- */
|
||||
static uint16_t YCView_RowY(uint8_t row)
|
||||
{
|
||||
uint16_t lineH = s_port->get_ascii_height() + s_port->get_row_space();
|
||||
return YC_CONTENT_BASE_Y + (uint16_t)row * lineH;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_DrawRowNameAndValue
|
||||
* 功能:
|
||||
* 在指定行绘制遥测项的名称和数值。
|
||||
*
|
||||
* 参数:
|
||||
* name - 名称字符串指针
|
||||
* value - 数值字符串指针
|
||||
* row - 目标行号(从 0 开始)
|
||||
* drawName - 是否显示名称的标志,非 0 表示显示,0 表示不显示
|
||||
*
|
||||
* 边界处理:
|
||||
* - 本函数不对 name/value 做空指针校验,调用方需保证字符串有效。
|
||||
* - 若 drawName 为 0,则跳过名称绘制,仅显示数值。
|
||||
*
|
||||
* 说明:
|
||||
* - 根据 drawName 标志决定是否在左侧区域(YC_NAME_X)显示名称。
|
||||
* - 数值始终在右侧固定位置(YC_VALUE_X)显示。
|
||||
* - Y 坐标通过 YCView_RowY(row) 计算,确保内容对齐到指定行。
|
||||
* - 该函数是遥测数据显示的核心绘制单元,被 YCView_PaintContent() 调用。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
static void YCView_DrawRowNameAndValue(const uint8_t *name, const uint8_t *value, uint8_t row, uint8_t drawName)
|
||||
{
|
||||
if (drawName != 0u)
|
||||
{
|
||||
s_port->show_str(YC_NAME_X, YCView_RowY(row), name);
|
||||
}
|
||||
s_port->show_str(YC_VALUE_X, YCView_RowY(row), value);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_ClearContentArea
|
||||
* 功能:
|
||||
* 清空内容区域(不含顶栏和底栏),填充背景色并准备重绘。
|
||||
*
|
||||
* 参数:
|
||||
* 无
|
||||
*
|
||||
* 边界处理:
|
||||
* - 若内容区上边界 y0 大于等于下边界 y1,或屏幕宽度为 0,不执行填充操作。
|
||||
* - 自动将下边界限制在屏幕有效范围内(sy-1)。
|
||||
*
|
||||
* 说明:
|
||||
* - 内容区范围:从 YC_CONTENT_BASE_Y-2 到 YC_FOOTER_Y_FROM_BOTTOM
|
||||
* - 上边界预留 2 像素用于视觉缓冲,避免与顶栏过于接近。
|
||||
* - 下边界通过 YC_FOOTER_Y_FROM_BOTTOM 计算,确保不覆盖底栏页码信息。
|
||||
* - 清空后内容区处于待绘制状态,由调用方继续执行数据项绘制。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
static void YCView_ClearContentArea(void)
|
||||
{
|
||||
uint16_t sx = s_port->get_size_x();
|
||||
uint16_t sy = s_port->get_size_y();
|
||||
uint16_t y0 = YC_CONTENT_BASE_Y - 2u;
|
||||
uint16_t y1 = sy - YC_FOOTER_Y_FROM_BOTTOM;
|
||||
if ((y1 > y0) && (sx > 0u))
|
||||
{
|
||||
s_port->fill_rect(0, y0, sx - 1u, y1, s_port->get_color_back());
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_ApplyCursorInvert
|
||||
* 功能:
|
||||
* 对当前光标所在行进行反显高亮处理。
|
||||
*
|
||||
* 参数:
|
||||
* input - 视图输入结构体,包含页码、光标位置等信息
|
||||
*
|
||||
* 边界处理:
|
||||
* - 若数据为空(input->empty != 0)或没有可显示的行数,直接返回。
|
||||
* - 若计算的反显区域越界,自动调整至有效范围内。
|
||||
* - 若反显上边界大于等于下边界,不执行反显操作。
|
||||
*
|
||||
* 说明:
|
||||
* - 光标行 Y 坐标通过 YCView_RowY(input->cursor_row) 计算。
|
||||
* - 反显区域高度为单行高度(lineH-1),确保覆盖整个字符区域。
|
||||
* - X 方向留白:左侧 YC_ROW_PAD_X0,右侧 sx-1-YC_ROW_PAD_X1,避免触及屏幕边缘。
|
||||
* - 下边界受 YC_FOOTER_Y_FROM_BOTTOM 限制,防止覆盖底栏页码。
|
||||
* - 该函数在绘制页码前调用,避免因页码绘制导致光标高亮消失。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
static void YCView_ApplyCursorInvert(const yc_view_input_t *input)
|
||||
{
|
||||
uint16_t sx = s_port->get_size_x();
|
||||
uint16_t rows = input->rows_on_page;
|
||||
uint16_t lineH = s_port->get_ascii_height() + s_port->get_row_space();
|
||||
uint16_t y0;
|
||||
uint16_t y1;
|
||||
uint16_t yMax;
|
||||
|
||||
if ((input->empty != 0u) || (rows == 0u))
|
||||
{
|
||||
return;
|
||||
}
|
||||
y0 = YCView_RowY((uint8_t)input->cursor_row);
|
||||
y1 = y0 + lineH - 1u;
|
||||
yMax = s_port->get_size_y() - YC_FOOTER_Y_FROM_BOTTOM;
|
||||
if (y1 > yMax)
|
||||
{
|
||||
y1 = yMax;
|
||||
}
|
||||
if (y1 < y0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
s_port->invert(YC_ROW_PAD_X0, y0, sx - 1u - YC_ROW_PAD_X1, y1);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_PaintContent
|
||||
* 功能:
|
||||
* 绘制内容区,包括清空背景、显示遥测数据项、光标高亮和页码信息。
|
||||
*
|
||||
* 参数:
|
||||
* input - 视图输入结构体,包含页面索引、行数据等信息
|
||||
*
|
||||
* 边界处理:
|
||||
* - 若数据为空(input->empty != 0),显示"无遥测数据"提示并返回。
|
||||
* - 跳过无效行(input->row_valid[row] == 0)。
|
||||
* - 循环次数受 input->rows_on_page 和 YC_VIEW_ROWS_MAX 双重限制。
|
||||
*
|
||||
* 说明:
|
||||
* - 绘制流程:
|
||||
* 1) 调用 YCView_ClearContentArea() 清空内容区背景
|
||||
* 2) 若数据为空,显示提示信息并返回
|
||||
* 3) 遍历有效行,逐行调用 YCView_DrawRowNameAndValue() 绘制名称和数值
|
||||
* 4) 先反显光标行(YCView_ApplyCursorInvert),再绘制页码
|
||||
* - 顺序重要:避免页码绘制覆盖光标高亮效果
|
||||
* 5) 最后显示页码信息(YCView_ShowInfoPage)
|
||||
* - 该函数是遥测页面内容绘制的核心入口,被 YCView_DrawFull() 和 YCView_DrawValues() 调用。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
static void YCView_PaintContent(const yc_view_input_t *input)
|
||||
{
|
||||
uint8_t row;
|
||||
uint16_t rows;
|
||||
|
||||
YCView_ClearContentArea();
|
||||
|
||||
if (input->empty != 0u)
|
||||
{
|
||||
s_port->show_str(6u, YC_CONTENT_BASE_Y + 20u, (const uint8_t *)"无遥测数据");
|
||||
return;
|
||||
}
|
||||
|
||||
rows = input->rows_on_page;
|
||||
for (row = 0; row < (uint8_t)rows && row < YC_VIEW_ROWS_MAX; row++)
|
||||
{
|
||||
if (input->row_valid[row] == 0u)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
YCView_DrawRowNameAndValue(input->row_name[row], input->row_value[row], row, 1u);
|
||||
}
|
||||
|
||||
/* 先反显光标,再绘页码,避免 invert 覆盖底栏「第 x 页」造成花屏 */
|
||||
YCView_ApplyCursorInvert(input);
|
||||
YCView_ShowInfoPage(input->page, input->page_max);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_DrawFull
|
||||
* 功能:
|
||||
* 完整绘制遥测页面,包括顶栏和内容区。
|
||||
*
|
||||
* 参数:
|
||||
* view - 视图对象指针(当前未使用)
|
||||
* input - 视图输入结构体,包含顶部名称和行数据等信息
|
||||
*
|
||||
* 边界处理:
|
||||
* - 若 input 或 s_port 为 NULL,直接返回。
|
||||
* - 通过 (void)view 消除未使用参数警告。
|
||||
*
|
||||
* 说明:
|
||||
* - 完整绘制流程:先显示顶栏名称(YCView_ShowTopName),再绘制内容区(YCView_PaintContent)。
|
||||
* - 整屏擦除操作在 MenuPage_OnExit() 统一完成,此处无需重复清屏。
|
||||
* - 该函数用于首次加载页面或需要完整重绘的场景。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
static void YCView_DrawFull(view_t *view, const yc_view_input_t *input)
|
||||
{
|
||||
(void)view;
|
||||
if ((input == NULL) || (s_port == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* 整屏擦除在 MenuPage_OnExit 统一完成,此处直接绘制顶栏与内容 */
|
||||
YCView_ShowTopName(input->top_name);
|
||||
YCView_PaintContent(input);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:YCView_DrawValues
|
||||
* 功能:
|
||||
* 仅重绘内容区数值(不重绘顶栏),用于主循环中的数值刷新。
|
||||
*
|
||||
* 参数:
|
||||
* view - 视图对象指针(当前未使用)
|
||||
* input - 视图输入结构体,包含页面和行数据信息
|
||||
*
|
||||
* 边界处理:
|
||||
* - 若 input 或 s_port 为 NULL,直接返回。
|
||||
* - 通过 (void)view 消除未使用参数警告。
|
||||
*
|
||||
* 说明:
|
||||
* - 该函数是主循环节拍的核心调用点,用于周期性刷新遥测数值显示。
|
||||
* - 仅重绘内容区(YCView_PaintContent),顶栏保持不变以减少绘制开销。
|
||||
* - 在桩模式下,此函数会触发 YCView_FormatStubValue() 生成模拟数据并更新显示。
|
||||
* - 相比 YCView_DrawFull(),此函数更高效,适合高频刷新场景。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
static void YCView_DrawValues(view_t *view, const yc_view_input_t *input)
|
||||
{
|
||||
(void)view;
|
||||
if ((input == NULL) || (s_port == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* 主循环节拍:重绘内容区以更新桩数值(不重画面顶栏) */
|
||||
YCView_PaintContent(input);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 函数名:View_Init
|
||||
* 功能:
|
||||
* 初始化遥测页面视图,绑定渲染端口和回调函数。
|
||||
*
|
||||
* 参数:
|
||||
* view - 视图对象指针,待初始化的视图结构体
|
||||
*
|
||||
* 边界处理:
|
||||
* - 本函数不对 view 做空指针校验,调用方需保证 view 有效。
|
||||
*
|
||||
* 说明:
|
||||
* - 初始化流程:
|
||||
* 1) 获取 LCD 渲染端口(s_port = PageRenderer_Lcd())
|
||||
* 2) 设置 show_top_name 为 NULL,表示不使用自定义顶栏显示函数
|
||||
* 3) 绑定 show_info_page 回调到 YCView_ShowInfoPage
|
||||
* 4) 绑定 draw_full 回调到 YCView_DrawFull(完整绘制入口)
|
||||
* 5) 绑定 draw_values 回调到 YCView_DrawValues(数值刷新入口)
|
||||
* - 初始化后,视图对象即可被页面管理器使用。
|
||||
*
|
||||
* 返回值:
|
||||
* - 无
|
||||
* ------------------------------------------------------------------------- */
|
||||
void View_Init(view_t *view)
|
||||
{
|
||||
s_port = PageRenderer_Lcd();
|
||||
view->show_top_name = YCView_ShowTopName;
|
||||
view->show_top_name = NULL;
|
||||
view->show_info_page = YCView_ShowInfoPage;
|
||||
}
|
||||
view->draw_full = YCView_DrawFull;
|
||||
view->draw_values = YCView_DrawValues;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user