sdk/: - 同步 meow_ui_widget/input/gfx/lazygrid/audio/media/img 等源码与头 (SDK 默认列表/容器控件默认 MD3 — meow_list_set_container 可回退; 全局 App 内底部上滑回桌面 — meow_ui_input_is_home_swipe 系统保留手势; LazyGrid/LazyColumn/LazyRow MD3 化;叠加让位自抑改 app_id 判定; DSD 音频格式等) - 新增独立模块源码 meow_img_color / meow_lyric / meow_lyric_view 及对应宿主 test_*.c - 保留公开仓自包含适配:vendored meow_font.c/meow_font.h/meow_notif.h 不动; build_sdk.sh 自包含版本不动;meow_ui_gfx.c 仅改 meow_font.h include 路径; meow_ui_internal.h 去除 FreeType 内部声明 - meow_ipc.h 同步到主仓 launcher 版本(含 AUDIO_FMT_DOP/媒体歌词/蓝牙输出协议) - 不含 FreeType 矢量字 meow_ft_*(需 freetype vendor,公开仓以位图 meow_font 自包含);不含 mipsel 二进制 / .o / .a / 固件 / 密钥 / devdocs examples/hello/: - 新增 ui/demo/sdk2/sdk2.c;build_hello.sh 纳入该文件(保持自包含) docs / README / .gitignore: - docs/MEOW_APP_SDK.md 补 §12.5(默认 MD3 容器 + 底部上滑回桌面 + 两个新 API) - README 能力清单补「默认 MD3 容器」与「底部上滑回桌面」 - .gitignore 补新增宿主测试二进制 验证:sdk/meow_ui.a 与 examples/hello/hello 交叉编译均 0 warning;工作区无生成物。
433 lines
29 KiB
C
433 lines
29 KiB
C
/*
|
||
* 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); /* 点是否落在控件内 */
|
||
/* 写控件矩形(§12.1 meow_box 布局引擎用;也可供 app 布局器用)。只设字段不标脏。 */
|
||
void meow_widget_set_rect(meow_widget *w, int x, int y, int wd, int ht);
|
||
|
||
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=描边宽;
|
||
* 控件语义:W_PROGRESS 用 bg=轨道(0=surfaceVariant)、fg=填充(0=primary);见 meow_ui_widget.c 批5b;
|
||
* 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=成功 */
|
||
|
||
/* ---- MD3 shape 层级(§5.8.6,Material You 圆角体系,单位 px)----
|
||
* 组件按角色落到五档 + 胶囊:按钮=full(全高一半)、对话框=extra-large(28)、卡=large(16)、
|
||
* 输入框=small(8)、勾选=extrasmall(4)。theme.radius/radius_card 为风格族默认;App 可经
|
||
* opts.radius 逐控件覆盖。全高一半用 MEOW_SHAPE_FULL(h) 宏(控件的胶囊圆角)。 */
|
||
#define MEOW_SHAPE_EXTRASMALL 4 /* 勾选 Checkbox/Radio */
|
||
#define MEOW_SHAPE_SMALL 8 /* 输入框 TextField */
|
||
#define MEOW_SHAPE_MEDIUM 12 /* 主题默认 radius(列表卡/通用控件) */
|
||
#define MEOW_SHAPE_LARGE 16 /* 卡片/容器(theme.radius_card 默认) */
|
||
#define MEOW_SHAPE_EXTRA_LARGE 28 /* 对话框 Dialog(MD3 标准 extra-large) */
|
||
#define MEOW_SHAPE_FULL(h) ((h) / 2) /* 全形=胶囊(按钮/导航等) */
|
||
|
||
/* ---- 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=无 */
|
||
/* TopAppBar 位图动作图标(sb_icons[],Material Symbols Rounded 32x32 单通道 alpha,Apache-2.0)。
|
||
* 动作项默认文本(add_action);经本 API 把某项改成位图:绘制取主题 onSurface(按压淡色),
|
||
* 与状态栏同源 blit(ink 垂直对齐栏中点)。返回 0=成功;NULL/非 topbar/越界 idx/非法 icon=负值。 */
|
||
int meow_topappbar_set_item_icon(meow_widget *w, int idx, int icon_idx);
|
||
/* 位图动作图标索引(= sb_icons[] 下标,与 SDK sb_icons.h 的 SB_I_* 同值)。
|
||
* 状态栏占用 0-14(不动);动作图标从 15 起连续追加,勿改序(须与 sb_icons.h 表序一致)。 */
|
||
enum {
|
||
MEOW_ICON_SETTINGS = 15,
|
||
MEOW_ICON_REFRESH = 16,
|
||
MEOW_ICON_SEARCH = 17,
|
||
MEOW_ICON_PLAY_ARROW = 18,
|
||
MEOW_ICON_PAUSE = 19,
|
||
MEOW_ICON_SKIP_NEXT = 20,
|
||
MEOW_ICON_SKIP_PREV = 21,
|
||
MEOW_ICON_ARROW_BACK = 22,
|
||
MEOW_ICON_CLOSE = 23,
|
||
MEOW_ICON_ADD = 24,
|
||
MEOW_ICON_CHECK = 25,
|
||
MEOW_ICON_LYRICS = 26,
|
||
MEOW_ICON_QUEUE_MUSIC = 27,
|
||
MEOW_ICON_DOWNLOAD = 28,
|
||
MEOW_ICON_HEART = 29,
|
||
};
|
||
|
||
/* ---- IconButton(圆形/位图图标按钮,M7.0a 缺口#2)----
|
||
* 圆形命中 + 位图图标(sb_icons[],Material Symbols Rounded 单通道 alpha)+ 按压态(实时)。
|
||
* 用途:电源菜单圆钮 / Now Playing 播放控制 / 锁屏常用件等「位图图标 + 圆形」按钮。
|
||
* icon_idx = sb_icons[] 下标(用上面 MEOW_ICON_* 枚举或 SB_I_*;越界画空位图,命中照常)。
|
||
* size = 按钮直径(外接正方形 w=h=size;图标 ink 高 = size*6/10,MD3 图标比)。
|
||
* 语义色:底 surfaceContainerLow、图标 onSurface;按压叠 onSurface 状态层(实时,同 meow_btn);
|
||
* 禁用变淡;选中态 primaryContainer/onPrimaryContainer(meow_widget_set_selected)。
|
||
* 命中:圆形(半径=size/2,圆心=按钮中心),owner==active + enabled 双闸门。
|
||
* 返回按钮句柄;App 在 on_tap 里用 meow_widget_hit 判定是否命中本钮(命中即触发动作)。 */
|
||
meow_widget *meow_iconbtn_create(int x, int y, int size, int icon_idx);
|
||
|
||
/* ---- 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 */
|
||
/* MD3 容器模式(W_LIST 共用,§5.5/§5.8.6):0=扁平满宽项+分隔线(回退);1=每项外套 surfaceContainer
|
||
* 圆角卡+项间空隙(去分隔线),选中=primaryContainer/按压=primary α26(卡内 tonal)。
|
||
* 覆盖 meow_list_create / meow_lazycolumn_create / meow_lazyrow_create。返回 0=成功;无效=负值。 */
|
||
int meow_list_set_container(meow_widget *w, int on);
|
||
|
||
/* ============================================================ */
|
||
/* §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);
|
||
|
||
/* ============================================================ */
|
||
/* §5.5 虚拟化列表(W_LISTVIEW 扩展层,2026-09-02):固定 item 池 + 多行富 item + 完全自绘
|
||
* ------------------------------------------------------------
|
||
* 在既有 W_LISTVIEW(src2 每帧按需取行,行为不变)之上做**虚拟化层**(API 追加式,旧 API 保留):
|
||
* - 数据源:count_fn() 返回总行数(任意长度,≥65535 不常驻 item 对象);
|
||
* bind_fn(index, item, ctx) 仅在行「进入视口」(绑定到固定池槽)时调用一次;
|
||
* - 固定 item 池:池容量 = 视口行数 + 2 静态槽(有界,见实现 MEOW_LV_POOL_MAX);
|
||
* 行离开视口不销毁,回滚不重绑(同一 index 命中同一槽 → bind 不重调);
|
||
* - 滚动只改 viewport 偏移(复用既有 set_scroll/max_scroll),不重绑未进视口的项;
|
||
* - 多行富 item:主标题+副标题(第二行小字)+左图标/缩略图+右尾件(chevron/开关/复选/⋯);
|
||
* 行高可配(set_item_h 精确 px / set_item_tier 单/双行档位默认高);
|
||
* - 默认 renderer 用主题语义色绘制富 item;App 也可经 set_item_draw 完全自绘。
|
||
* 段头:bind 回调把 item->section=1(title=段名)→ 段头占位行(非粘性),默认 renderer 特殊绘制。
|
||
* 空态:set_empty_text 设置文案,count==0 时视口内居中画出。
|
||
* 兼容:既有 meow_listview_*(src2 模式)全部保留不动;本层为叠加,src2==NULL 时走既有路径。 */
|
||
|
||
/* 虚拟化行 item(bind 回调填充;SDK 固定池持有;不常驻 src2 那样的全量行对象)。 */
|
||
typedef struct meow_lv_item {
|
||
const char *title; /* 主标题(必填,NULL 视为空行) */
|
||
const char *subtitle; /* 副标题(第二行小字),可空 */
|
||
const meow_img *icon; /* 可选:左图标/缩略图(icon_kind==MEOW_LIST_ICON_IMG 时用) */
|
||
int icon_kind; /* MEOW_LIST_ICON_*(NONE=无图标) */
|
||
int right; /* MEOW_LIST_RIGHT_* 右尾件 */
|
||
int on; /* right==SWITCH 时开关态(0/1) */
|
||
int enabled; /* 1=可交互;0=变淡不响应 */
|
||
int section; /* 1=段头占位行(title=段名;默认 renderer 特殊绘制,非粘性) */
|
||
void *user; /* App 私有(跨 bind 保存业务态/图/index;SDK 不碰) */
|
||
} meow_lv_item;
|
||
|
||
/* 虚拟化数据源:count 返回当前行数(>=0,任意长);bind 在行进入视口时被调一次填充 item。
|
||
* 二者均不常驻 item 对象;count 每帧实时查(支持搜索过滤/懒加载动态长度)。 */
|
||
typedef int (*meow_listview_count_fn)(void *ctx);
|
||
typedef void (*meow_listview_bind_fn)(int index, meow_lv_item *item, void *ctx);
|
||
|
||
/* 完全自绘回调(覆盖默认 renderer):idx=行号;x,y,w,h=行视口矩形(已裁剪到列表视口);
|
||
* state=MEOW_LISTVIEW_ST_* 状态位(选中/按压/禁用组合)。App 用 §3 绘制 API 自绘整行。 */
|
||
typedef void (*meow_listview_draw_fn)(int idx, int x, int y, int w, int h,
|
||
int state, void *ctx);
|
||
/* state 位(set_item_draw 的 draw 回调收到;选中/按压/禁用组合,供自绘整行)。 */
|
||
#define MEOW_LISTVIEW_ST_SELECTED (1u<<0)
|
||
#define MEOW_LISTVIEW_ST_PRESSED (1u<<1)
|
||
#define MEOW_LISTVIEW_ST_DISABLED (1u<<2)
|
||
|
||
/* 挂虚拟化数据源:切到 pool 模式(count_fn/bind_fn 均非 NULL 才生效;否则回退 src2 模式)。
|
||
* 返回 0=成功;NULL 回调/无效=负值。挂虚拟源后既有 sel/滚动/命中/焦点照常。 */
|
||
int meow_listview_set_vsource(meow_widget *lv, meow_listview_count_fn count,
|
||
meow_listview_bind_fn bind, void *ctx);
|
||
/* 默认 renderer 配置:lines=1/2(单行/双行档位,影响副标题显示与行高默认);
|
||
* show_icon=1 画左图标/缩略图;show_right=1 画右尾件。返回 0=成功。 */
|
||
int meow_listview_set_item_renderer(meow_widget *lv, int lines, int show_icon,
|
||
int show_right);
|
||
/* 行档位默认行高:lines=1→48(单行)、2→56(双行);与 set_item_h(精确 px)互补。 */
|
||
int meow_listview_set_item_tier(meow_widget *lv, int lines);
|
||
/* 完全自绘:设 draw_item 回调(覆盖默认 renderer);NULL=用默认 renderer。返回 0=成功。 */
|
||
int meow_listview_set_item_draw(meow_widget *lv, meow_listview_draw_fn draw,
|
||
void *ctx);
|
||
/* MD3 容器模式(默认 renderer 可选,P0 对齐):0=扁平满宽行+分隔线(默认,兼容);
|
||
* 1=每行外套 surfaceContainer 圆角卡(12dp)+行间空隙,选中=primaryContainer/按压=primary α
|
||
* (tonal,非满幅实心),去冗余分隔线;段头=surface 上的 primary 段标签(无卡无分隔线)。
|
||
* 注意:仅对默认 renderer(未 set_item_draw)生效;完全自绘行由 App self-draw 自理。 */
|
||
int meow_listview_set_container(meow_widget *lv, int on);
|
||
/* 空态占位:count==0 时视口内居中画 empty_text(NULL 不画)。返回 0=成功。 */
|
||
int meow_listview_set_empty_text(meow_widget *lv, const char *text);
|
||
|
||
/* ============================================================ */
|
||
/* §5.5 左滑删除(M7.3 通知中心缺口 #9):列表行横向手势 + 删除/回弹动画 */
|
||
/* ------------------------------------------------------------
|
||
* 行自绘 set_item_draw 配合(SDK 在自绘行前把该行横向偏移 swipe_dx 传给 x,并画右露删除区)。
|
||
* 手势由 App 在 on_touch_move 喂三级:begin(touch-down)/ move(touch-move)/ end(release)。
|
||
* 判定:横向小位移|dx|>|dy| 且超容差=swipe(move 返回 1=本列表消费,App 勿滚动);纵向
|
||
* |dy|>|dx| 且超容差=滚动手势优先(返回 0 并取消本行 swipe,App 照常 scroll_by);点按
|
||
* 无位移(end 时未 started)=行点击(返回 0,App 照常 tap_at)。不修改 tap_at/滚动语义。
|
||
* 动画:超阈值 → 删除动画(行滑出 meow_anim,结束后回调 on_delete(idx));未超 → 回弹。
|
||
* 颜色:删除区用主题 error/onError;不与行点击/滚动冲突(见判定表)。 */
|
||
typedef void (*meow_listview_swipe_fn)(int idx, void *ctx);
|
||
void meow_listview_set_swipe_delete(meow_widget *lv, int enabled,
|
||
meow_listview_swipe_fn on_delete, void *ctx);
|
||
int meow_listview_swipe_begin(meow_widget *lv, int x, int y); /* touch-down:1=命中可滑行(喂后续 move) */
|
||
int meow_listview_swipe_move(meow_widget *lv, int x, int y); /* touch-move:1=消费(横向);0=让位(取消/纵向) */
|
||
int meow_listview_swipe_end(meow_widget *lv, int x, int y); /* release:1=消费(删/回弹动画);0=未滑动(tap) */
|
||
int meow_listview_swipe_active(meow_widget *lv); /* 1=有行处于滑动/动画中 */
|
||
int meow_listview_swipe_offset(meow_widget *lv); /* 当前滑动行的 dx(<0=左移;自绘行画用) */
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif /* MEOW_UI_WIDGETS_H */
|