- 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,由主会话统一处理)。
114 lines
5.1 KiB
C
114 lines
5.1 KiB
C
/*
|
||
* 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 */
|