From d1a3cce7f16c6c0f22a7f23a0042da65fcc36364 Mon Sep 17 00:00:00 2001 From: MeowOS Date: Mon, 31 Aug 2026 03:31:09 +0800 Subject: [PATCH] =?UTF-8?q?refactor(hello):=20=E8=A7=86=E5=9B=BE=E6=A1=86?= =?UTF-8?q?=E6=9E=B6=E6=89=B9=E6=AC=A1=E2=91=A1=20=E2=80=94=20hello.c=20?= =?UTF-8?q?=E6=8B=86=E5=88=86=E4=B8=BA=20app.c+ui/{home,full,demo}.c+ui/co?= =?UTF-8?q?mmon/chrome.c+logic/{notify,state}.c=EF=BC=88=E5=AE=9A=E6=A1=88?= =?UTF-8?q?B:=20demo=E8=A7=86=E5=9B=BE=E6=80=81=E7=95=99ui/=EF=BC=9B?= =?UTF-8?q?=E5=AE=9A=E6=A1=88b:=20page=E5=AF=BC=E8=88=AA=E5=8C=85=E8=A3=85?= =?UTF-8?q?activity=E6=A0=88=EF=BC=89=EF=BC=9Btest=5Fp1p2p3=5Frepro=20?= =?UTF-8?q?=E6=94=B9=E5=A4=9A=E6=96=87=E4=BB=B6=E9=93=BE=E6=8E=A5=E5=BD=A2?= =?UTF-8?q?=E6=80=81=20(agent-177)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hello f45ba051→c06b3b4f; mipsel -Wall -Wextra 0 warning; 宿主 P1c/P2/P3+widgets 全 PASS 出入(诚实): view on_draw/on_event 路径暂未启用(注册表直绘已覆盖, on_draw 双画风险), 留批③实测; home/full 仍手绘未迁注册表 --- app.c | 115 ++++++++++++ build_hello.sh | 9 +- hello | Bin 270412 -> 273788 bytes hello_internal.h | 102 ++++++++++ logic/logic.h | 30 +++ logic/notify.c | 56 ++++++ logic/state.c | 38 ++++ ui/common/chrome.c | 36 ++++ hello.c => ui/demo.c | 429 +++++++++---------------------------------- ui/full.c | 56 ++++++ ui/home.c | 119 ++++++++++++ 11 files changed, 646 insertions(+), 344 deletions(-) create mode 100644 app.c create mode 100644 hello_internal.h create mode 100644 logic/logic.h create mode 100644 logic/notify.c create mode 100644 logic/state.c create mode 100644 ui/common/chrome.c rename hello.c => ui/demo.c (52%) create mode 100644 ui/full.c create mode 100644 ui/home.c diff --git a/app.c b/app.c new file mode 100644 index 0000000..241e835 --- /dev/null +++ b/app.c @@ -0,0 +1,115 @@ +/* app.c — hello 应用装配层:main + 组装 + 事件分发。 + * + * 职责(SDK_VIEW_FRAMEWORK_DESIGN.md §B.2):main 只做初始化/建页/跑事件循环/清理;把 + * meow_ui_run 的平铺输入回调(key/tap/swipe/tick/touch)路由到当前活动页(home/full/demo)。 + * 页面切换统一走 meow_view_page_push/pop(活动栈 + on_enter/on_leave 的唯一驱动,App 不再 + * 分别调 activity_push/pop)。业务变化经 logic 监听器送回 UI(见 ui/home.c)。 + * + * 契约(MEOW_APP_SDK.md §1/§3/§6):应用只调 meow_ui API。 + */ +#include "hello_internal.h" +#include + +/* Dialog / BottomSheet(阻塞模态;非控件,main() 创建一次,demo 页打开/关) */ +meow_dialog *g_dlg; +meow_sheet *g_sheet; + +static meow_view *g_home_view; +static meow_view *g_full_view; +static meow_view *g_demo_view; + +static void on_sigterm(int s) { (void)s; meow_ui_request_exit(); } + +/* ============================================================ */ +/* 事件分发:meow_ui_run 平铺回调 → 当前页 */ +/* ============================================================ */ + +static void app_on_key(int keycode, int is_down) +{ + (void)keycode; (void)is_down; + meow_log(MEOW_LOG_DEBUG, "key"); +} + +static void app_on_tap(int x, int y) +{ + if (demo_is_active()) { demo_on_tap(x, y); return; } + if (full_is_active()) { meow_view_page_pop(); return; } /* 全屏:点任意处回 home */ + home_on_tap(x, y); +} + +static void app_on_swipe(int dir, int dx, int dy) +{ + (void)dy; + if (demo_is_active()) { demo_swipe(dir, dx); return; } + if (dir == MEOW_SWIPE_LEFT) { + if (full_is_active()) { meow_view_page_pop(); } + else { meow_log(MEOW_LOG_INFO, "exit:swipe"); meow_ui_request_exit(); } + } +} + +/* M2.71-bug2/6:拖动过程回调(只对 demo 页有意义;home/全屏不拖拽)。 */ +static void app_on_touch_down(int x, int y) +{ + if (demo_is_active()) demo_touch_down(x, y); +} +static void app_on_touch_move(int x, int y) +{ + if (demo_is_active()) demo_touch_move(x, y); +} + +static void app_on_swipe_progress(int x_start, int dx) +{ + meow_ui_swipe_hint(x_start + dx); +} + +static void app_on_tick(void) +{ + uint64_t now = meow_ui_time_ms(); + if (demo_is_active()) { demo_tick(now); return; } + static uint64_t last = 0; /* home/全屏计时:1s 一跳(demo 不计数,同旧) */ + if (now - last >= 1000) { last = now; logic_secs_add(1); } +} + +/* ============================================================ */ +/* main */ +/* ============================================================ */ +int main(void) +{ + meow_log(MEOW_LOG_INFO, "start"); + meow_ui_opts o = { 480, 720 }; + if (meow_ui_init(&o) != 0) { meow_log(MEOW_LOG_ERROR, "init failed"); return 1; } + meow_theme_add_listener(NULL); + + signal(SIGTERM, on_sigterm); + + /* Dialog / BottomSheet 实例(阻塞模态;打开前排空残留触摸由 SDK 处理) */ + g_dlg = meow_dialog_create(MEOW_DLG_SELECT, "Pick a fruit"); + const char *items[] = { "Apple", "Banana", "Cherry" }; + meow_dialog_set_items(g_dlg, items, 3, 1); + g_sheet = meow_sheet_create("Options", 0); + meow_sheet_add_item(g_sheet, "Copy"); + meow_sheet_add_item(g_sheet, "Delete"); + meow_sheet_add_item(g_sheet, "Share"); + + /* 建三页 view(on_create 建各自控件/状态)+ 弹层实例 */ + g_home_view = home_view_create(); + g_full_view = full_view_create(); + g_demo_view = demo_view_create(); + + /* 进入根页(activity_push + home on_enter → home_redraw) */ + meow_view_page_push(ACT_HOME); + + meow_ui_events ev = { app_on_key, app_on_tap, app_on_swipe, app_on_tick, app_on_swipe_progress, + app_on_touch_down, app_on_touch_move }; + meow_ui_run(&ev); + + /* 清理:meow_view_free 触发各页 on_destroy(home 控件 / demo 内容+chrome) */ + meow_view_free(g_full_view); + meow_view_free(g_demo_view); + meow_view_free(g_home_view); + meow_dialog_free(g_dlg); + meow_sheet_free(g_sheet); + meow_ui_shutdown(); + meow_log(MEOW_LOG_INFO, "exit"); + return 0; +} diff --git a/build_hello.sh b/build_hello.sh index 860ce79..908e32a 100755 --- a/build_hello.sh +++ b/build_hello.sh @@ -1,11 +1,16 @@ #!/bin/bash -# Build the hello app (SDK B1 版): 链 meow_ui.a(已内含 meow_font.o), +# Build the hello app (SDK B1, 视图框架批次②文件拆分): 链 meow_ui.a(已内含 meow_font.o), # 额外链系统 libz.a(meow_font 的 inflate 依赖)+ -lpthread。静态 MIPS32r2 (musl sf)。 +# 批次②:hello.c 拆为多文件(app.c + ui/home.c + ui/full.c + ui/demo.c + ui/common/chrome.c + +# logic/notify.c + logic/state.c),仅改列文件,编译期不改 SDK(patch_v2/sdk/ 零触及)。 +# mipsel -Wall -Wextra 0 warning。 set -e cd "$(dirname "$0")" ROOT="$HOME/Project/R3ProII" CC="$ROOT/.tools/zig-mipsel-cc" SYSROOT="$ROOT/.tools/mipsel-linux-muslsf-cross/mipsel-linux-muslsf" -"$CC" -Os -static -I../sdk hello.c ../sdk/meow_ui.a "$SYSROOT/lib/libz.a" -lpthread -o hello +"$CC" -Os -static -Wall -Wextra -I../sdk -I. \ + app.c ui/home.c ui/full.c ui/demo.c ui/common/chrome.c logic/notify.c logic/state.c \ + ../sdk/meow_ui.a "$SYSROOT/lib/libz.a" -lpthread -o hello ls -la hello file hello diff --git a/hello b/hello index 9aa889be0fb56bd2a80c6d79489193812db5cd0a..b0519504835c35d1bcb1eb48c134f8ffa8bc0147 100755 GIT binary patch delta 79835 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 delta 78402 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 +#include "meow_ui.h" +#include "meow_ui_view.h" +#include "logic/logic.h" + +/* ---- App 级弹层(app.c 创建;demo 页打开/关)---- */ +extern meow_dialog *g_dlg; /* Dialog(阻塞模态;main 创建一次) */ +extern meow_sheet *g_sheet; /* BottomSheet(阻塞模态;main 创建一次) */ + +/* ---- Activity 归属(§6.1 ①)---- */ +#define ACT_HOME 0 +#define ACT_FULL 1 +#define ACT_DEMO 2 + +/* ---- SDK 控件不透明:App 自记几何,用于局部 flush / 命中 / scroll 重建 ---- */ +typedef struct { int x, y, w, h; } rect_t; +#define RX(x,y,w,h) ((rect_t){ (x), (y), (w), (h) }) + +/* ---- 视图控制器(ctx = biz-UI 绑定点)---- + * 本批控制器为薄壳:持 meow_view 回指针;页面细粒度视图态(g_ds/g_drag_* /scroll 等)留在各页 + * 模块作用域全局(设计定案 B:demo 视图态不迁 logic)。控制器未来可吸收这些状态。 */ +typedef struct { + meow_view *view; + int active; /* 是否有页进入(与模块 active 全局同步) */ + int _pad; +} home_ctrl; +typedef struct { + meow_view *view; + int active; + int _pad; +} full_ctrl; +typedef struct { + meow_view *view; + int active; /* = g_demo */ + int focus; /* = g_demo_focus */ + int scroll; /* = g_demo_scroll */ + int _pad; +} demo_ctrl; + +/* ---- home 页(ui/home.c)---- */ +meow_view *home_view_create(void); /* 建 home view;on_create 建 home 控件 + 注册业务监听器 */ +int home_on_tap(int x, int y);/* home 态命中分发:返回 1=已消费(含导航到 demo/full) */ + +/* ---- full 页(ui/full.c)---- */ +meow_view *full_view_create(void); /* 建 full view(无控件;全屏文本由 full_draw 手绘) */ +int full_is_active(void); /* 1=处于全屏态 */ +void full_draw(void); /* 画全屏帧(clear accent + 文本 + flush) */ + +/* ---- demo 页(ui/demo.c)---- */ +meow_view *demo_view_create(void); /* 建 demo view;on_create 调 demo_init() 建 chrome+内容 */ +int demo_is_active(void); /* 1=处于 demo 页 */ +void demo_on_tap(int x, int y); +void demo_touch_down(int x, int y); +void demo_touch_move(int x, int y); +void demo_swipe(int dir, int dist); +void demo_tick(uint64_t now); + +/* demo 构建/绘制入口(宿主 test_p1p2p3_repro 直接驱动 + demo view 复用): + * demo_init 建 chrome+内容(scroll=0);demo_paint 整帧按 z 重画;demo_rebuild_to 重建到 scroll。 */ +void demo_init(void); +void demo_paint(void); +void demo_rebuild_to(int scroll); + +/* ---- demo 视图态(设计定案 B:g_ds/g_drag_* /scroll 留 ui/demo.c,不迁 logic)---- + * 暴露为 extern,供宿主测试对真实 demo 状态断言(P1/P2/P3)。 */ +extern int g_demo; /* 1=处于 demo 演示页 */ +extern int g_demo_focus; /* 1=LazyColumn 聚焦 */ +extern int g_demo_scroll; /* 内容区滚动偏移 */ +extern int g_drag_list; /* 手指在列表:拖拽滚列表 */ +extern int g_drag_page; /* 手指在页内容:拖拽滚页面 */ +extern meow_widget *g_dlc; /* LazyColumn */ +extern meow_widget *g_dprc; /* ProgressBar 圆形 */ +extern rect_t r_prc; /* 圆形进度外接框 */ +extern rect_t r_list; /* 列表区几何 */ +extern rect_t r_dr1, r_dr2; /* Radio 几何 */ + +/* ---- chrome(ui/common/chrome.c)---- */ +extern meow_widget *g_tb; /* TopAppBar(chrome 固定) */ +extern meow_widget *g_nav; /* NavigationBar(chrome 固定) */ +extern meow_widget *g_fab; /* FAB(chrome 置顶;demo 交互可重建换 label) */ +extern rect_t r_tb, r_nav, r_fab; +void chrome_create(void); /* 建 chrome(调用方须先 push ACT_DEMO 使 owner=ACT_DEMO) */ +void chrome_free(void); /* 释放 chrome(demo on_destroy 调) */ + +#endif /* HELLO_INTERNAL_H */ diff --git a/logic/logic.h b/logic/logic.h new file mode 100644 index 0000000..4ca4ae1 --- /dev/null +++ b/logic/logic.h @@ -0,0 +1,30 @@ +/* logic/logic.h — 业务层接口(纯 C,不依赖 meow_ui.h / meow_view)。 + * + * 分层契约(SDK_VIEW_FRAMEWORK_DESIGN.md §B.1): + * ① UI→业务 = 纯函数命令 + getter(logic_* / notify_* 返回业务态,业务不回调 UI); + * ② 业务→UI = 可选 push 监听器(logic_listener_fn + logic_set_listener); + * ③ view 的 ctx = 视图控制器(biz-UI 绑定点)。 + * 本头只声明数据类型与函数原型,不含任何 meow_ui.h / meow_ui_view.h 依赖—— + * logic/state.c 因此保持纯 C;logic/notify.c 仅因要用 SDK 通知 API 而 include meow_ui.h。 + */ +#ifndef HELLO_LOGIC_H +#define HELLO_LOGIC_H + +/* 监听器事件类型(业务态变化 → 通知 UI) */ +#define LOGIC_EV_TAPS 1 /* taps 计数变化 */ +#define LOGIC_EV_SECS 2 /* secs 秒计数变化 */ + +typedef void (*logic_listener_fn)(int ev, void *ctx); /* ctx = 监听器注册时给的视图控制器 */ + +/* ---- 计数业务态(logic/state.c)---- */ +int logic_taps_get(void); /* 返回累计 taps */ +void logic_taps_bump(void); /* taps++,并触发监听器(若已注册) */ +int logic_secs_get(void); /* 返回过去秒数 */ +void logic_secs_add(int n); /* secs += n,并触发监听器(若已注册) */ +void logic_set_listener(logic_listener_fn cb, void *ctx); /* 注册业务→UI 推送监听器(可 NULL 注销) */ + +/* ---- 通知业务(logic/notify.c)---- */ +void notif_send(int which); /* 按索引发一条通知(数据/超时/优先级在业务层定) */ +void notif_cancel(void); /* 取消最近一条发送的通知 */ + +#endif /* HELLO_LOGIC_H */ diff --git a/logic/notify.c b/logic/notify.c new file mode 100644 index 0000000..8675bbd --- /dev/null +++ b/logic/notify.c @@ -0,0 +1,56 @@ +/* logic/notify.c — 通知业务(notif_send/notif_cancel)。 + * + * 纯业务:只依赖 SDK 通知数据类型/API(meow_notify_*)+ meow_log,不碰任何 UI 控件/view。 + * UI 只经 notif_send()/notif_cancel() 调用(契约 ①);本层不回调 UI,最近一条 id 由本层持有。 + * 注:boundary 折中——通知是 SDK 服务(§9.1),故本文件 include meow_ui.h 仅用其通知类型/函数。 + */ +#include "logic.h" +#include "meow_ui.h" +#include +#include + +static uint32_t g_last_notif = 0; /* 最近一次 send 返回的 id,供 cancel */ + +void notif_send(int which) +{ + meow_notify n; + memset(&n, 0, sizeof n); + n.progress = -1; + n.timeout_ms = MEOW_NOTIFY_TIMEOUT_NEVER; + n.urgency = MEOW_NOTIFY_URG_NORMAL; + const char *label = "?"; + + switch (which) { + case 0: label = "INFO"; n.cat = MEOW_NOTIFY_CAT_GENERAL; + n.title = "测试-普通通知"; n.body = "普通 INFO 通知,timeout=5000ms"; n.timeout_ms = 5000; break; + case 1: label = "MEDIA"; n.cat = MEOW_NOTIFY_CAT_MEDIA; n.urgency = MEOW_NOTIFY_URG_LOW; + n.title = "测试-媒体通知"; n.body = "媒体单例,正在播放,timeout=-1 常驻"; + n.timeout_ms = MEOW_NOTIFY_TIMEOUT_ONGOING; break; + case 2: label = "HIGH"; n.cat = MEOW_NOTIFY_CAT_GENERAL; n.urgency = MEOW_NOTIFY_URG_HIGH; + n.title = "测试-紧急度HIGH"; n.body = "高紧急度:顶部横幅+提示音"; n.timeout_ms = 3000; break; + case 3: label = "PROG"; n.cat = MEOW_NOTIFY_CAT_PROGRESS; + n.title = "测试-进度通知"; n.body = "下载进度 40%"; n.timeout_ms = 8000; n.progress = 40; break; + case 4: label = "ONGO"; n.cat = MEOW_NOTIFY_CAT_GENERAL; + n.title = "测试-常驻通知"; n.body = "常驻不自动过期(timeout=-1),需手动取消"; + n.timeout_ms = MEOW_NOTIFY_TIMEOUT_ONGOING; break; + case 5: label = "TGT"; n.cat = MEOW_NOTIFY_CAT_MESSAGE; + n.title = "测试-跳转Activity"; n.body = "点击跳转 target_activity=main"; + n.timeout_ms = 6000; n.target_activity = "main"; n.icon = NULL; break; + default: return; + } + + uint32_t id = meow_notify_send(&n); + g_last_notif = id; + meow_log(MEOW_LOG_INFO, + "notify btn=%s id=%u cat=%s urg=%s tmo=%d prog=%d target=%s title=%s", + label, (unsigned)id, meow_notify_category_str(n.cat), + meow_notify_urgency_str(n.urgency), n.timeout_ms, n.progress, + n.target_activity ? n.target_activity : "-", n.title ? n.title : "-"); +} + +void notif_cancel(void) +{ + int r = meow_notify_cancel(g_last_notif); + meow_log(MEOW_LOG_INFO, "notify cancel id=%u result=%d", (unsigned)g_last_notif, r); + g_last_notif = 0; +} diff --git a/logic/state.c b/logic/state.c new file mode 100644 index 0000000..f676b0a --- /dev/null +++ b/logic/state.c @@ -0,0 +1,38 @@ +/* logic/state.c — 计数业务态(taps/secs)+ 可选推送监听器(biz→UI)。 + * + * 纯 C(无 meow_ui.h 依赖):状态 + getter/setter + 监听器。UI 经 logic_taps_bump()/ + * logic_secs_add() 改状态;业务改后触发监听器(若已注册)通知 UI 刷新——契约 ①②(§B.1)。 + */ +#include "logic.h" +#include + +static int g_taps = 0; +static int g_secs = 0; +static logic_listener_fn g_listener = NULL; +static void *g_listener_ctx = NULL; + +int logic_taps_get(void) +{ + return g_taps; +} +void logic_taps_bump(void) +{ + g_taps++; + if (g_listener) g_listener(LOGIC_EV_TAPS, g_listener_ctx); +} + +int logic_secs_get(void) +{ + return g_secs; +} +void logic_secs_add(int n) +{ + g_secs += n; + if (g_listener) g_listener(LOGIC_EV_SECS, g_listener_ctx); +} + +void logic_set_listener(logic_listener_fn cb, void *ctx) +{ + g_listener = cb; + g_listener_ctx = ctx; +} diff --git a/ui/common/chrome.c b/ui/common/chrome.c new file mode 100644 index 0000000..25a2fea --- /dev/null +++ b/ui/common/chrome.c @@ -0,0 +1,36 @@ +/* ui/common/chrome.c — demo 页共享 chrome(TopAppBar / NavigationBar / FAB)。 + * + * 与 demo 内容分离:chrome 固定不随内容重建滚动;显式 set_z(999) 置顶(§6.2), + * 区域/整帧重画都最后画 chrome。FAB 可被 demo 交互重建换计数 label(见 demo_on_tap)。 + * chrome 控件 owner=ACT_DEMO(由调用方 demo_init 先 push ACT_DEMO 再建),命中/绘制只在 demo 态生效。 + */ +#include "hello_internal.h" + +meow_widget *g_tb = NULL; /* TopAppBar(chrome 固定) */ +meow_widget *g_nav = NULL; /* NavigationBar(chrome 固定) */ +meow_widget *g_fab = NULL; /* FAB(chrome 固定,可重建换计数 label) */ +rect_t r_tb, r_nav, r_fab; + +void chrome_create(void) +{ + int sb = meow_ui_statusbar_height(); + r_tb = RX(0, sb, 480, 56); g_tb = meow_topappbar_create(0, sb, 480, 56, "Widgets Demo"); + meow_topappbar_set_back(g_tb, 1); + r_nav = RX(0, 680, 480, 40); g_nav = meow_navigationbar_create(0, 680, 480, 40); + meow_navigationbar_add_item(g_nav, "Buttons"); + meow_navigationbar_add_item(g_nav, "List"); + meow_navigationbar_add_item(g_nav, "More"); + meow_navigationbar_set_selected(g_nav, 0); + r_fab = RX(406, 616, 56, 56); g_fab = meow_fab_create(406, 616, 56, "+"); + /* chrome 显式置顶(§6.2):> 一切自动 z(127),区域重画/整帧都最后画 chrome。 */ + meow_widget_set_z(g_tb, 999); + meow_widget_set_z(g_nav, 999); + meow_widget_set_z(g_fab, 999); +} + +void chrome_free(void) +{ + if (g_tb) { meow_widget_free(g_tb); g_tb = NULL; } + if (g_nav) { meow_widget_free(g_nav); g_nav = NULL; } + if (g_fab) { meow_widget_free(g_fab); g_fab = NULL; } +} diff --git a/hello.c b/ui/demo.c similarity index 52% rename from hello.c rename to ui/demo.c index aa02370..cb25477 100644 --- a/hello.c +++ b/ui/demo.c @@ -1,95 +1,45 @@ -/* hello.c — MeowOS SDK 版示例应用(链 meow_ui.a,B1)。 +/* ui/demo.c — 控件库 Demo 演示页(ACT_DEMO)view + 控制器。 * - * 契约(MEOW_APP_SDK.md §1/§3/§6):应用只调 meow_ui API —— 屏幕(back_buf + - * flush 上屏)与输入(meow_ui_run 事件循环)由框架接管;不再 open/mmap/ioctl - * /dev/fb0、不再读 /dev/input/event*。 + * 内容控件以绝对坐标创建,页滚动 = 按「base_y - scroll」重建内容(owner=ACT_DEMO 不变); + * 各控件跨重建状态存 g_ds(App 持有),重建后恢复。绘制走 batch① 郑序注册表:demo_paint 调 + * meow_ui_set_page_bg + meow_ui_paint_full(整帧按 z 重画:内容→标题/slider值→chrome 置顶), + * 局部刷新统一 meow_ui_invalidate(清底+按 z 重画相交绘制物)。旧 d_paint_region/d_redraw/ + * d_rect_overlap(App 层郑栈重画)已删、下沉 SDK。 * - * 两大职责: - * A) 原有:验证「清屏 + 画文本 + 画按钮 + 响应触摸」最小闭环 + 通知触发按钮 - * (meow_notify_send,§9.1)端到端测试通知链路; - * B) 新增:**控件库 Demo 演示页**(§5.8 第一/二批组件)——作为 SDK 控件库的 - * 验证载体 + 活文档:用真实控件(meow_btn_* / meow_switch_* / meow_slider_* / - * meow_widget_custom_create / meow_*)搭「展示 + 可交互」界面,用户刷 hello - * 从 home 的「WIDGETS DEMO」按钮进入,逐项验证各组件外观 / 命中 / 状态。 - * - * 交互: - * - home:点 TAP ME → 回圈计数;6 个通知触发行;CANCEL LAST;FULLSCREEN; - * 新增「WIDGETS DEMO」按钮 → 进入 demo 页;左缘左滑 → 退出。 - * - demo 页:TopAppBar 返回箭头 / 左缘左滑 → 回 home;内容区展示并交互 - * Button 五型(含禁用) / Switch / Slider / TextField(点开阻塞 IME) / Checkbox / - * Radio(单选组) / ProgressBar(线性+圆形带动画) / Card(嵌子项) / Divider / - * Badge / TabBar / NavigationBar(底部) / TopAppBar(顶部) / Dialog+BottomSheet / - * FAB / LazyColumn(100 项列表,swipe 滚动)。配色取 meow_theme 语义色板(随系统 - * MD3/MIUIx + 明暗自动切,零硬编码品牌色)。交互局部刷新(meow_ui_flush_region, - * 不整屏、不冲状态栏)。 - * - * 页面/Activity(§6.1 ①):home(根,ACT_HOME 0)、全屏(ACT_FULL 1)、demo(ACT_DEMO 2) - * 三态互斥;控件 owner=创建时 active Activity,命中只在 owner==active 生效(根治跨页 - * 残留)。demo 控件在启动 push(ACT_DEMO) 下一次性创建(owner=ACT_DEMO),此后 home - * 态不命中不绘制、demo 态 home 控件不命中。 - * - * 滚动实现(关键:SDK 控件不透明——结构体对外不可见,App 不能读/写控件坐标;也无 - * 位置 setter): - * - 内容控件以**绝对坐标**创建(App 侧另存 rect_t 几何用于局部 flush/命中)。 - * - 页滚动 = 按「base_y - scroll」**重建**内容控件(仍处于 ACT_DEMO,owner 不变); - * 各控件跨重建状态存于 g_ds(App 持有),重建后恢复。 - * - LazyColumn 是第二滚动区:滚它时 meow_list_scroll_by + 列表区局部刷新,不重建。 - * - 因内容仅略超一屏(max_scroll 小),一次滑动仅触发 1~2 次重建,代价可接受。 - * - * 宿主/qemu 离屏:设 MEOW_UI_DUMP= 时,首帧 flush 即把 back_buf 写成 - * PPM 截图供检查;设备上无副作用。 - * - * Build(见 build_hello.sh): - * zig-mipsel-cc -Os -static hello.c meow_ui.a libz.a -lpthread -o hello + * 设计定案 B(SDK_VIEW_FRAMEWORK_DESIGN §B.3/F):demo 的 g_ds/g_drag_* /g_demo_scroll 等视图态 + * 留本文件(不迁 logic);UI→业务只经 logic_* / notify_*。页面进入/离开经 meow_view_page_push/pop + * 驱动 on_enter/on_leave(demo_page_enter/leave)。 */ -#include "meow_ui.h" +#include "hello_internal.h" #include #include -#include -#include -#include -#include +#include -/* §6.1 ①:Activity 归属。home=根(0);全屏=独立 Activity(无控件);demo=独立 Activity。 */ -#define ACT_HOME 0 -#define ACT_FULL 1 -#define ACT_DEMO 2 +/* 供 demo_content_tap / touch 回调用的前向声明 */ +static void demo_slider_drag(int x); -/* ---- 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 int g_fullscreen = 0; /* 1=处于全屏视图(点任意处退出回主界面) */ -static const char *g_notif_labels[6] = { "INFO", "MEDIA", "HIGH", "PROG", "ONGO", "TGT" }; -static uint32_t g_last_notif = 0; /* 最近一次 send 返回的 id,供 cancel */ -static int g_taps = 0; -static int g_secs = 0; -static char g_btn_label[32] = "TAP ME"; +static demo_ctrl g_demo_ctrl; /* ---- demo 演示页状态 ---- */ -static int g_demo = 0; /* 1=处于 demo 演示页 */ -static int g_demo_scroll = 0; /* 内容区滚动偏移(base 空间 px) */ -static int g_demo_focus = 0; /* 1=LazyColumn 聚焦(swipe 滚列表而非页面) */ -static int g_demo_fab = 0; /* FAB 点击计数反馈 */ -static int g_demo_prog = 0; /* ProgressBar 动画当前值 0..100 */ +int g_demo = 0; /* 1=处于 demo 演示页 */ +int g_demo_scroll = 0; /* 内容区滚动偏移(base 空间 px) */ +int g_demo_focus = 0; /* 1=LazyColumn 聚焦(swipe 滚列表而非页面) */ +static int g_demo_fab = 0; /* FAB 点击计数反馈 */ +static int g_demo_prog = 0; /* ProgressBar 动画当前值 0..100 */ static uint64_t g_demo_prog_last = 0; -static int g_demo_ct = 0; /* 内容视口顶(屏幕 y,= statusbar+56+8) */ -static int g_demo_cb = 0; /* 内容视口底(屏幕 y,=608,NavBar 上方留白) */ -static int g_demo_content_h = 0; /* 内容总高(base 空间;决定 max_scroll) */ +static int g_demo_ct = 0; /* 内容视口顶(屏y = statusbar+56+8) */ +static int g_demo_cb = 0; /* 内容视口底(屏y =608,NavBar 上方留白) */ +static int g_demo_content_h = 0;/* 内容总高(base 空间;决定 max_scroll) */ -/* M2.71-bug2/6:拖动过程(跟手)状态。on_touch_down 锁一种拖拽,on_touch_move 期间实时更新。 */ -static int g_drag_slider = 0; /* 手指按在 slider:拖拽改值(按即定位) */ -static int g_drag_list = 0; /* 手指按在 LazyColumn:拖拽滚列表 */ -static int g_drag_page = 0; /* 手指按在页内容(非 slider/list):拖拽滚页面 */ -static int g_drag_list_last_y = 0; /* 列表拖拽上一帧 y(求增量) */ +/* M2.71-bug2/6:拖动过程(跟手)状态。on_touch_down 锁一种拖拽,on_touch_move 实时更新。 */ +static int g_drag_slider = 0; /* 手指按在 slider */ +int g_drag_list = 0; /* 手指按在 LazyColumn:拖拽滚列表 */ +int g_drag_page = 0; /* 手指按在页内容(非 slider/list):拖拽滚页面 */ +static int g_drag_list_last_y = 0; /* 列表拖拽上一帧 y */ static int g_drag_page_last_y = 0; /* 页面拖拽上一帧 y */ static int g_drag_page_delta = 0; /* 页面拖拽累计位移(节流重建,≥8px 才重建一次) */ /* SDK 控件不透明:App 自记几何,用于局部 flush / 命中 / scroll 重建。 */ -typedef struct { int x, y, w, h; } rect_t; -#define RX(x,y,w,h) ((rect_t){ (x), (y), (w), (h) }) /* demo 各控件跨重建保留的状态(app 持有;重建后按此恢复) */ static struct { @@ -115,34 +65,27 @@ static int g_dslot_n = 0; static struct { int x, y; const char *s; } g_dtitle[D_TITLE_MAX]; static int g_dtitle_n = 0; -/* demo 交互组件引用(rebuild 时 g_* 与 r_* 同步重指/recompute) */ -static meow_widget *g_tb; static rect_t r_tb; /* TopAppBar(chrome 固定) */ -static meow_widget *g_nav; static rect_t r_nav; /* NavigationBar(chrome 固定) */ -static meow_widget *g_fab; static rect_t r_fab; /* FAB(chrome 固定,可重建换计数 label) */ +/* demo 交互组件引用(rebuild 时 g_* 与 r_* 同步重指/recompute;chrome 在 ui/common/chrome.c) */ static meow_widget *g_dbtn_b[5]; static rect_t r_btn[5]; /* Button 五型 */ static meow_widget *g_dbtn_d; /* DISABLED 按钮(禁用不命中,无需 rect) */ static meow_widget *g_dsw; static rect_t r_dsw; /* Switch */ static meow_widget *g_dslider; static rect_t r_slider, r_slider_txt; /* Slider + 值文本 */ static meow_widget *g_dtf; static rect_t r_dtf; /* TextField */ static meow_widget *g_dcb; static rect_t r_dcb; /* Checkbox */ -static meow_widget *g_dr1, *g_dr2; static rect_t r_dr1, r_dr2; /* Radio 单选组 */ +static meow_widget *g_dr1, *g_dr2; rect_t r_dr1, r_dr2; /* Radio 单选组 */ static meow_widget *g_dprl; static rect_t r_prl; /* ProgressBar 线性 */ -static meow_widget *g_dprc; static rect_t r_prc; /* ProgressBar 圆形 */ +meow_widget *g_dprc; rect_t r_prc; /* ProgressBar 圆形 */ static meow_widget *g_dcard; static rect_t r_card; /* Card */ static meow_widget *g_dcard_btn; static rect_t r_cardbtn; /* Card 内容子按钮 */ static meow_widget *g_dbadge; /* Badge */ static meow_widget *g_dtab; static rect_t r_tab; /* TabBar */ static meow_widget *g_dbtn_dlg; static rect_t r_dlg; /* 打开 Dialog 的按钮 */ static meow_widget *g_dbtn_sheet; static rect_t r_sheet;/* 打开 BottomSheet 的按钮 */ -static meow_widget *g_dlc; static rect_t r_list; /* LazyColumn */ - -/* Dialog / BottomSheet(阻塞模态;非控件,main() 创建一次) */ -static meow_dialog *g_dlg; -static meow_sheet *g_sheet; +meow_widget *g_dlc; rect_t r_list; /* LazyColumn */ /* ---- demo 分区标题/slider 值文本:注册为 CUSTOM 绘制物(§6.2 区域重画会重画它们)---- - * 显式 z=D_TITLE_Z:> 一切自动 z(=127)、< chrome 置顶(999),故「内容→标题→slider值→chrome」。 - * 非控件直绘必须注册,否则 meow_ui_invalidate 清底后会漏画(非保留模型固有代价)。 */ + * 显式 z=D_TITLE_Z:> 一切自动 z(=127)、< chrome 置顶(999)。非控件直绘必须注册,否则 + * meow_ui_invalidate 清底后会漏画。 */ #define D_TITLE_Z 128 static int g_dtitle_cid[D_TITLE_MAX]; /* 分区标题绘制物 id(rebuild 时注销/重注册) */ static int g_slider_cid = 0; /* slider 值文本绘制物 id */ @@ -165,77 +108,7 @@ static void demo_draw_slider_val(void *ctx) meow_ui_text(r_slider_txt.x, r_slider_txt.y, buf, 20, th->dim); } -/* 前向声明 */ -static void redraw(void); -static void demo_rebuild_to(int scroll); -static void demo_paint(void); -static void demo_slider_drag(int x); - -/* M2.51:统一日志改用 SDK meow_log()。 */ -static void on_sigterm(int s) { (void)s; meow_ui_request_exit(); } - -/* ============================================================ */ -/* 通知触发(home 既有) */ -/* ============================================================ */ -static void notif_send(int which) -{ - meow_notify n; - memset(&n, 0, sizeof n); - n.progress = -1; - n.timeout_ms = MEOW_NOTIFY_TIMEOUT_NEVER; - n.urgency = MEOW_NOTIFY_URG_NORMAL; - const char *label = "?"; - - switch (which) { - case 0: label = "INFO"; n.cat = MEOW_NOTIFY_CAT_GENERAL; - n.title = "测试-普通通知"; n.body = "普通 INFO 通知,timeout=5000ms"; n.timeout_ms = 5000; break; - case 1: label = "MEDIA"; n.cat = MEOW_NOTIFY_CAT_MEDIA; n.urgency = MEOW_NOTIFY_URG_LOW; - n.title = "测试-媒体通知"; n.body = "媒体单例,正在播放,timeout=-1 常驻"; - n.timeout_ms = MEOW_NOTIFY_TIMEOUT_ONGOING; break; - case 2: label = "HIGH"; n.cat = MEOW_NOTIFY_CAT_GENERAL; n.urgency = MEOW_NOTIFY_URG_HIGH; - n.title = "测试-紧急度HIGH"; n.body = "高紧急度:顶部横幅+提示音"; n.timeout_ms = 3000; break; - case 3: label = "PROG"; n.cat = MEOW_NOTIFY_CAT_PROGRESS; - n.title = "测试-进度通知"; n.body = "下载进度 40%"; n.timeout_ms = 8000; n.progress = 40; break; - case 4: label = "ONGO"; n.cat = MEOW_NOTIFY_CAT_GENERAL; - n.title = "测试-常驻通知"; n.body = "常驻不自动过期(timeout=-1),需手动取消"; - n.timeout_ms = MEOW_NOTIFY_TIMEOUT_ONGOING; break; - case 5: label = "TGT"; n.cat = MEOW_NOTIFY_CAT_MESSAGE; - n.title = "测试-跳转Activity"; n.body = "点击跳转 target_activity=main"; - n.timeout_ms = 6000; n.target_activity = "main"; n.icon = NULL; break; - default: return; - } - - uint32_t id = meow_notify_send(&n); - g_last_notif = id; - meow_log(MEOW_LOG_INFO, - "notify btn=%s id=%u cat=%s urg=%s tmo=%d prog=%d target=%s title=%s", - label, (unsigned)id, meow_notify_category_str(n.cat), - meow_notify_urgency_str(n.urgency), n.timeout_ms, n.progress, - n.target_activity ? n.target_activity : "-", n.title ? n.title : "-"); -} - -static void notif_cancel(void) -{ - int r = meow_notify_cancel(g_last_notif); - meow_log(MEOW_LOG_INFO, "notify cancel id=%u result=%d", (unsigned)g_last_notif, r); - g_last_notif = 0; -} - -static void set_fullscreen(int on) -{ - g_fullscreen = on ? 1 : 0; - meow_ui_set_fullscreen(g_fullscreen); - meow_ui_statusbar_set_collapsed(g_fullscreen); - if (on) meow_ui_activity_push(ACT_FULL); - else meow_ui_activity_pop(); - meow_log(MEOW_LOG_INFO, g_fullscreen ? "fullscreen ON (collapsed), activity->%d" - : "fullscreen OFF (restore), activity->%d", - meow_ui_activity_active()); -} - -/* ============================================================ */ -/* demo 演示页:布局 / 绘制 / 交互 */ -/* ============================================================ */ +/* ---- demo 构建/布局 ---- */ static void d_slot(meow_widget *w, rect_t r) { @@ -247,7 +120,6 @@ static void d_title(int x, int y, const char *s) int i = g_dtitle_n; g_dtitle[i].x = x; g_dtitle[i].y = y; g_dtitle[i].s = s; g_dtitle_n++; - /* 注册为 CUSTOM 绘制物(bbox=文本绘制范围;cb 读 g_dtitle[i]) */ int tw = meow_ui_text_width(s, 20); int th = meow_ui_text_height(20); g_dtitle_cid[i] = meow_draw_custom_register(D_TITLE_Z, x, y, tw, th, @@ -328,8 +200,6 @@ static void demo_build_at(int scroll) /* ---- ProgressBar(线性 + 圆形,on_tick 动画) ---- */ d_title(DCL_X, SY(yb), "PROGRESS (animated)"); yb += 26; r_prl = RX(DCL_X, SY(yb), DFW, 8); g_dprl = meow_progress_create(r_prl.x, r_prl.y, r_prl.w, r_prl.h, g_ds.prog); SLOT(g_dprl, r_prl.x, r_prl.y, r_prl.w, r_prl.h); yb += 16; - /* 圆形进度:r_prc = 整圆像素外接框(中心 ± (r+margin),r=17 → 40×40),使 d_redraw 的 - * flush 区与控件 bbox(=真实绘制范围)一致,不漏刷外圈(bgg M2.71-bug1)。中心仍取原视觉点。 */ r_prc = RX(DCL_X + 400 + 17 - 20, SY(yb) + 17 - 20, 40, 40); g_dprc = meow_progress_circular_create(r_prc.x + 20, r_prc.y + 20, 17, g_ds.prog); SLOT(g_dprc, r_prc.x, r_prc.y, r_prc.w, r_prc.h); yb += 48; @@ -371,10 +241,8 @@ static void demo_build_at(int scroll) #undef SLOT } -/* demo 全页重绘:整帧按 z 序重画全部(set_page_bg 清底 + 注册表按 z 升序)。 - * 此前手工遍历 g_dslot/g_dtitle/后画 chrome 已删;现在自动 z 排:内容(0..127)→标题/slider值(128) - * →chrome(999 置顶),与旧绘制序一致,但「清底+重画」由 SDK 统一按 z 保证(P1 修法下沉)。 */ -static void demo_paint(void) +/* demo 全页重绘:整帧按 z 序重画全部(set_page_bg 清底 + 注册表按 z 升序)。 */ +void demo_paint(void) { const meow_theme *th = meow_theme_get(); meow_ui_set_page_bg(th->bg); /* 页面底 = 主题 bg(区域/整帧重画清底用) */ @@ -382,7 +250,7 @@ static void demo_paint(void) } /* 重建内容到指定 scroll(clamp 到 [0, max_scroll]);进入/滚动共用 */ -static void demo_rebuild_to(int scroll) +void demo_rebuild_to(int scroll) { int vp_h = g_demo_cb - g_demo_ct; int maxs = g_demo_content_h - vp_h; @@ -395,9 +263,9 @@ static void demo_rebuild_to(int scroll) demo_paint(); } -/* 局部刷新统一走 SDK meow_ui_invalidate(清底 + 按 z 重画相交绘制物 + 上屏); - * 旧 d_paint_region/d_redraw/d_rect_overlap(App 层 z 栈重画)已删除、下沉到 SDK(§6.2)。 - * 局部刷新一控件:整区清底 + 重画重叠 z 栈由注册表完成。 */ +/* ---- demo 交互 ---- */ + +/* 局部刷新统一走 SDK meow_ui_invalidate(清底 + 按 z 重画相交绘制物 + 上屏)。 */ static void d_toggle_sel(meow_widget *w, rect_t r) { if (!w) return; @@ -441,11 +309,11 @@ static int demo_content_tap(int x, int y) } /* demo 页 on_tap 分发(chrome → 内容) */ -static void demo_on_tap(int x, int y) +void demo_on_tap(int x, int y) { if (g_tb) { int ah = meow_topappbar_hit(g_tb, x, y); - if (ah == MEOW_TOPBAR_BACK) { g_demo = 0; meow_ui_activity_pop(); redraw(); return; } + if (ah == MEOW_TOPBAR_BACK) { meow_view_page_pop(); return; } } if (g_fab && meow_widget_hit(g_fab, x, y)) { g_demo_fab++; @@ -460,11 +328,11 @@ static void demo_on_tap(int x, int y) int idx = meow_navigationbar_hit(g_nav, x, y); if (idx >= 0) { meow_navigationbar_set_selected(g_nav, idx); meow_ui_invalidate(r_nav.x, r_nav.y, r_nav.w, r_nav.h); return; } } - if (demo_content_tap(x, y)) return; + demo_content_tap(x, y); } /* demo 页 on_tick:ProgressBar 动画(局部刷,~120ms 步进) */ -static void demo_tick(uint64_t now) +void demo_tick(uint64_t now) { if (g_demo_prog_last == 0) g_demo_prog_last = now; if (now - g_demo_prog_last < 120) return; @@ -485,20 +353,15 @@ static void demo_slider_drag(int x) meow_ui_invalidate(r_slider_txt.x, r_slider_txt.y, r_slider_txt.w, r_slider_txt.h); /* 重画值文本 */ } -/* demo 页 on_touch_down:锁一种拖拽(slider > list > 页内容)。非 demo 态跳过。 - * P2:滚动焦点按「本次触摸起作用的控件」绑定、抬手/命中其它区域即释放——命中非 list - * 区域时不再沿用「已聚焦列表」的旧焦点去滚列表,而是切到页/上一层滚动(否则滑完列表再 - * 滑页面,焦点仍在列表里继续滚列表,需额外点一下才出来)。 */ -static void demo_touch_down(int x, int y) +/* demo 页 on_touch_down:锁一种拖拽(slider > list > 页内容)。 */ +void demo_touch_down(int x, int y) { g_drag_slider = 0; g_drag_list = 0; g_drag_page = 0; g_drag_page_delta = 0; if (!g_demo) return; if (meow_widget_hit(g_dslider, x, y)) { g_drag_slider = 1; demo_slider_drag(x); return; } - /* 命中列表 → 本次手势滚列表(焦点绑到列表) */ if (g_dlc && meow_widget_hit(g_dlc, x, y)) { g_demo_focus = 1; g_drag_list = 1; g_drag_list_last_y = y; return; } - /* 未命中列表 → 释放列表焦点,本次手势滚页面 */ g_demo_focus = 0; if (y >= g_demo_ct && y < g_demo_cb && x >= 0 && x < meow_ui_width()) { g_drag_page = 1; g_drag_page_last_y = y; @@ -506,7 +369,7 @@ static void demo_touch_down(int x, int y) } /* demo 页 on_touch_move:拖动过程实时更新(slider 值 / 列表滚动 / 页面滚动节流重建)。 */ -static void demo_touch_move(int x, int y) +void demo_touch_move(int x, int y) { if (!g_demo) return; if (g_drag_slider) { demo_slider_drag(x); return; } @@ -525,11 +388,10 @@ static void demo_touch_move(int x, int y) } } -/* demo 页 on_swipe:LEFT=回 home;UP/DOWN=列表聚焦滚列表,否则页滚动。 - * M2.71-bug6:拖动过程已在 on_touch_move 实时跟手滚过,抬手不再重复滚(否则叠加一次全距跳变)。 */ -static void demo_swipe(int dir, int dist) +/* demo 页 on_swipe:LEFT=回 home;UP/DOWN=列表聚焦滚列表,否则页滚动。 */ +void demo_swipe(int dir, int dist) { - if (dir == MEOW_SWIPE_LEFT) { g_demo = 0; meow_ui_activity_pop(); redraw(); return; } + if (dir == MEOW_SWIPE_LEFT) { meow_view_page_pop(); return; } if (dir != MEOW_SWIPE_UP && dir != MEOW_SWIPE_DOWN) return; if (g_drag_page || g_drag_list) return; /* 本次手势已实时跟手滚动过 */ int del = (dir == MEOW_SWIPE_UP) ? dist : -dist; /* 手指上移 → 偏移增大 */ @@ -542,178 +404,61 @@ static void demo_swipe(int dir, int dist) } } -/* 进入 demo 演示页(重建到顶部) */ -static void demo_enter(void) +/* ---- demo 页 view(on_enter/on_leave/on_destroy 驱动进入/离开/释放)---- */ + +static void demo_page_enter(meow_view *v, void *ctx) { + (void)v; + ((demo_ctrl *)ctx)->active = 1; g_demo = 1; g_demo_focus = 0; - meow_ui_activity_push(ACT_DEMO); demo_rebuild_to(0); meow_log(MEOW_LOG_INFO, "demo enter scroll=0"); } -/* 启动时创建 chrome(固定)+ 内容(scroll=0);push(ACT_DEMO) 后创建使 owner=ACT_DEMO。 */ -static void demo_init(void) +static void demo_page_leave(meow_view *v, void *ctx) +{ + (void)v; + ((demo_ctrl *)ctx)->active = 0; + g_demo = 0; +} + +static void demo_page_destroy(meow_view *v, void *ctx) +{ + (void)v; (void)ctx; + demo_free_content(); /* 内容控件 + CUSTOM 标题/slider值 */ + chrome_free(); /* chrome(TopAppBar / NavigationBar / FAB) */ +} + +void demo_init(void) { - int sb = meow_ui_statusbar_height(); meow_ui_activity_push(ACT_DEMO); - r_tb = RX(0, sb, 480, 56); g_tb = meow_topappbar_create(0, sb, 480, 56, "Widgets Demo"); - meow_topappbar_set_back(g_tb, 1); - r_nav = RX(0, 680, 480, 40); g_nav = meow_navigationbar_create(0, 680, 480, 40); - meow_navigationbar_add_item(g_nav, "Buttons"); - meow_navigationbar_add_item(g_nav, "List"); - meow_navigationbar_add_item(g_nav, "More"); - meow_navigationbar_set_selected(g_nav, 0); - r_fab = RX(406, 616, 56, 56); g_fab = meow_fab_create(406, 616, 56, "+"); - /* chrome 显式置顶(§6.2 置顶):> 一切自动 z(127),区域重画/整帧都最后画 chrome。 */ - meow_widget_set_z(g_tb, 999); - meow_widget_set_z(g_nav, 999); - meow_widget_set_z(g_fab, 999); + chrome_create(); /* chrome 位置/置顶在 chrome.c */ demo_build_at(0); meow_ui_activity_pop(); g_demo_scroll = 0; } -/* ============================================================ */ -/* 既有 home 绘制 / 事件 */ -/* ============================================================ */ - -static void redraw(void) +int demo_is_active(void) { - const meow_theme *th = meow_theme_get(); - int sb = meow_ui_statusbar_height(); - if (g_fullscreen) { - meow_ui_clear(th->accent); - meow_ui_text_center(240, 330, "FULLSCREEN ACTIVE", 28, 0xFFFFFF); - meow_ui_text_center(240, 366, "tap anywhere = back to home", 20, 0xFFFFFF); - meow_ui_text_center(240, 394, "(left-edge swipe also returns)", 20, 0xFFFFFF); - meow_ui_flush(); - return; - } - 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", g_taps, g_secs); - meow_ui_text_center(240, 516, line, 20, th->dim); - meow_ui_text(20, 660, "left-swipe = exit", 20, th->dim); - meow_ui_flush(); + return g_demo; } -static void on_tap(int x, int y) +/* demo view:on_create 建 chrome+内容(一次,owner=ACT_DEMO);进入时 rebuild 到顶。 */ +static void demo_page_create(meow_view *v, void *ctx) { - if (g_demo) { demo_on_tap(x, y); return; } - if (g_fullscreen) { set_fullscreen(0); redraw(); return; } - if (meow_widget_hit(g_demo_btn, x, y)) { demo_enter(); return; } - for (int i = 0; i < 6; i++) { - if (meow_widget_hit(g_nbtn[i], x, y)) { notif_send(i); redraw(); return; } - } - if (meow_widget_hit(g_cancel, x, y)) { notif_cancel(); redraw(); return; } - if (meow_widget_hit(g_fs_btn, x, y)) { set_fullscreen(1); redraw(); return; } - if (meow_widget_hit(g_btn, x, y)) { - g_taps++; - snprintf(g_btn_label, sizeof g_btn_label, "TAPPED x%d", g_taps); - meow_widget_free(g_btn); - g_btn = meow_btn_create(120, 300, 240, 64, g_btn_label); - redraw(); - } -} - -static void on_key(int keycode, int is_down) -{ - (void)keycode; (void)is_down; - meow_log(MEOW_LOG_DEBUG, "key"); -} - -static void on_swipe_progress(int x_start, int dx) -{ - meow_ui_swipe_hint(x_start + dx); -} - -/* M2.71-bug2/6:拖动过程回调(只对 demo 页有意义;home/全屏不拖拽)。 */ -static void on_touch_down(int x, int y) -{ - if (g_demo) demo_touch_down(x, y); -} -static void on_touch_move(int x, int y) -{ - if (g_demo) demo_touch_move(x, y); -} - -static void on_swipe(int dir, int dx, int dy) -{ - (void)dy; - if (g_demo) { demo_swipe(dir, dx); return; } - if (dir == MEOW_SWIPE_LEFT) { - if (g_fullscreen) { set_fullscreen(0); redraw(); } - else { meow_log(MEOW_LOG_INFO, "exit:swipe"); meow_ui_request_exit(); } - } -} - -static void on_tick(void) -{ - uint64_t now = meow_ui_time_ms(); - if (g_demo) { demo_tick(now); return; } - static uint64_t last = 0; - if (now - last >= 1000) { - last = now; - g_secs++; - redraw(); - } -} - -int main(void) -{ - meow_log(MEOW_LOG_INFO, "start"); - meow_ui_opts o = { 480, 720 }; - if (meow_ui_init(&o) != 0) { meow_log(MEOW_LOG_ERROR, "init failed"); return 1; } - meow_theme_add_listener(NULL); - - signal(SIGTERM, on_sigterm); - - 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"); - - /* Dialog / BottomSheet 实例(阻塞模态;打开前排空残留触摸由 SDK 处理) */ - g_dlg = meow_dialog_create(MEOW_DLG_SELECT, "Pick a fruit"); - const char *items[] = { "Apple", "Banana", "Cherry" }; - meow_dialog_set_items(g_dlg, items, 3, 1); - g_sheet = meow_sheet_create("Options", 0); - meow_sheet_add_item(g_sheet, "Copy"); - meow_sheet_add_item(g_sheet, "Delete"); - meow_sheet_add_item(g_sheet, "Share"); - + (void)v; + ((demo_ctrl *)ctx)->view = v; demo_init(); - redraw(); +} - meow_ui_events ev = { on_key, on_tap, on_swipe, on_tick, on_swipe_progress, - on_touch_down, on_touch_move }; - meow_ui_run(&ev); - - 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); - /* demo 内容 + chrome */ - demo_free_content(); - meow_widget_free(g_tb); - meow_widget_free(g_nav); - meow_widget_free(g_fab); - meow_dialog_free(g_dlg); - meow_sheet_free(g_sheet); - meow_ui_shutdown(); - meow_log(MEOW_LOG_INFO, "exit"); - return 0; +meow_view *demo_view_create(void) +{ + static const meow_view_hooks h = { + .on_create = demo_page_create, + .on_enter = demo_page_enter, + .on_leave = demo_page_leave, + .on_destroy = demo_page_destroy, + }; + return meow_view_create(ACT_DEMO, MEOW_VIEW_ACTIVITY, &h, &g_demo_ctrl); } diff --git a/ui/full.c b/ui/full.c new file mode 100644 index 0000000..c54547f --- /dev/null +++ b/ui/full.c @@ -0,0 +1,56 @@ +/* ui/full.c — 全屏页(ACT_FULL)view + 控制器。 + * + * 无控件:进入时声明全屏+状态栏收合,绘制 accent 底 + 三行文本;点任意处/左缘左滑回 home。 + * 页面切换由 meow_view_page_push/pop 驱动 on_enter/on_leave(activity_push/pop 在 page_push/pop 内)。 + * 注:on_leave 里 activity_active() 仍为 ACT_FULL(activity_pop 在其后),故 OFF 日志的 activity + * id 与旧 set_fullscreen(0) 略异——纯诊断日志差异,功能无变化(见报告)。 + */ +#include "hello_internal.h" + +static full_ctrl g_full_ctrl; +static int g_full = 0; /* 1=处于全屏视图 */ + +void full_draw(void) +{ + const meow_theme *th = meow_theme_get(); + meow_ui_clear(th->accent); + meow_ui_text_center(240, 330, "FULLSCREEN ACTIVE", 28, 0xFFFFFF); + meow_ui_text_center(240, 366, "tap anywhere = back to home", 20, 0xFFFFFF); + meow_ui_text_center(240, 394, "(left-edge swipe also returns)", 20, 0xFFFFFF); + meow_ui_flush(); +} + +static void full_page_enter(meow_view *v, void *ctx) +{ + (void)v; + ((full_ctrl *)ctx)->active = 1; + g_full = 1; + meow_ui_set_fullscreen(1); + meow_ui_statusbar_set_collapsed(1); + full_draw(); + meow_log(MEOW_LOG_INFO, "fullscreen ON (collapsed), activity->%d", meow_ui_activity_active()); +} + +static void full_page_leave(meow_view *v, void *ctx) +{ + (void)v; + ((full_ctrl *)ctx)->active = 0; + g_full = 0; + meow_ui_set_fullscreen(0); + meow_ui_statusbar_set_collapsed(0); + meow_log(MEOW_LOG_INFO, "fullscreen OFF (restore), activity->%d", meow_ui_activity_active()); +} + +int full_is_active(void) +{ + return g_full; +} + +meow_view *full_view_create(void) +{ + static const meow_view_hooks h = { + .on_enter = full_page_enter, + .on_leave = full_page_leave, + }; + return meow_view_create(ACT_FULL, MEOW_VIEW_ACTIVITY, &h, &g_full_ctrl); +} diff --git a/ui/home.c b/ui/home.c new file mode 100644 index 0000000..bc252c8 --- /dev/null +++ b/ui/home.c @@ -0,0 +1,119 @@ +/* ui/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; + 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); +}