feat(ui): show real weekday/day/month on HOME screen instead of placeholder
UI_ShowClockPage()/UI_ShowSetTimePage() now take weekday/day/month(/year) and build the date bar dynamically via Build_DateString() instead of the fixed placeholder string. app_home.c reads the full date from RTC via PCF8563_ReadDateTime() and recalculates weekday since the RTC's stored date may differ from the software clock's. config.h exposes current_day/month/year/weekday alongside the existing time fields so main.c's debug commands don't need a separate include.
This commit is contained in:
125
App/ui.c
125
App/ui.c
@@ -7,19 +7,77 @@
|
||||
// 引入外部主菜单对码项名称的字符串 ID 表 (例如门磁/PIR/烟感等防区类型)
|
||||
extern const StringID device_menu_ids[5];
|
||||
|
||||
// 底部日期栏固定用 8x16 小字体、LCD_ShowStringCentered 居中绘制在 y=195;
|
||||
// 编辑日期时对 日/月/年 做局部刷新需要精确知道每个字段的像素 X 坐标,这里按
|
||||
// LCD_ShowStringCentered 的居中公式 (LCD_WIDTH - 字符数*8) / 2 手工算好,
|
||||
// 前提是字符串格式固定为 "WWW DD-MM-YY" (12 个字符),不能随意改动格式。
|
||||
#define DATE_BAR_Y 195
|
||||
#define DATE_BAR_START_X 19 // (135 - 12*8) / 2 = 19
|
||||
#define DATE_BAR_DAY_X (DATE_BAR_START_X + 4 * 8) // 第 4 个字符起 = 51
|
||||
#define DATE_BAR_MONTH_X (DATE_BAR_START_X + 7 * 8) // 第 7 个字符起 = 75
|
||||
#define DATE_BAR_YEAR_X (DATE_BAR_START_X + 10 * 8) // 第 10 个字符起 = 99
|
||||
#define DATE_BAR_FIELD_W 16 // 2 位数字,8px/字符
|
||||
|
||||
/**
|
||||
* @brief 拼出"星期缩写 日-月"格式的日期字符串 (如 "VEN 10-07"),供 HOME 页时钟显示
|
||||
* @param out 输出缓冲区,调用方需保证至少 10 字节 (3字母+空格+2位+'-'+2位+'\0')
|
||||
*/
|
||||
static void Build_DateString(char *out, u8 weekday, u8 day, u8 month)
|
||||
{
|
||||
char *wd = Lang_Get((StringID)(STR_WEEKDAY_SUN + weekday));
|
||||
u8 i = 0;
|
||||
while (*wd) {
|
||||
out[i++] = *wd++;
|
||||
}
|
||||
out[i++] = ' ';
|
||||
out[i++] = '0' + (day / 10);
|
||||
out[i++] = '0' + (day % 10);
|
||||
out[i++] = '-';
|
||||
out[i++] = '0' + (month / 10);
|
||||
out[i++] = '0' + (month % 10);
|
||||
out[i] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 拼出"星期缩写 日-月-年"格式的日期字符串 (如 "VEN 10-07-25"),供时间设置页编辑日期时显示
|
||||
* @param out 输出缓冲区,调用方需保证至少 13 字节 (3字母+空格+2位+'-'+2位+'-'+2位+'\0')
|
||||
*/
|
||||
static void Build_DateStringWithYear(char *out, u8 weekday, u8 day, u8 month, u8 year)
|
||||
{
|
||||
char *wd = Lang_Get((StringID)(STR_WEEKDAY_SUN + weekday));
|
||||
u8 i = 0;
|
||||
while (*wd) {
|
||||
out[i++] = *wd++;
|
||||
}
|
||||
out[i++] = ' ';
|
||||
out[i++] = '0' + (day / 10);
|
||||
out[i++] = '0' + (day % 10);
|
||||
out[i++] = '-';
|
||||
out[i++] = '0' + (month / 10);
|
||||
out[i++] = '0' + (month % 10);
|
||||
out[i++] = '-';
|
||||
out[i++] = '0' + (year / 10);
|
||||
out[i++] = '0' + (year % 10);
|
||||
out[i] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 渲染并显示系统待机时钟主页面
|
||||
* @param state 当前的系统布防状态 (STATE_ARMED: 已布防, 否则为正常或撤防)
|
||||
* @param hour 当前待显示的小时数 (0~23)
|
||||
* @param min 当前待显示的分钟数 (0~59)
|
||||
* @param weekday 当前星期 (0=周日, ..., 6=周六)
|
||||
* @param day 当前日 (1~31)
|
||||
* @param month 当前月 (1~12)
|
||||
* @details 该页面被划分为三大功能视觉区:
|
||||
* 1. 顶部状态栏:左侧绘制布撤防指示锁,右侧显示真实剩余电量百分比以及电池单色位图。
|
||||
* 2. 中部核心栏:垂直居中以 16x32 大号粗字体绘制格式化时间 "HH:MM",在其下方标注 AM/PM 标识。
|
||||
* 3. 底部信息栏:使用灰色小字模绘制法语星期日期 "VEN 10-07" (星期五 7月10日)。
|
||||
* 3. 底部信息栏:使用灰色小字模绘制真实星期日期 "VEN 10-07" (星期五 7月10日)。
|
||||
*/
|
||||
void UI_ShowClockPage(SystemState state, u8 hour, u8 min)
|
||||
void UI_ShowClockPage(SystemState state, u8 hour, u8 min, u8 weekday, u8 day, u8 month)
|
||||
{
|
||||
char time_str[6];
|
||||
char date_str[10];
|
||||
char batt_str[7];
|
||||
u8 batt;
|
||||
|
||||
@@ -74,8 +132,9 @@ void UI_ShowClockPage(SystemState state, u8 hour, u8 min)
|
||||
// ====== 绘制 AM/PM 状态 ======
|
||||
LCD_ShowStringCentered(150, Lang_Get(STR_CLOCK_AMPM), COLOR_WHITE, COLOR_BLACK);
|
||||
|
||||
// ====== 绘制日期星期栏 ======
|
||||
LCD_ShowStringCentered(195, Lang_Get(STR_CLOCK_DATE), COLOR_GRAY, COLOR_BLACK);
|
||||
// ====== 绘制日期星期栏 (真实日期,不再是写死的占位文案) ======
|
||||
Build_DateString(date_str, weekday, day, month);
|
||||
LCD_ShowStringCentered(DATE_BAR_Y, date_str, COLOR_GRAY, COLOR_BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,10 +423,14 @@ void UI_ShowMainMenu(u8 selected_index)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 渲染修改时间闪烁调节页面 (调节小时或分钟)
|
||||
* @brief 渲染修改时间/日期闪烁调节页面
|
||||
* @param hour 修改状态中的小时
|
||||
* @param min 修改状态中的分钟
|
||||
* @param selection 当前正在编辑聚焦的属性位 (1: 修改小时, 2: 修改分钟)
|
||||
* @param day 修改状态中的日
|
||||
* @param month 修改状态中的月
|
||||
* @param year 修改状态中的年 (0~99,代表 2000~2099)
|
||||
* @param weekday 根据当前日期算出的星期 (0=周日, ..., 6=周六)
|
||||
* @param selection 当前正在编辑聚焦的属性位 (1:小时, 2:分钟, 3:日, 4:月, 5:年)
|
||||
* @param blink_on 当前 500ms 控制隐现的闪烁周期标志位 (1-绘制正常字,0-以空格消隐该数值字符)
|
||||
*/
|
||||
// 小时/分钟数字在屏幕上的固定坐标 (16x32 字体,两位数字宽度为 32px)
|
||||
@@ -377,9 +440,10 @@ void UI_ShowMainMenu(u8 selected_index)
|
||||
#define SET_TIME_HOUR_X 23
|
||||
#define SET_TIME_MIN_X 75
|
||||
|
||||
void UI_ShowSetTimePage(u8 hour, u8 min, u8 selection, u8 blink_on)
|
||||
void UI_ShowSetTimePage(u8 hour, u8 min, u8 day, u8 month, u8 year, u8 weekday, u8 selection, u8 blink_on)
|
||||
{
|
||||
char time_str[6];
|
||||
char date_str[13];
|
||||
LCD_Clear(COLOR_BLACK);
|
||||
|
||||
// 绘制绿锁头等背景静态信息
|
||||
@@ -392,7 +456,7 @@ void UI_ShowSetTimePage(u8 hour, u8 min, u8 selection, u8 blink_on)
|
||||
LCD_ShowString(77, 24, "85%", COLOR_GRAY, COLOR_BLACK);
|
||||
LCD_DrawMonoBitmap(107, 27, 20, 10, bmp_battery_20x10, COLOR_GRAY, COLOR_BLACK);
|
||||
|
||||
// 整页绘制时,小时/分钟数字一律完整显示 (消隐闪烁效果交给 UI_UpdateSetTimeDigit 局部刷新处理)
|
||||
// 整页绘制时,各数字一律完整显示 (消隐闪烁效果交给 UI_UpdateSetTimeDigit 局部刷新处理)
|
||||
time_str[0] = '0' + (hour / 10);
|
||||
time_str[1] = '0' + (hour % 10);
|
||||
time_str[2] = '\0';
|
||||
@@ -408,30 +472,49 @@ void UI_ShowSetTimePage(u8 hour, u8 min, u8 selection, u8 blink_on)
|
||||
|
||||
// 补齐底部的固定辅助元素
|
||||
LCD_ShowStringCentered(150, Lang_Get(STR_CLOCK_AMPM), COLOR_WHITE, COLOR_BLACK);
|
||||
LCD_ShowStringCentered(195, Lang_Get(STR_CLOCK_DATE), COLOR_GRAY, COLOR_BLACK);
|
||||
|
||||
// 编辑日期时,日期栏额外带上年份 ("WWW DD-MM-YY"),方便看清正在改的年份数值
|
||||
Build_DateStringWithYear(date_str, weekday, day, month, year);
|
||||
LCD_ShowStringCentered(DATE_BAR_Y, date_str, COLOR_GRAY, COLOR_BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 局部刷新时间设置界面里"正在调节的那一个"数字 (小时或分钟)
|
||||
* @param selection 1:刷新小时区域, 2:刷新分钟区域
|
||||
* @brief 局部刷新时间设置界面里"正在调节的那一个"字段 (小时/分钟/日/月/年)
|
||||
* @param selection 1:小时, 2:分钟, 3:日, 4:月, 5:年
|
||||
* @param blink_on 1:显示数值, 0:消隐(涂黑),用于 500ms 周期闪烁效果
|
||||
* @details 只重画 32x32px 的数字区域,不触碰锁头/电池/冒号/AM-PM/日期等其它内容,
|
||||
* @details 小时/分钟用 32x32px 大字体区域;日/月/年用日期栏里对应的 16x16px 小字体区域,
|
||||
* 都只重画自己那一小块,不触碰锁头/电池/冒号/AM-PM/星期文字等其它内容,
|
||||
* 避免每次闪烁或调值都整屏 LCD_Clear() 造成全屏闪烁。
|
||||
*/
|
||||
void UI_UpdateSetTimeDigit(u8 hour, u8 min, u8 selection, u8 blink_on)
|
||||
void UI_UpdateSetTimeDigit(u8 hour, u8 min, u8 day, u8 month, u8 year, u8 selection, u8 blink_on)
|
||||
{
|
||||
char time_str[3];
|
||||
u16 x = (selection == 1) ? SET_TIME_HOUR_X : SET_TIME_MIN_X;
|
||||
u8 value = (selection == 1) ? hour : min;
|
||||
char buf[3];
|
||||
u16 x;
|
||||
u16 y;
|
||||
u16 w;
|
||||
u16 h;
|
||||
u8 value;
|
||||
|
||||
switch (selection) {
|
||||
case 1: x = SET_TIME_HOUR_X; y = SET_TIME_DIGIT_Y; w = SET_TIME_DIGIT_W; h = SET_TIME_DIGIT_H; value = hour; break;
|
||||
case 2: x = SET_TIME_MIN_X; y = SET_TIME_DIGIT_Y; w = SET_TIME_DIGIT_W; h = SET_TIME_DIGIT_H; value = min; break;
|
||||
case 3: x = DATE_BAR_DAY_X; y = DATE_BAR_Y; w = DATE_BAR_FIELD_W; h = 16; value = day; break;
|
||||
case 4: x = DATE_BAR_MONTH_X; y = DATE_BAR_Y; w = DATE_BAR_FIELD_W; h = 16; value = month; break;
|
||||
default: x = DATE_BAR_YEAR_X; y = DATE_BAR_Y; w = DATE_BAR_FIELD_W; h = 16; value = year; break;
|
||||
}
|
||||
|
||||
if (!blink_on) {
|
||||
// 灭周期:直接把这一小块涂黑,形成消隐效果
|
||||
LCD_FillRect(x, SET_TIME_DIGIT_Y, SET_TIME_DIGIT_W, SET_TIME_DIGIT_H, COLOR_BLACK);
|
||||
LCD_FillRect(x, y, w, h, COLOR_BLACK);
|
||||
return;
|
||||
}
|
||||
|
||||
time_str[0] = '0' + (value / 10);
|
||||
time_str[1] = '0' + (value % 10);
|
||||
time_str[2] = '\0';
|
||||
LCD_ShowString16x32(x, SET_TIME_DIGIT_Y, time_str, COLOR_CYAN, COLOR_BLACK);
|
||||
buf[0] = '0' + (value / 10);
|
||||
buf[1] = '0' + (value % 10);
|
||||
buf[2] = '\0';
|
||||
if (selection <= 2) {
|
||||
LCD_ShowString16x32(x, y, buf, COLOR_CYAN, COLOR_BLACK);
|
||||
} else {
|
||||
LCD_ShowString(x, y, buf, COLOR_GRAY, COLOR_BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user