#include "app_manager.h" #include "clock.h" #include "xtell.h" #include "ui.h" #include "rgb.h" #include "event.h" #include "system.h" #include "../Drivers/rf.h" #include "../Drivers/lcd.h" // 外部引用的全局系统状态变量 extern SystemState current_state; extern volatile u16 ms_tick; // 待机时钟应用内特有的编辑时间私有变量 static u8 time_edit_active = 0; // 标识当前是否正在编辑修改时间中 (1:是, 0:否) static u8 time_edit_field = 1; // 标识当前聚焦在哪一个参数上进行微调 (1:修改小时, 2:修改分钟) static u8 time_edit_blink_on = 1; // 时钟修改时光标闪烁周期状态位 // 声明本应用的生命周期回调函数 static void ClockApp_OnStart(void); static void ClockApp_onRun(void); static void ClockApp_onClose(void); static EventResult ClockApp_onEvent(SystemEvent *evt); // 实体化定义待机时钟应用控制块 WristbandApp clock_app = { APP_ID_CLOCK, "Clock", ClockApp_OnStart, ClockApp_onRun, ClockApp_onClose, ClockApp_onEvent }; /** * @brief 触发启动时间设置状态机,准备修改时钟 */ void Start_Time_Edit(void) { time_edit_active = 1; time_edit_field = 1; time_edit_blink_on = 1; current_state = STATE_SET_TIME; // 系统切入时间设置状态 // FCOB 幻彩灯条双灯珠均显示蓝色常亮 (R=0, G=0, B=180),进行模式视觉区分 RGB_Send(0, 0, 180, 0, 0, 180); // 振动马达单次短震 50 毫秒,提供触觉反馈 MOTOR = 1; Delay_ms(50); MOTOR = 0; // 渲染显示时间编辑界面,默认高亮编辑小时字段,消隐位开启 UI_ShowSetTimePage(current_hour, current_min, time_edit_field, 1); XTELL_LOG("[ClockApp] Time edit started.\r\n"); } /** * @brief ClockApp 启动回调 */ static void ClockApp_OnStart(void) { time_edit_active = 0; current_state = STATE_NORMAL; // 系统切入正常待机状态 RF_SetMode(1); // 开启天线并置为接收模式,监听无线探测器 UI_ShowClockPage(current_state, current_hour, current_min); // 渲染时钟主页 // 关断/熄灭 FCOB 双灯条 RGB_Send(0, 0, 0, 0, 0, 0); XTELL_LOG("[ClockApp] Started\r\n"); } /** * @brief ClockApp 轮询主回调 */ static void ClockApp_onRun(void) { if (time_edit_active) { // ====== 时间设置闪烁动画 (周期 500ms) ====== u8 blink = (ms_tick / 500) % 2; if (blink != time_edit_blink_on) { time_edit_blink_on = blink; // 每次闪烁状态发生变化,重新刷写屏幕数值 UI_ShowSetTimePage(current_hour, current_min, time_edit_field, time_edit_blink_on); } } else { // 软时钟发生分钟改变,需要通知屏幕重画时钟主页 if (clock_updated) { clock_updated = 0; UI_ShowClockPage(current_state, current_hour, current_min); } } } /** * @brief ClockApp 退出清理回调 */ static void ClockApp_onClose(void) { time_edit_active = 0; RGB_Send(0, 0, 0, 0, 0, 0); // 关闭灯条 XTELL_LOG("[ClockApp] Closed\r\n"); } /** * @brief ClockApp 接收事件处理回调 (按键导航与布撤防交互) */ static EventResult ClockApp_onEvent(SystemEvent *evt) { if (time_edit_active) { // ====== 处于时间设置状态下的按键拦截处理机 ====== if (evt->key_event == KEY_EVENT_UP_CLICK) { // 短按 ▲ 键增加数值 (小时/分钟循环相加) if (time_edit_field == 1) { current_hour = (current_hour + 1) % 24; } else { current_min = (current_min + 1) % 60; } UI_ShowSetTimePage(current_hour, current_min, time_edit_field, 1); return EVENT_HANDLED; // 吞掉并消化事件 } if (evt->key_event == KEY_EVENT_DOWN_CLICK) { // 短按 ▼ 键减小数值 if (time_edit_field == 1) { current_hour = (current_hour == 0) ? 23 : (current_hour - 1); } else { current_min = (current_min == 0) ? 59 : (current_min - 1); } UI_ShowSetTimePage(current_hour, current_min, time_edit_field, 1); return EVENT_HANDLED; } if (evt->key_event == KEY_EVENT_CONFIRM_LONG) { // 长按 ■ 确认键切换调节字段 (在修改小时与修改分钟间跳转) if (time_edit_field == 1) { time_edit_field = 2; } else { time_edit_field = 1; } UI_ShowSetTimePage(current_hour, current_min, time_edit_field, 1); return EVENT_HANDLED; } if (evt->key_event == KEY_EVENT_CONFIRM_CLICK) { // 短按 ■ 确认键保存最新时钟配置并退出编辑模式 time_edit_active = 0; current_state = STATE_NORMAL; RGB_Send(0, 0, 0, 0, 0, 0); // 熄灭蓝色指示灯 // 退出短振反馈 MOTOR = 1; Delay_ms(50); MOTOR = 0; UI_ShowClockPage(current_state, current_hour, current_min); return EVENT_HANDLED; } return EVENT_HANDLED; // 在时间设置模式下屏蔽拦截其他一切无关按键事件 } // ====== 正常时钟待机状态下的按键拦截处理 ====== // 1. 长按 ■ 确认键,打开设置主菜单 MenuApp if (evt->key_event == KEY_EVENT_CONFIRM_LONG) { AppManager_SwitchToForeground(&menu_app); return EVENT_HANDLED; } // 2. 长按 ▲ 键,一键切换系统的 布防 (ARMED) 和 撤防 (DISARMED) 状态 if (evt->key_event == KEY_EVENT_UP_LONG) { if (current_state == STATE_ARMED) { current_state = STATE_DISARMED; } else { current_state = STATE_ARMED; } // 布撤防状态切换成功后进行 100ms 短震确认,并重新刷写时钟待机页 MOTOR = 1; Delay_ms(100); MOTOR = 0; UI_ShowClockPage(current_state, current_hour, current_min); return EVENT_HANDLED; } return EVENT_IGNORED; // 其他未被关心的事件交由后台应用或丢弃 }