- 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,由主会话统一处理)。
66 lines
3.4 KiB
C
66 lines
3.4 KiB
C
/*
|
||
* meow_ui_scroll.h — SDK 滚动物理(§12.3:meow_scroll)。
|
||
*
|
||
* 定位:给既有滚动容器(W_LIST / W_LISTVIEW / LazyColumn / LazyRow)加**可惯性滚动**的
|
||
* **物理层**——速度跟踪(最近 N 个采样加权)、松手 fling(减速度曲线,用 §12.2 动画基座驱动)、
|
||
* 边界过冲 clamp + 简单回弹(不做复杂 spring)、滚动停止可选 snap。**跟手拖动行为保持现状
|
||
* 不变**(track 内部调既有 set_scroll,clamp 一致)。
|
||
*
|
||
* 设计:meow_scroll 是**滚动会话**,包住一个滚动控件(或任意的 set/max/get/redraw 回调)。
|
||
* 拖动态:app 在 on_touch_move 里把位移喂给 meow_scroll_track(dy, t)(等价于 app 直接调
|
||
* meow_list_scroll_by,且额外记录速度采样);松手:app 调 meow_scroll_fling(s),内部用
|
||
* 加权速度采样得出初速 → 起一条 ease-out 动画推进位移 → 每帧只 redraw(flush 列表视口区)。
|
||
*
|
||
* 内存纪律:静态池(应用侧按需创建会话),track/fling/tick 全程零 malloc;无动画时
|
||
* meow_scroll 不参与节拍(fling 由 meow_anim_tick 驱动,活动计数为 0 则零开销)。
|
||
*/
|
||
#ifndef MEOW_UI_SCROLL_H
|
||
#define MEOW_UI_SCROLL_H
|
||
|
||
#include "meow_ui_types.h" /* meow_widget 前向 + 基础类型(子头不引伞头,避免相对路径依赖) */
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
typedef struct meow_scroll meow_scroll;
|
||
|
||
/* ---- 通用回调(wrap 之外的自定义滚动源用)---- */
|
||
typedef void (*meow_scroll_set_fn)(void *ctx, int off);
|
||
typedef int (*meow_scroll_max_fn)(void *ctx);
|
||
typedef int (*meow_scroll_get_fn)(void *ctx);
|
||
typedef void (*meow_scroll_redraw_fn)(void *ctx); /* 只刷滚动视口区(不整屏) */
|
||
|
||
/* 创建会话:app 提供 set/max/get/redraw。返回 NULL=池满。 */
|
||
meow_scroll *meow_scroll_create(meow_scroll_set_fn set, meow_scroll_max_fn max,
|
||
meow_scroll_get_fn get, meow_scroll_redraw_fn redraw,
|
||
void *ctx);
|
||
/* 便捷:包一个 meow_widget 列表(is_listview:1=W_LISTVIEW / 0=W_LIST 或 lazycolumn/row)。
|
||
* redraw 只 flush 该控件矩形(视口区)。 */
|
||
meow_scroll *meow_scroll_wrap(meow_widget *list, int is_listview);
|
||
void meow_scroll_free(meow_scroll *s);
|
||
|
||
/* 拖动跟手 + 速度采样:dy=本次位移(px);t_ms=采样时刻(单调毫秒)。
|
||
* 内部 set_scroll(pos+dy)(clamp 到 [0,max],与 app 直接 scroll_by 行为一致)。 */
|
||
void meow_scroll_track(meow_scroll *s, int dy, uint64_t t_ms);
|
||
|
||
/* 松手 fling:内部用「最近 N 个采样加权」算初速,起减速度曲线动画推进位移;
|
||
* 边界过冲 clamp + 简单回弹;每帧只 redraw 视口区。停止后可选 snap。 */
|
||
void meow_scroll_fling(meow_scroll *s);
|
||
/* 立即停止(取消 fling/回弹/snap,停在当前 offset)。 */
|
||
void meow_scroll_stop(meow_scroll *s);
|
||
|
||
/* 当前加权初速(px/s;为 fling 内部所用,供 app 读取/调试)。 */
|
||
int meow_scroll_velocity(meow_scroll *s);
|
||
|
||
/* 查询/配置 */
|
||
int meow_scroll_active(meow_scroll *s); /* 是否有活动 fling/回弹/snap */
|
||
int meow_scroll_offset(meow_scroll *s); /* 当前 scroll(get) */
|
||
void meow_scroll_set_snap(meow_scroll *s, int step); /* >0=fling 停止后吸附到 step 倍数 */
|
||
void meow_scroll_set_friction(meow_scroll *s, int tau_ms); /* 摩擦时间常数(默认 180ms) */
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif /* MEOW_UI_SCROLL_H */
|