Files
MeowOS 5a5e995ebd 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,由主会话统一处理)。
2026-09-01 23:49:24 +08:00

114 lines
5.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* meow_ui_box.h — SDK 线性布局引擎(§12.1:meow_box)。
*
* 定位:既有的 meow_row/column/box(§5.8.5,W_LAYOUT)只支持「固定尺寸子项 + 居中」,
* 本模块是其**独立增强**:竖直/水平容器,子项 = 固定尺寸 | weight 权重 | wrap(内容测量),
* 支持 margin/padding / 主轴对齐(start/center/end/space-between/around/evenly)/ 交叉轴对齐
* (start/center/end/stretch)/ 嵌套。
*
* 与绝对定位完全兼容:meow_box 是**纯布局计算器**,不是控件,不参与 z 序注册表/命中/绘制;
* arrange 把每个子控件的 x/y/w/h 写进现有 meow_widget(用新增 meow_widget_set_rect),
* 此后照常 draw/hit/flush_region/owner 闸门——与既有控件绝对定位零冲突。
*
* 与视图框架集成(opt-in):meow_box 可作 meow_view 的布局提供者(meow_view_set_layout);
* view 不设就保持现有绝对坐标行为(§12.1.4)。
*
* 内存纪律:静态池 + 定长 items 数组(≥MEOW_BOX_MAX_CHILD),热路径(arrange)零 malloc;
* 嵌套用深度≤MEOW_BOX_MAX_DEPTH 的静态栈单遍求解,无递归爆炸。
*/
#ifndef MEOW_UI_BOX_H
#define MEOW_UI_BOX_H
#include "meow_ui_types.h" /* meow_widget 前向 + 基础类型(子头不引伞头,避免相对路径依赖) */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct meow_box meow_box;
/* 主轴方向 */
typedef enum {
MEOW_BOX_H = 0, /* 横向(row) */
MEOW_BOX_V = 1, /* 纵向(column) */
} meow_box_dir;
/* 子项主轴尺寸策略 */
typedef enum {
MEOW_BOX_FIXED = 0, /* 固定尺寸:内容主轴向取控件当前 w/h */
MEOW_BOX_WEIGHT = 1, /* 权重:均分剩余主轴空间(weight>0) */
MEOW_BOX_WRAP = 2, /* wrap:按内容测量(min/preferred 或 measure 回调) */
} meow_box_size;
/* 主轴对齐 */
typedef enum {
MEOW_BOX_ALIGN_START = 0,
MEOW_BOX_ALIGN_CENTER = 1,
MEOW_BOX_ALIGN_END = 2,
MEOW_BOX_ALIGN_SPACE_BETWEEN = 3,
MEOW_BOX_ALIGN_SPACE_AROUND = 4,
MEOW_BOX_ALIGN_SPACE_EVENLY = 5,
} meow_box_align;
/* 交叉轴对齐 */
typedef enum {
MEOW_BOX_CROSS_START = 0,
MEOW_BOX_CROSS_CENTER = 1,
MEOW_BOX_CROSS_END = 2,
MEOW_BOX_CROSS_STRETCH = 3,
} meow_box_cross;
/* 内容测量回调(size==MEOW_BOX_WRAP 时用;可 NULL):给出主轴向 min/preferred 尺寸。
* ctx = meow_box_add_ex 的 mctx。 */
typedef void (*meow_box_measure_fn)(void *ctx, int *min_main, int *pref_main);
/* 子项描述(add/add_ex/add_sub 提供;app 只读)。w 与 sub 二选一。 */
typedef struct meow_box_item {
meow_widget *w; /* 子控件(sub==NULL 时用) */
meow_box *sub; /* 嵌套 box(w==NULL 时用) */
int size; /* MEOW_BOX_* 尺寸策略 */
int weight; /* size==WEIGHT 时>0 */
int min; /* size==WRAP 的主轴下限 */
int preferred;/* size==WRAP 的主轴目标 */
meow_box_measure_fn measure; /* size==WRAP 内容测量(可 NULL) */
void *mctx;
} meow_box_item;
#define MEOW_BOX_MAX_CHILD 24 /* 每容器子项上限(静态数组) */
#define MEOW_BOX_MAX_DEPTH 16 /* 嵌套深度上限(静态求解栈) */
/* ---- 生命周期(静态池;new 冷路径,arrange 热路径零 malloc)----
* 注:命名用 meow_box_new(meow_box_create 已被 §5.8.5 的 W_LAYOUT box 占用)。 */
meow_box *meow_box_new(meow_box_dir dir);
void meow_box_free(meow_box *b);
/* ---- 容器配置 ---- */
void meow_box_set_rect(meow_box *b, int x, int y, int w, int h); /* 容器矩形(绝对坐标) */
void meow_box_set_padding(meow_box *b, int l, int t, int r, int btm);
void meow_box_set_gap(meow_box *b, int gap);
void meow_box_set_align(meow_box *b, int main_align, int cross_align);
/* ---- 子项添加(返回 0=成功;越界/无效=负值,不清空既有子项)---- */
int meow_box_add(meow_box *b, meow_widget *w, int size, int weight);
/* add_ex:WRAP 用 min/preferred(主轴向)+ 可选内容测量回调。 */
int meow_box_add_ex(meow_box *b, meow_widget *w, int size, int weight,
int min, int preferred, meow_box_measure_fn m, void *mctx);
/* 嵌套子 box(parent 布局会为 sub 分配矩形并递归 arrange)。 */
int meow_box_add_sub(meow_box *b, meow_box *sub, int size, int weight);
/* ---- 求解(单遍;深度≤MEOW_BOX_MAX_DEPTH 静态栈,无递归)----
* 把每个子控件 x/y/w/h 写进其 meow_widget(meow_widget_set_rect);
* 嵌套 sub 的矩形写进 sub 并递归。子控件的 margin(meow_widget_opts.margin_x/y)参与排布。 */
void meow_box_arrange(meow_box *b);
/* ---- 查询 ---- */
int meow_box_count(const meow_box *b);
meow_widget *meow_box_widget_at(const meow_box *b, int idx); /* 子项控件(无则 NULL) */
meow_box *meow_box_sub_at(const meow_box *b, int idx); /* 子项嵌套 box(无则 NULL) */
void meow_box_rect(const meow_box *b, int out[4]); /* x,y,w,h */
#ifdef __cplusplus
}
#endif
#endif /* MEOW_UI_BOX_H */