SDK 冲刺批①+②+⑤: meow_box 线性布局 + meow_anim 动画基座 + meow_scroll 滚动物理
- meow_box(include/meow_ui_box.h + meow_ui_box.c):竖直/水平容器;子项=固定|weight|wrap; margin/padding/gap;主轴对齐 start/center/end/space-between/around/evenly;交叉轴 start/center/end/stretch; 嵌套(深度≤16 静态栈,单遍求解,无递归爆炸)。可作 meow_view 布局提供者 (meow_view_set_layout/relayout,opt-in;未设布局的 view 保持现有绝对坐标行为)。 新增 meow_widget_set_rect(只写字段不标脏)作为 box 写坐标的通道。 - meow_anim(include/meow_ui_anim.h + meow_ui_anim.c):时间驱动 tween(from/to/duration/easing: linear/ease-out/ease-in-out/overshoot)+ update/done 回调;静态池≤16、取消、并行多动画; meow_anim_set_region 让每帧只 flush 动画影响区(不整屏)。meow_anim_tick 挂主循环 on_tick, 无动画零开销(只查计数即返回)。 - meow_scroll(include/meow_ui_scroll.h + meow_ui_scroll.c):速度跟踪(最近 N 采样加权)+ 松手 fling (减速度曲线,用 anim 基座驱动)+ 边界过冲 clamp + 简单回弹(不做 spring)+ 可选 snap; 跟手拖动行为不变(track 内部调既有 set_scroll);每帧只 redraw 列表视口区;不引 libm。 - 追加式:既有 meow_row/column/box 与全部 meow_*_create/hit/scroll 签名一行未改;旧绝对坐标永远有效; 既有 App 免改源码。 - 验证:宿主新测试 box(42)/anim(32)/scroll(17) 全 PASS;既存 9 回归(widgets/sdk_input_keys/ime_fix/ pinyin/overlay_suppress/notif_gesture/sdk_fixes/sb_collapse/p1p2p3_repro)全 PASS; 离屏 demo(demo_box_scroll.c)渲染 box 布局 + 列表 fling 正常;zig-mipsel -Wall -Wextra 全 TU 0 warning; meow_ui.a md5 83dd6a2d0d24cc748a8659c29f1de2b5(未重链/部署 hello/files/ncm/reader,由主会话统一处理)。
This commit is contained in:
1 parent
553a7d5d9e
commit
5a5e995ebd
19 files changed
+1839
-2
No files matched your search
@@ -0,0 +1,89 @@
|
||||
/* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in new issue
Block a user