Files
MeowOS-SDK/include/meow_ui_widgets.h
T
MeowOS 2e7561d74f sdk: meow_ui.h 公共头按模块拆分(伞头聚合,API 零改动)
- meow_ui.h(922 行)改为伞头:只做 #include 聚合 + 模块索引,不定义新 API。
- 新增 patch_v2/sdk/include/ 16 个子头(types/draw/image/theme/ime/widgets/input/
  activity/zorder/statusbar/dialog/log/notify/config/font/audio),各自自洽可单独 include,
  依赖最小化(不透明句柄前向声明 + 必要模块互引)。
- 验证:meow_ui.a md5 与主树完全一致(4786158d…,头重组 .o 逐字节等价);
  SDK .c 用 mipsel -Wall -Wextra 0 warning;hello/files 全量重编链接通过
  (-Wall -Wextra 0 warning);宿主 test_p1p2p3_repro(P1c/P2/P3 ALL PASS)
  + 15 个 SDK/宿主测试 PASS;16 子头自洽编译 0 warning;伞头完整性回归
  test_umbrella.c 0 warning;ncm 5 个含 meow_ui.h TÜ mipsel 交叉编译到 .o 0 warning。
- meow_ui_internal.h 及 view/nav/media/sys/vol 子头未动;build_sdk.sh 无需改。
- MEOW_APP_SDK.md 头部新增「公共头模块索引」。分支 sdk-header-split。
2026-09-01 20:30:16 +08:00

298 lines
18 KiB
C
Raw 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_widgets.h — SDK 控件层(§5 控件)+ 控件层升级(§5.8 基座)+ Material 3 组件子集(§5.8.6)
* + 结构化列表 W_LISTVIEW(§5.5)。
*
* 原 meow_ui.h 拆分的一部分(widgets 模块)。依赖 meow_ui_theme.h(meow_theme/MD3 色板/风格参数)
* 与 meow_ui_ime.h(meow_ime_mode,TextField 接 IME);meow_img 为不透明句柄(meow_ui_types.h)。
* 向后兼容:既有 create 签名一字不改,只在上面扩展(Options/状态机走新增挂载器)。
*/
#ifndef MEOW_UI_WIDGETS_H
#define MEOW_UI_WIDGETS_H
#include "meow_ui_types.h"
#include "meow_ui_theme.h"
#include "meow_ui_ime.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ============================================================ */
/* §5 控件层 */
/* ============================================================ */
typedef struct meow_widget meow_widget;
meow_widget *meow_btn_create(int x, int y, int w, int h, const char *label);
meow_widget *meow_slider_create(int x, int y, int w, int min, int max, int val);
meow_widget *meow_switch_create(int x, int y, int on);
/* 列表数据源回调:idx 有效时填 label 并返回 1;越界返回 0([D2] 定案签名) */
typedef int (*meow_list_source)(int idx, char *label, int len, void *ctx);
meow_widget *meow_list_create(int x, int y, int w, int h, int count,
meow_list_source src, void *ctx);
void meow_widget_free(meow_widget *w);
void meow_widget_draw(meow_widget *w); /* 每次 flush 前调用 */
int meow_widget_hit(meow_widget *w, int x, int y); /* 点是否落在控件内 */
void meow_slider_set(meow_widget *s, int val);
int meow_slider_get(meow_widget *s);
void meow_switch_set(meow_widget *w, int on);
int meow_switch_get(meow_widget *s);
int meow_btn_pressed(meow_widget *w); /* 应用在 on_tap 命中后标记按下 */
/* ============================================================ */
/* §5.8 控件层升级(第一批=通用基座):Options / 状态机 / 自定义画布 / 布局 */
/* ============================================================ */
/* ---- §5.8.2 Modifier 式通用 Options(轻量结构体,非链式 DSL)----
* 经 meow_widget_set_opts 一次性挂载,作用于任意控件(标准/自定义)。全部控件共用。
* 哨兵语义:bg/fg==0=用控件/主题默认;stroke==0=无描边;stroke_w=描边宽;
* radius==-1=控件默认(如按钮 10),>=0=指定圆角(0=直角);pad/margin=0=无;
* disabled/selected=1=置位(立即反映到状态机位)。 */
typedef struct meow_widget_opts {
uint32_t bg; /* 背景色(0=控件/主题默认) */
uint32_t fg; /* 前景/文字(0=主题 onSurface) */
uint32_t stroke; /* 描边色(0=无描边) */
int stroke_w; /* 描边宽(px) */
int radius; /* 圆角(px;-1=控件默认,如按钮 10) */
int pad_x; /* 内边距(水平,px) */
int pad_y; /* 内边距(垂直,px) */
int margin_x; /* 外边距(水平,px;布局用) */
int margin_y; /* 外边距(垂直,px;布局用) */
int disabled; /* 1=禁用(视觉变暗 + 不响应命中,见状态机 §5.8.3) */
int selected; /* 1=选中(列表高亮/勾选,见状态机 §5.8.3) */
} meow_widget_opts;
/* 挂载:作用于任意控件(标准/自定义)。w 内部浅拷这份 opts。
* 返回 0=成功;NULL/无效=负值(不销毁 w)。 */
int meow_widget_set_opts(meow_widget *w, const meow_widget_opts *opts);
/* 取回当前 opts(浅拷到 out;0=成功)。自定义画布用它读通用修饰。 */
int meow_widget_opts_get(const meow_widget *w, meow_widget_opts *out);
/* ---- §5.8.3 统一状态机(enabled / selected / focused / pressed)----
* 标准/自定义控件共用;visual 层由 SDK/App 按状态位叠。enabled=0 阻断 hit/pressed。 */
#define MEOW_WS_ENABLED (1u<<0)
#define MEOW_WS_SELECTED (1u<<1)
#define MEOW_WS_FOCUSED (1u<<2)
#define MEOW_WS_PRESSED (1u<<3)
/* 设/查状态(置位/清位,其它位不动)。on=1 置位 / 0 清位。 */
void meow_widget_set_state(meow_widget *w, unsigned bits, int on);
unsigned meow_widget_state(const meow_widget *w);
/* 便捷:禁用/启用、选中/取消(单态等效于 set_state)。 */
int meow_widget_enabled(const meow_widget *w);
void meow_widget_set_enabled(meow_widget *w, int on);
int meow_widget_selected(const meow_widget *w);
void meow_widget_set_selected(meow_widget *w, int on);
/* 一键叠状态层(自定义画布可选):把 pressed/focused/disabled/selected 的视觉层
* 叠到 w 的矩形上(半透明状态层 + 焦点描边)。标准控件由 SDK 自动叠,无需调用;
* 自定义画布在 render_cb 里画完内容后可调它(App 也可据 meow_widget_state 自行叠)。 */
void meow_widget_draw_state_layer(meow_widget *w, const meow_theme *th);
/* ---- §5.8.1 自定义画布(App 提供 render/hit 回调;同一个 meow_widget)----
* render:SDK 在 meow_widget_draw 时调用,th=当前生效主题(MD3 语义色板);
* w 的 x/y/w/h 已就位;App 用 §3/§4 绘制 API 自绘(往 back_buf 画)。
* hit :命中判定,App 自定义(如圆形/区域外镂空);返回 1=命中。 */
typedef void (*meow_widget_render_fn)(meow_widget *w, const meow_theme *th, void *ctx);
typedef int (*meow_widget_hit_fn)(meow_widget *w, int x, int y, void *ctx);
/* 创建:自定义画布(x,y,w,h = 绝对坐标,同既有控件)。
* 生命周期/Activity 归属:创建时绑定当前 active Activity(同 meow_btn_create,§6.1 ①);
* 命中走 hit_cb(先过 owner==active + enabled 双闸门)。 */
meow_widget *meow_widget_custom_create(int x, int y, int w, int h,
meow_widget_render_fn render_cb,
meow_widget_hit_fn hit_cb,
void *ctx);
/* ---- §5.8.5 可组合布局(Row / Column / Box + Spacer)----
* 布局容器 = meow_widget(W_LAYOUT);arrange 把子控件算成绝对坐标(写进各 child 的
* x/y/w/h)→ 与现有绝对定位完全兼容(draw/hit/flush_region/owner 闸门照常)。
* 本批先支持固定尺寸子项(w/h 均已知);弹性(w/h==0)为后续增强。 */
enum { MEOW_LAYOUT_ROW = 0, MEOW_LAYOUT_COLUMN = 1, MEOW_LAYOUT_BOX = 2 };
meow_widget *meow_row_create(int x, int y, int w, int h, int spacing);
meow_widget *meow_column_create(int x, int y, int w, int h, int spacing);
meow_widget *meow_box_create(int x, int y, int w, int h);
/* 添加子控件(子可为普通控件/自定义/另一布局/Spacer)。返回 0=成功;无效=负值。 */
int meow_layout_add(meow_widget *layout, meow_widget *child);
/* 计算子控件绝对坐标(写入各 child 的 x,y,w/h;嵌套布局递归);此后照常 draw/hit。 */
void meow_layout_arrange(meow_widget *layout);
/* 固定尺寸空白(也作撑余量;不可见,hit 恒 0)。 */
meow_widget *meow_layout_spacer(int w, int h);
/* ============================================================ */
/* §5.8.6 Material 3 组件子集(第二批,基于第一批基座:Options + 状态机 + MD3 色板 + 布局)
* 每个组件 = 新增 meow_widget 类型或组合既有模板的便捷函数;复用主题语义色(th->primary /
* surfaceContainer / outline / ...)+ 风格参数(radius/radius_card/spacing/stroke_w)+ 通用
* Options(meow_widget_set_opts 对它们同样生效)+ 状态机(enabled/selected/pressed/focused)。
* 向后兼容:既有 create 签名一字不改;本批只在其上扩展。 */
/* ============================================================ */
/* ---- Button 五型(meow_btn 扩展;既有 meow_btn_create = FILLED)---- */
enum {
MEOW_BTN_FILLED = 0, /* primary 底 / onPrimary 文 */
MEOW_BTN_TONAL = 1, /* secondaryContainer 底 / onSecondaryContainer 文 */
MEOW_BTN_OUTLINED = 2, /* 透明底 / primary 文 / primary 描边 */
MEOW_BTN_TEXT = 3, /* 透明底 / primary 文 / 无描边 */
MEOW_BTN_ELEVATED = 4, /* surfaceContainerLow 底 / primary 文 */
};
meow_widget *meow_btn_create_variant(int x, int y, int w, int h, const char *label, int variant);
int meow_btn_set_variant(meow_widget *w, int variant); /* 越界 clamp;0=成功 */
/* ---- TextField(单行文本输入,接 IME §5.1)---- */
/* placeholder=提示文案;buf=App 持有的文本缓冲(组件不回拷,只绘制/编辑其上);maxlen=含 NUL 预算 */
meow_widget *meow_textfield_create(int x, int y, int w, int h, const char *placeholder,
char *buf, int maxlen, meow_ime_mode mode);
void meow_textfield_set_placeholder(meow_widget *w, const char *placeholder);
/* 聚焦并打开**阻塞** IME(同 meow_ui_text_input 内层轮询);回车不关闭键盘,ESC/点背景关闭。
* 内容经 on_change 实时同步到 w->buf(返回值关闭路径为 0,提交不依赖返回值回填)。 */
int meow_textfield_activate(meow_widget *w);
const char *meow_textfield_text(meow_widget *w);
/* ---- Card(圆角容器卡片;surfaceContainerLow 底 + 可选描边/状态层)---- */
meow_widget *meow_card_create(int x, int y, int w, int h);
/* 内容子控件:绘制时递归绘到卡片内(卡片 hit 仍为矩形;子控件独立命中) */
void meow_card_set_content(meow_widget *card, meow_widget *child);
/* ---- Divider(分隔线;vertical=1 纵向)---- */
meow_widget *meow_divider_create(int x, int y, int len, int vertical);
/* ---- Badge(角标;count=0 红点 / >0 数字 / <0 隐藏;cx,cy=锚点=角标中心)---- */
meow_widget *meow_badge_create(int cx, int cy);
void meow_badge_set(meow_widget *w, int count);
/* ---- Checkbox / Radio(勾选态走 meow_widget_set_selected/meow_widget_selected)---- */
meow_widget *meow_checkbox_create(int x, int y);
meow_widget *meow_radio_create(int x, int y);
/* ---- ProgressBar(线性/圆形;value=0-100 确定性,-1=不定)---- */
meow_widget *meow_progress_create(int x, int y, int w, int h, int value); /* 线性 */
meow_widget *meow_progress_circular_create(int cx, int cy, int r, int value); /* 圆形 */
void meow_progress_set(meow_widget *w, int value); /* -1=不定 */
/* ---- FloatingActionButton(悬浮按钮;圆角胶囊,无投影仅状态层近似)---- */
meow_widget *meow_fab_create(int x, int y, int size, const char *label);
/* ---- TopAppBar(顶部标题栏:标题 + 返回 + 动作)---- */
meow_widget *meow_topappbar_create(int x, int y, int w, int h, const char *title);
void meow_topappbar_set_title(meow_widget *w, const char *title);
void meow_topappbar_set_back(meow_widget *w, int on); /* 1=显示返回箭头 */
int meow_topappbar_add_action(meow_widget *w, const char *label); /* 返回动作下标 */
#define MEOW_TOPBAR_BACK (-2)
int meow_topappbar_hit(meow_widget *w, int x, int y); /* MEOW_TOPBAR_BACK=返回 idx>=0=动作 -1=无 */
/* ---- NavigationBar(底部导航栏)---- */
meow_widget *meow_navigationbar_create(int x, int y, int w, int h);
int meow_navigationbar_add_item(meow_widget *w, const char *label);
void meow_navigationbar_set_selected(meow_widget *w, int idx);
int meow_navigationbar_selected(meow_widget *w);
int meow_navigationbar_hit(meow_widget *w, int x, int y); /* 返回项下标/-1 */
/* ---- TabBar(顶部分页页签;swipe 联动 §5.2 由 App 在 on_swipe 驱动)---- */
meow_widget *meow_tabbar_create(int x, int y, int w, int h);
int meow_tabbar_add_tab(meow_widget *w, const char *label);
void meow_tabbar_set_selected(meow_widget *w, int idx);
int meow_tabbar_hit(meow_widget *w, int x, int y); /* 返回页签下标/-1 */
/* ---- 列表容器(LazyColumn/LazyRow:数据源回调 + 可见区虚拟化;复用 meow_list_source)
* meow_lazycolumn_create=纵向(item_h=行高);meow_lazyrow_create=横向(item_w=列宽)。
* 滚动由 App 在 on_swipe 里用 meow_list_scroll_by/set_scroll 驱动。 */
meow_widget *meow_lazycolumn_create(int x, int y, int w, int h, int item_h, int count,
meow_list_source src, void *ctx);
meow_widget *meow_lazyrow_create(int x, int y, int w, int h, int item_w, int count,
meow_list_source src, void *ctx);
void meow_list_set_scroll(meow_widget *w, int offset); /* clamp 到 [0, max_scroll] */
int meow_list_scroll(meow_widget *w);
int meow_list_max_scroll(meow_widget *w); /* max(0, count*item - viewport) */
void meow_list_scroll_by(meow_widget *w, int dy); /* 相对滚动(App on_swipe 用) */
int meow_list_set_item_h(meow_widget *w, int item); /* 改行高/列宽 */
int meow_list_hit_index(meow_widget *w, int x, int y); /* 命中项下标(含滚动换算);-1=未命中项/越界 */
/* M2.71-bug8:列表行选中 + 行点击回调。选中行已有高亮(现有绘制读 w->sel)。
* meow_list_tap_at:命中一行则置选中并回调 tap_cb(若设),返回该行 idx;未命中返回 -1。 */
void meow_list_set_selected(meow_widget *w, int idx); /* 选中行(越界 clamp);标脏 */
int meow_list_selected(meow_widget *w);
typedef void (*meow_list_tap_fn)(int idx, void *ctx);
void meow_list_set_on_tap(meow_widget *w, meow_list_tap_fn cb, void *ctx); /* 命中行→回调 */
int meow_list_tap_at(meow_widget *w, int x, int y); /* 命中行:置选中+回调,返回 idx/-1 */
/* ============================================================ */
/* §5.5 设计模板 A② 结构化列表(W_LISTVIEW):行=图标+标题+副标题+右侧操作 + 选中
* ------------------------------------------------------------
* 在既有「label-only」列表(meow_list_create/lazycolumn,行为不变)之上做**结构化扩展**:
* 行数据源回调逐行给出 meow_list_item(图标 / 标题 / 副标题 / 右侧操作 / 可选中),容器负责
* 绘制/滚动/选中/命中;支持单选/多选/无选择。向后兼容:既有 meow_list_* 全部保留不动。
* 颜色全部取 meow_theme_get() 语义色(日/夜/style 自动),不硬编码。
* 命中:meow_listview_hit 返回行号(含滚动换算 + 禁用行不响应);行右 1/3 为右侧操作区
* (meow_listview_hit_op 另判)。抬手用最新坐标(goodix 免疫,参照既有 W_LIST 习惯)。 */
/* ============================================================ */
/* 选中模式:无(纯入口列表)/ 单选 / 多选。 */
typedef enum { MEOW_LIST_SEL_NONE = 0, MEOW_LIST_SEL_SINGLE, MEOW_LIST_SEL_MULTI } meow_list_sel;
/* 行图标:meow_img*(MEOW_LIST_ICON_IMG)或内置符号(FOLDER/FILE,无图 App 用)。 */
typedef enum {
MEOW_LIST_ICON_NONE = 0, /* 无图标 */
MEOW_LIST_ICON_IMG, /* 用 item->icon(meow_img*) */
MEOW_LIST_ICON_FOLDER, /* 内置目录符号(填充矩形+页签) */
MEOW_LIST_ICON_FILE, /* 内置文件符号(空心矩形+折角) */
} meow_list_icon_kind;
/* 行右侧操作类型:无 / 箭头 / 开关 / 复选 / 详情钮(⋯)。 */
typedef enum {
MEOW_LIST_RIGHT_NONE = 0, /* 无右侧操作 */
MEOW_LIST_RIGHT_ARROW, /* 箭头 › */
MEOW_LIST_RIGHT_SWITCH, /* 开关(on/off = item->on) */
MEOW_LIST_RIGHT_CHECK, /* 复选标记 */
MEOW_LIST_RIGHT_MORE, /* ⋯ 详情钮 */
} meow_list_right;
/* 单行数据(回调填充到栈上,容器不长期持有)。title 必填;subtitle 可空。 */
typedef struct meow_list_item {
const meow_img *icon; /* 可选(icon_kind==MEOW_LIST_ICON_IMG 时用) */
int icon_kind; /* MEOW_LIST_ICON_*(NONE=无图标) */
const char *title; /* 主文本(必填,NULL 视为空行) */
const char *subtitle; /* 副文本,可空 */
int right; /* MEOW_LIST_RIGHT_* 右侧操作类型 */
int on; /* right==SWITCH 时开关态(0/1) */
int enabled; /* 1=可选中/可交互;0=变淡不响应命中 */
} meow_list_item;
/* 行数据源回调:idx 有效时填充 out 并返回 1;越界返回 0。每行轻量填充(不做 IO,§5.5)。 */
typedef int (*meow_list2_source)(int idx, meow_list_item *out, void *ctx);
/* 创建:视口(x,y,w,h) + 行数 count + 行数据源 + 选中模式。行高默认 56(可用 set_item_h 改)。 */
meow_widget *meow_listview_create(int x, int y, int w, int h, int count,
meow_list2_source src, void *ctx, meow_list_sel mode);
/* 行高(固定;越界/<=0 忽略)。 */
int meow_listview_set_item_h(meow_widget *lv, int item);
/* 行数(搜索过滤/懒加载/目录切换时动态更新):截断 sel 到新范围 + clamp scroll。 */
void meow_listview_set_count(meow_widget *lv, int count);
/* 滚动:set 越界 clamp 到 [0, max_scroll];by 相对滚动(App on_swipe/touch_move 用)。 */
void meow_listview_set_scroll(meow_widget *lv, int offset);
void meow_listview_scroll_by(meow_widget *lv, int dy);
int meow_listview_scroll(meow_widget *lv);
int meow_listview_max_scroll(meow_widget *lv); /* max(0, count*item_h - viewport_h) */
/* 选中集(mode 语义):
* NONE :忽略;SINGLE:set_sel(idx) 设/清(idx<0 清除);MULTI:set_sel(idx) 翻转 idx。
* get_sel 把当前选中下标写入 out[0..max),返回写入数;sel_count 返回选中总数。 */
void meow_listview_set_sel(meow_widget *lv, int idx);
int meow_listview_get_sel(meow_widget *lv, int *out, int max);
int meow_listview_sel_count(meow_widget *lv);
/* 命中:返回行号(含滚动换算;禁用行/越界返回 -1);行右 1/3 = 右侧操作区(另判)。 */
int meow_listview_hit(meow_widget *lv, int x, int y);
int meow_listview_hit_op(meow_widget *lv, int x, int y); /* 1=点在行右 1/3 操作区 */
/* 行点击回调(idx=行号;op:0=行体,1=右侧操作区)。 */
typedef void (*meow_listview_tap_fn)(int idx, int op, void *ctx);
void meow_listview_set_on_tap(meow_widget *lv, meow_listview_tap_fn cb, void *ctx);
/* 命中行:置选中 + 回调(若设)+ 返回 idx;未命中返回 -1。 */
int meow_listview_tap_at(meow_widget *lv, int x, int y);
#ifdef __cplusplus
}
#endif
#endif /* MEOW_UI_WIDGETS_H */