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;工作区无生成物。
126 lines
8.8 KiB
C
126 lines
8.8 KiB
C
/*
|
||
* meow_ui_input.h — SDK 输入层 / 生命周期(§6,B1)+ 通用长按(§6.3,2026-08-31)。
|
||
*
|
||
* 原 meow_ui.h 拆分的一部分(input 模块)。物理键为系统语义(SDK 不下发 on_key 映射为确认/exit),
|
||
* App 只响应触摸/滑动;事件循环阻塞到 meow_ui_request_exit。
|
||
*/
|
||
#ifndef MEOW_UI_INPUT_H
|
||
#define MEOW_UI_INPUT_H
|
||
|
||
#include "meow_ui_types.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/* ============================================================ */
|
||
/* §6 输入层 / 生命周期(B1) */
|
||
/* ============================================================ */
|
||
typedef struct meow_ui_events {
|
||
void (*on_key)(int keycode, int is_down); /* M2.24:物理键为系统语义,SDK 不下发;回调保留(应用不映射键为确认/exit) */
|
||
void (*on_tap)(int x, int y); /* 触摸抬起落点 */
|
||
void (*on_swipe)(int dir, int dx, int dy); /* 左滑=返回(左缘起点+抬手触发) */
|
||
void (*on_tick)(void); /* 空闲周期回调(动画/时钟) */
|
||
void (*on_swipe_progress)(int x_start, int dx);/* 左缘返回手势过程实时回调;x_start=按下X, dx=当前X-按下X */
|
||
/* M2.71-bug2/6:拖动过程回调(跟手)。on_touch_down=按下后首个有效坐标(起点);
|
||
* on_touch_move=拖动中坐标变化(坐标变了才回调)。用于 slider 拖动 / 列表/页面滚动跟手。
|
||
* 均在 IME 弹出或模态阻塞时被吞(键盘/模态优先喂)。可 NULL。 */
|
||
void (*on_touch_down)(int x, int y);
|
||
void (*on_touch_move)(int x, int y);
|
||
} meow_ui_events;
|
||
|
||
void meow_ui_run(const meow_ui_events *ev); /* 阻塞:事件循环,直到 meow_ui_request_exit */
|
||
void meow_ui_request_exit(void); /* 请求退出(相当于返回/退出键) */
|
||
|
||
/* 顶部左滑进度条(视觉反馈):画一条 5px 高、从 x=0 到 x 的横条(主题 accent 色)。
|
||
* x<=0 时清掉此前画的条(填回背景色)。不发 flush,由调用方 meow_ui_flush_region 上屏。 */
|
||
void meow_ui_swipe_hint(int x);
|
||
|
||
/* 批②(2026-09-04):底部热区上滑 → 回桌面(home)判定,镜像 launcher np_gesture.h
|
||
* np_home_gesture 同口径。down_x/down_y=抬手原点,dx/dy=抬手位移(释放-原点),
|
||
* fb_h=屏高(SDK 传 meow_ui_height())。命中=起点在底部热区(最后 HOME_EDGE_H≈28px)且
|
||
* **不在左缘**(down_x>=EDGE_W,与左缘返回互斥)+ 上移 ≥HOME_SWIPE(65px) + 竖向主导(adx<-dy)。
|
||
* 供宿主单测直调;触摸状态机(meow_ui_input.c touch_release)与 App 内判据共用,避免两端漂移。 */
|
||
int meow_ui_input_is_home_swipe(int down_x, int down_y, int dx, int dy, int fb_h);
|
||
|
||
/* ============================================================ */
|
||
/* §6.3 通用长按(2026-08-31) */
|
||
/* ============================================================ */
|
||
/* 控件按下 ≥ 阈值(默认 500ms,可配)未抬手、且按下后位移 ≤ 容忍(超移动/抬手取消)
|
||
* → 触发一次长按回调;坐标 = 触发时刻的按下点(App 据此 meow_widget_hit / meow_listview_hit
|
||
* 判定命中哪个控件/行,与 on_tap 同一套命中流程)。
|
||
*
|
||
* **opt-in**:注册回调(meow_ui_set_long_press_cb)才启用长按判定;未注册时行为与之前完全一致
|
||
* (按压不触发长按、抬手照常 TAP/SWIPE)——hello 等不使用长按的 App 零回归。
|
||
*
|
||
* 与 pressed 状态机共存:按压视觉态(MEOW_WS_PRESSED / 按住加深)不变;短按(未达阈值或
|
||
* 抬手先于阈值)仍正常触发 on_tap 点击;长按已触发后其抬手**不再产生 TAP/SWIPE**(SDK 抑制
|
||
* 点击,App 无需自行吞掉后续 tap)。
|
||
*
|
||
* 注册经独立 set 接口:**不做进 meow_ui_events**——避免给既有 App(hello/files)按位置初始化
|
||
* meow_ui_events 的写法在 -Wextra 下引入「缺省成员」告警(_missing-field-initializers),
|
||
* 保持 SDK 头向后兼容。 */
|
||
typedef void (*meow_long_press_fn)(int x, int y);
|
||
void meow_ui_set_long_press_cb(meow_long_press_fn cb); /* 注册/更换回调;NULL=取消 */
|
||
void meow_ui_set_long_press_ms(int ms); /* 长按阈值(ms);<=0 恢复默认 500 */
|
||
int meow_ui_long_press_ms(void); /* 当前阈值(默认 500) */
|
||
|
||
/* ============================================================ */
|
||
/* §6.4 事件分发形式化(2026-09-02)—— 统一「命中测试 / 捕获 / 消费 / 层间隔离 / 焦点」
|
||
*
|
||
* 背景:此前命中/捕获/消费/层间隔离各处 ad-hoc 补丁(模式层穿透、弹层叠黑、list 焦点残留、
|
||
* 同坐标二次消费)。本节把三层模型的形式化落地为**单一仲裁者**(SDK 内部实现,见
|
||
* devdocs/plan/SDK_VIEW_FRAMEWORK_DESIGN.md §A.7 命中分流 ③②① + 本 SDK 内部拓扑):
|
||
*
|
||
* 触摸沿 z 序**自顶向下**命中:模态层永远先审;某一层命中即消费(返回 consumed 才继续下探)。
|
||
* 某一次 touch-down 命中后,捕获直到 up;期间 move/up 只发给捕获目标(防滑出误触发下层)。
|
||
* 模态层存在时下层**完全收不到**事件——未命中面板的事件由模态背板消费,不透传。
|
||
*
|
||
* 兼容:**只追加、不删改既有签名**;未调用本节 API 的 App 行为与之前完全一致(命中/捕获仍
|
||
* 由 App 在 on_tap/on_touch_* 里自理)。hello/files/ncm/reader 等既有 App 只把 SDK 提供的
|
||
* 语义用于收敛 bug,不改正常交互。
|
||
*/
|
||
/* ---- 模态作用域(modal scope)----
|
||
* 一组自顶向下优先的叠层。dialog/sheet/App 自绘模态在「打开时 begin、关闭时 end」。
|
||
* 作用域存在(meow_ui_modal_active / depth>0)时,下层(view/widget)完全收不到触摸;
|
||
* 未命中面板的事件由背板消费(meow_ui_hit_topdown 恒返回模态哨兵)。支持嵌套(弹层叠开,
|
||
* depth 递增)。begin 返回作用域句柄;end 销栈(幂等,NULL 忽略)。 */
|
||
typedef struct meow_ui_modal meow_ui_modal;
|
||
meow_ui_modal *meow_ui_modal_begin(void); /* 打开模态层入栈;返回句柄(NULL=栈满/上限) */
|
||
void meow_ui_modal_end(meow_ui_modal *m); /* 关闭:弹到 m(含 m,一次性关上嵌套) */
|
||
int meow_ui_modal_active(void); /* 当前是否有任一模态作用域打开(depth>0) */
|
||
int meow_ui_modal_depth(void); /* 模态栈深(弹层叠开计数) */
|
||
|
||
/* ---- 自上而下命中 ---- */
|
||
/* 沿 z 序(模态最高优先,其次注册控件 z 降序;均含 owner==active+enable 过滤)返回第一个
|
||
* 命中绘制物(meow_widget* 或 meow_view*);无命中返回 NULL。模态存在时恒返回模态哨兵
|
||
* (背板消费,不透传)。供 gesture_begin/focus_tap/App 自绘模态命中统一使用。 */
|
||
void *meow_ui_hit_topdown(int x, int y);
|
||
/* meow_widget_hit 的公共别名(owner==active + enable + 矩形/自定义命中回调一致)。 */
|
||
int meow_ui_widget_hit(meow_widget *w, int x, int y);
|
||
|
||
/* ---- 手势捕获(gesture capture)----
|
||
* touch-down 命中目标捕获整个手势直到 up。捕获期 meow_ui_gesture_owner 恒返回捕获目标;
|
||
* 后续 move/up 只发给它(防滑出后误触发下层)。begin 返回捕获目标(未命中=NULL 不捕获);
|
||
* end/抬手释放。 */
|
||
void *meow_ui_gesture_begin(int x, int y); /* 命中+捕获;返回捕获目标(模态存在时=模态哨兵) */
|
||
void *meow_ui_gesture_owner(void); /* 当前手势捕获目标(无=NULL) */
|
||
void meow_ui_gesture_end(void); /* 手势结束(抬手/TAP/SWIPE 边沿):释放捕获 */
|
||
|
||
/* ---- 唯一焦点(focus,root 根治 list 焦点残留 / 滚动容器间转移)----
|
||
* 焦点持有者唯一。点非焦点区域 → 释放焦点并触发 lost 回调;滚动容器(list/scroll)在
|
||
* 获得焦点时 acquire,点外由 meow_ui_focus_tap 统一释放——「命中非 focus 区域 → 释放并通知」。
|
||
* 转移规则:某滚动容器 acquire 后,随后的纵向 swipe / 拖动滚该容器;任何落在该容器外的
|
||
* 触摸(hit != focus owner)释放焦点,回退到页面级滚动。 */
|
||
typedef void (*meow_ui_focus_lost_fn)(void *owner, void *ctx); /* 焦点被释放/转移时回调 */
|
||
void meow_ui_focus_set_lost_cb(meow_ui_focus_lost_fn cb, void *ctx); /* 注册/更换焦点丢失回调 */
|
||
void *meow_ui_focus_owner(void); /* 当前唯一焦点持有者(无=NULL) */
|
||
int meow_ui_focus_acquire(void *owner); /* 设为唯一焦点(覆盖旧焦点并触发其 lost) */
|
||
int meow_ui_focus_release(void *owner); /* owner==当前焦点才释放+通知(NULL=任意) */
|
||
void meow_ui_focus_tap(int x, int y); /* TAP 落点:命中焦点持有者→保位;否则释放+通知 */
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif /* MEOW_UI_INPUT_H */
|