/* demo_box_scroll.c — 宿主离屏 demo:§12.1 meow_box 布局 + §12.3 meow_scroll fling 端到端。 * 渲染一屏「标题(固定) / 列表(weight 撑满) / 底栏(固定)」的 box 布局(cross 拉伸), * 再对列表跑一次 fling(速度跟踪→惯性滑动到停止处),并 dump PPM 供目检。 * * 编译(宿主 gcc,链真实 SDK 源 + 打桩 font/global): * gcc -o demo_box_scroll demo_box_scroll.c test_host_stub.c \ * meow_ui_gfx.c meow_ui_sys.c meow_ui_theme.c meow_ui_vol.c meow_ui_log.c \ * meow_ui_widget.c meow_ui_input.c meow_ui_activity.c meow_ui_dialog.c meow_ui_ime.c \ * meow_pinyin.c meow_ui_draw.c meow_ui_view.c meow_ui_box.c meow_ui_anim.c meow_ui_scroll.c \ * meow_ui_img.c meow_ui_media.c meow_notify_ipc.c stb_image.c \ * -I. -I../meow_launcherd -DMEOW_UI_HOST_TEST -pthread -lm * 运行:MEOW_UI_DUMP=/tmp/demo_box.ppm ./demo_box_scroll */ #include "meow_ui.h" #include "meow_ui_internal.h" #include #include #include #include #define NROW 60 #define ITEM 44 static int src(int idx, char *label, int len, void *ctx) { (void)ctx; if (idx < 0 || idx >= NROW) return 0; snprintf(label, (size_t)len, "item %d", idx); return 1; } int main(void) { /* 离屏 dump */ setenv("MEOW_UI_DUMP", "/tmp/demo_box.ppm", 1); meow_ui_opts o = { 480, 720 }; if (meow_ui_init(&o) != 0) { printf("DEMO FAIL: init\n"); return 1; } const meow_theme *th = meow_theme_get(); meow_ui_clear(th->bg); /* ---- box 布局:标题(固定) / 列表(weight) / 底栏(固定),交叉轴拉伸 ---- */ meow_box *bx = meow_box_new(MEOW_BOX_V); meow_box_set_rect(bx, 0, 0, 480, 720); meow_box_set_padding(bx, 12, 12, 12, 12); meow_box_set_gap(bx, 8); meow_box_set_align(bx, MEOW_BOX_ALIGN_START, MEOW_BOX_CROSS_STRETCH); meow_widget *header = meow_btn_create(0, 0, 480, 44, "Header (fixed)"); meow_widget *list = meow_list_create(0, 0, 480, 100, NROW, src, NULL); meow_list_set_item_h(list, ITEM); meow_widget *footer = meow_btn_create(0, 0, 480, 52, "Footer (fixed)"); meow_box_add(bx, header, MEOW_BOX_FIXED, 0); meow_box_add(bx, list, MEOW_BOX_WEIGHT, 1); meow_box_add(bx, footer, MEOW_BOX_FIXED, 0); meow_box_arrange(bx); int hr[4], lr[4], fr[4]; meow_widget_rect(header, hr); meow_widget_rect(list, lr); meow_widget_rect(footer, fr); printf("DEMO layout: header(%d,%d,%d,%d) list(%d,%d,%d,%d) footer(%d,%d,%d,%d)\n", hr[0], hr[1], hr[2], hr[3], lr[0], lr[1], lr[2], lr[3], fr[0], fr[1], fr[2], fr[3]); meow_widget_draw(header); meow_widget_draw(list); meow_widget_draw(footer); meow_ui_flush(); /* 上屏并 MEOW_UI_DUMP 写 PPM *//* (host 离屏无 fb → 只落盘) */ /* ---- fling:对列表做一次惯性下滑(速度跟踪→减速→停)---- */ meow_scroll *s = meow_scroll_wrap(list, 0); int maxs = meow_list_max_scroll(list); uint64_t t = meow_ui_time_ms(); for (int i = 0; i < 14; i++) meow_scroll_track(s, 40, t + (uint64_t)i * 16); meow_scroll_fling(s); int guard = 0; while (meow_scroll_active(s) && guard++ < 300) { meow_anim_tick(); usleep(10000); } meow_anim_tick(); int end = meow_scroll_offset(s); printf("DEMO fling: max_scroll=%d final=%d (active=%d)\n", maxs, end, meow_scroll_active(s)); meow_scroll_free(s); meow_box_free(bx); meow_widget_free(list); meow_widget_free(header); meow_widget_free(footer); meow_ui_shutdown(); printf("DEMO OK\n"); return 0; }