/* ui/home/home.c — 主页(ACT_HOME)view + 控制器(批次③ 目录嵌套后)。 * * 负责 home 控件(TAP ME / 6 通知行 / CANCEL LAST / FULLSCREEN / WIDGETS DEMO)+ 手绘(非注册表 * 路径,batch① 仅 demo 迁注册表,home 保持命令式 draw+flush)+ 命中分发 + 业务监听(logic 推送)。 * UI→业务只经 logic_taps_bump()/notif_send()/notif_cancel();业务变化经 logic_set_listener 回调 * home_state_listener 刷新(契约 ①②)。导航到 demo/full 经 meow_view_page_push(单一入口)。 */ #include "hello_internal.h" #include #include static home_ctrl g_home_ctrl; /* ---- home 既有控件 ---- */ static meow_widget *g_btn; static meow_widget *g_nbtn[6]; /* 通知触发按钮行 */ static meow_widget *g_cancel; /* 取消最近一条通知 */ static meow_widget *g_fs_btn; /* FULLSCREEN 进入按钮(主界面) */ static meow_widget *g_demo_btn; /* 「控件库 Demo」入口按钮(主界面) */ static const char *g_notif_labels[6] = { "INFO", "MEDIA", "HIGH", "PROG", "ONGO", "TGT" }; static char g_btn_label[32] = "TAP ME"; void home_redraw(void) { const meow_theme *th = meow_theme_get(); int sb = meow_ui_statusbar_height(); if (sb > 0) meow_ui_fill_rect(0, sb, 480, 720 - sb, th->bg); else meow_ui_clear(th->bg); meow_ui_text_center(240, sb + 8, "MEOWOS HELLO", 28, th->fg); meow_ui_text_center(240, sb + 38, "SDK: meow_ui.a", 20, th->dim); meow_widget_draw(g_btn); meow_ui_text_center(240, 372, "tap = send notification (see log)", 20, th->dim); for (int i = 0; i < 6; i++) meow_widget_draw(g_nbtn[i]); meow_widget_draw(g_cancel); meow_widget_draw(g_fs_btn); meow_widget_draw(g_demo_btn); char line[64]; snprintf(line, sizeof line, "taps=%d uptime=%ds", logic_taps_get(), logic_secs_get()); meow_ui_text_center(240, 516, line, 20, th->dim); meow_ui_text(20, 660, "left-swipe = exit", 20, th->dim); meow_ui_flush(); } /* 业务→UI 监听器:taps 变化 → 重建按钮 label;secs 变化 → 重绘(仅本页在前台时,否则只改业务 * 不覆写全屏帧——例如全屏态下 logic_secs_add 仍触发,但本页 active=0 跳过 redraw)。 */ static void home_state_listener(int ev, void *ctx) { home_ctrl *c = (home_ctrl *)ctx; if (ev == LOGIC_EV_TAPS) { char lb[32]; snprintf(lb, sizeof lb, "TAPPED x%d", logic_taps_get()); meow_widget_free(g_btn); g_btn = meow_btn_create(120, 300, 240, 64, lb); } if (!c->active) return; /* 本页不在前台(全屏):不覆写当前帧 */ home_redraw(); } int home_on_tap(int x, int y) { if (meow_widget_hit(g_demo_btn, x, y)) { meow_view_page_push(ACT_DEMO); return 1; } for (int i = 0; i < 6; i++) { if (meow_widget_hit(g_nbtn[i], x, y)) { notif_send(i); home_redraw(); return 1; } } if (meow_widget_hit(g_cancel, x, y)) { notif_cancel(); home_redraw(); return 1; } if (meow_widget_hit(g_fs_btn, x, y)) { meow_view_page_push(ACT_FULL); return 1; } if (meow_widget_hit(g_btn, x, y)) { logic_taps_bump(); return 1; } return 0; } static void home_page_create(meow_view *v, void *ctx) { (void)v; ((home_ctrl *)ctx)->view = v; g_btn = meow_btn_create(120, 300, 240, 64, g_btn_label); for (int i = 0; i < 6; i++) g_nbtn[i] = meow_btn_create(3 + i * 80, 400, 74, 56, g_notif_labels[i]); g_cancel = meow_btn_create(36, 464, 200, 42, "CANCEL LAST"); g_fs_btn = meow_btn_create(244, 464, 200, 42, "FULLSCREEN"); g_demo_btn = meow_btn_create(36, 560, 408, 44, "WIDGETS DEMO"); /* 注册业务→UI 推送监听器(biz-UI 绑定点 = 本页控制器 ctx)。 */ logic_set_listener(home_state_listener, ctx); } static void home_page_enter(meow_view *v, void *ctx) { (void)v; ((home_ctrl *)ctx)->active = 1; hello_nav_report(); /* ① 上报 home 栈深/顶层(pop 回 home / 首次进入) */ home_redraw(); } static void home_page_leave(meow_view *v, void *ctx) { (void)v; ((home_ctrl *)ctx)->active = 0; /* 默认不销毁子控件;弹回时 on_enter 重绘恢复 */ } static void home_page_destroy(meow_view *v, void *ctx) { (void)v; (void)ctx; meow_widget_free(g_demo_btn); for (int i = 0; i < 6; i++) meow_widget_free(g_nbtn[i]); meow_widget_free(g_cancel); meow_widget_free(g_fs_btn); meow_widget_free(g_btn); g_btn = g_cancel = g_fs_btn = g_demo_btn = NULL; for (int i = 0; i < 6; i++) g_nbtn[i] = NULL; } meow_view *home_view_create(void) { static const meow_view_hooks h = { .on_create = home_page_create, .on_enter = home_page_enter, .on_leave = home_page_leave, .on_destroy = home_page_destroy, }; return meow_view_create(ACT_HOME, MEOW_VIEW_ACTIVITY, &h, &g_home_ctrl); }