117 lines
6.8 KiB
C
117 lines
6.8 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(M7.0a):在 §6.4 分流之上,TAP/KEY/SWIPE/LONG_PRESS 先经本路由,
|
||
* 命中即消费(不再落 App 的 on_* 回调);返回 0 时回落 on_* 原路径(无 view 树 / 未命中 →
|
||
* 完全向后兼容)。App 也可在自持事件循环里直接调用本函数实现 SDK 原生路由。 */
|
||
int meow_view_dispatch_event(int ev, int a, int b);
|
||
|
||
/* ---- 页内子导航(预留扩展位 a,**标注废弃**)----
|
||
* 设计定案 b(§F.2):不做页内子导航栈,只做子视图容器嵌套;顶层页切仍走 activity 栈。
|
||
* 故本组为**不实现、不供依赖**的桩(返回 0/NULL);页内子页请用 meow_view_add_child 挂
|
||
* CONTAINER 子视图,或以 page_push/pop/replace 走 activity 栈。保留符号仅作将来 a 的占位。 */
|
||
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 */
|