- 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,由主会话统一处理)。
112 lines
6.3 KiB
C
112 lines
6.3 KiB
C
/*
|
||
* meow_ui_view.h — SDK 视图/页面框架(meow_view,嵌套容器 + 生命周期 + 事件路由)。
|
||
*
|
||
* 源:devdocs/plan/SDK_VIEW_FRAMEWORK_DESIGN.md §A。本文件为机制 ABI(结构 + 生命周期钩子 +
|
||
* 页面导航包装),与 z 序绘制物注册表(meow_ui_draw.c,§C/§6.2)协同:
|
||
* - meow_view 是**薄壳**:容器 + 生命周期 + 事件路由;叶子仍是 meow_widget(不改)。
|
||
* - on_draw 是回调,view 不缓存像素(非保留);重绘由 meow_ui_invalidate 触发。
|
||
* - opt-in:不调用 meow_view_* 的 App 完全照旧(widget/activity/flush 不动)。
|
||
* - z 深度源 = view 树(parent/children 深度);叶子 widget 深度 = 所属 view 深度 + 1。
|
||
*
|
||
* 页面模型(定案 b,预留 a):顶层页切换仍由 activity 栈(meow_view_page_push/pop/replace 包装),
|
||
* 不做页内子导航栈;meow_view_sub_push/pop 为将来扩展位(仅在一个 ACTIVITY view 内维护子栈)。
|
||
*/
|
||
#ifndef MEOW_UI_VIEW_H
|
||
#define MEOW_UI_VIEW_H
|
||
|
||
#include "meow_ui.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
typedef struct meow_view meow_view;
|
||
|
||
typedef enum { MEOW_VIEW_ACTIVITY = 0, MEOW_VIEW_CONTAINER = 1 } meow_view_type;
|
||
typedef enum {
|
||
MEOW_VIEW_STATE_CREATED = 1u << 0,
|
||
MEOW_VIEW_STATE_ENTERED = 1u << 1,
|
||
MEOW_VIEW_STATE_DIRTY = 1u << 2,
|
||
} meow_view_state;
|
||
|
||
/* 生命周期/事件钩子(on_create→on_enter→(事件循环)→on_leave→on_destroy + on_layout)。
|
||
* 均以 view 自身 + ctx(=视图控制器,业务-UI 绑定点)为参。可 NULL。 */
|
||
typedef void (*meow_view_fn)(meow_view *v, void *ctx);
|
||
typedef int (*meow_view_ev_fn)(meow_view *v, int ev, int a, int b, void *ctx);
|
||
typedef void (*meow_view_draw_fn)(meow_view *v, const meow_theme *th, void *ctx);
|
||
|
||
typedef struct meow_view_hooks {
|
||
meow_view_fn on_create; /* 建 view 后跑一次(分配视图态/初始布局) */
|
||
meow_view_fn on_enter; /* 页面进入(push/replace 后;回页面自动恢复零重建) */
|
||
meow_view_fn on_leave; /* 页面离开(pop/replace 前;默认不销毁子 view/widget) */
|
||
meow_view_fn on_destroy; /* meow_view_free 释放(递归)时跑 */
|
||
meow_view_fn on_layout; /* 布局(on_create/page_push 后跑一次,算子控件绝对坐标) */
|
||
meow_view_draw_fn on_draw; /* 绘制回调(非保留;由 meow_ui_invalidate 触发) */
|
||
meow_view_ev_fn on_event; /* 事件路由(可 NULL;先发后代按 z 降序,命中即消费) */
|
||
} meow_view_hooks;
|
||
|
||
#define MEOW_VIEW_MAX_CHILD 16
|
||
#define MEOW_VIEW_MAX_WIDGET 32
|
||
|
||
struct meow_view {
|
||
int type; /* MEOW_VIEW_ACTIVITY / MEOW_VIEW_CONTAINER */
|
||
int id; /* 页面/视图 id(App 命名的稳定值;= page_push 用的 id) */
|
||
int x, y, w, h; /* 自身坐标(相对父内容原点;子 view 默认占满,叠放由 z 排) */
|
||
meow_view *parent;
|
||
meow_view *children[MEOW_VIEW_MAX_CHILD];
|
||
int nchildren;
|
||
meow_widget *widgets[MEOW_VIEW_MAX_WIDGET]; /* 叶子控件(直接挂本 view) */
|
||
int nwidgets;
|
||
int z; /* 显式 z(meow_view_set_z);0=未设(由子/注册表推导) */
|
||
unsigned state; /* meow_view_state 位掩码 */
|
||
meow_view_hooks hooks;
|
||
void *ctx; /* 视图控制器(biz-UI 绑定点) */
|
||
};
|
||
|
||
/* ---- 生命周期 ---- */
|
||
meow_view *meow_view_create(int id, meow_view_type type,
|
||
const meow_view_hooks *hooks, void *ctx);
|
||
void meow_view_free(meow_view *v); /* 递归 on_destroy + widget_free 叶子 + 注销 z 序 */
|
||
|
||
/* ---- 嵌套(组合视图树)---- */
|
||
int meow_view_add_child(meow_view *parent, meow_view *child); /* 任意深挂子 view;0/负=结果 */
|
||
int meow_view_add_widget(meow_view *v, meow_widget *w); /* 挂叶子控件(登记 z 深度源) */
|
||
void meow_view_set_z(meow_view *v, int z); /* 显式 z(999 置顶);影响其绘制物 z */
|
||
int meow_view_z(const meow_view *v);
|
||
|
||
/* ---- 页面导航(包装 activity 栈,唯一驱动 on_enter/on_leave——单一入口,App 不再分别调)----
|
||
* 顶层页切换走 activity 栈;页内子导航为预留(见设计定案 b)。 */
|
||
void meow_view_page_push(int id); /* activity_push + 旧top on_leave + 新页 on_enter */
|
||
void meow_view_page_pop(void); /* 旧top on_leave + activity_pop + 新top on_enter */
|
||
void meow_view_page_replace(int id); /* 旧top on_leave + 新页 on_enter(目标页须已 create) */
|
||
|
||
/* 入口:把语义事件注入当前活动页 view 子树路由——先发子视图(按 z 降序),命中即消费,
|
||
* 再落本 view 的 on_event(其内做该 view 的 widget 命中)。返回 1=已消费(§A.7)。
|
||
* 未接线于 meow_ui_run(App 可在 on_tap/on_swipe 等回调里改用它实现 SDK 原生路由)。 */
|
||
int meow_view_dispatch_event(int ev, int a, int b);
|
||
|
||
/* ---- 页内子导航(预留扩展位 a;本批为空实现/桩,仅在 ACTIVITY view 内维护子栈)---- */
|
||
int meow_view_sub_push(meow_view *v, meow_view *sub); /* 预留;返回 0(未实现于本批) */
|
||
meow_view *meow_view_sub_pop(meow_view *v); /* 预留;返回 NULL(未实现于本批) */
|
||
|
||
/* ---- 坐标:view 相对父内容原点的累计(父坐标链求和 → 屏幕绝对坐标)---- */
|
||
int meow_view_screen_x(const meow_view *v);
|
||
int meow_view_screen_y(const meow_view *v);
|
||
|
||
/* ---- 查询 ---- */
|
||
meow_view *meow_view_parent(const meow_view *v);
|
||
int meow_view_get_state(const meow_view *v); /* MEOW_VIEW_STATE_* 位掩码 */
|
||
|
||
/* ---- 布局提供者(§12.1.4:meow_box 作为 view 的 layout,opt-in)----
|
||
* meow_box(见 include/meow_ui_box.h)是**纯布局计算器**,arrange 把子控件算成绝对坐标。
|
||
* 设了布局的 view:其直接挂载控件应**同时**加入该 box(box 会在 arrange 时写这些控件的
|
||
* x/y/w/h);page 进入/relayout 时框架自动 arrange。未设布局的 view 保持现有绝对坐标行为
|
||
* (on_layout 里自己算,零改动)。box 矩形默认跟 view 内容矩形(w/h 未设时自动填)。 */
|
||
void meow_view_set_layout(meow_view *v, struct meow_box *box); /* NULL=取消 */
|
||
void meow_view_relayout(meow_view *v); /* 手动重排(改 box 后调) */
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif /* MEOW_UI_VIEW_H */
|