feat(sdk): 通用长按事件 (agent-191, 用户定案) — MEOW_EV_LONG_PRESS 坐标式事件+meow_ui_set_long_press_cb/ms(opt-in,默认500ms,移动>12px取消,长按后抬手抑制TAP/SWIPE); 按钮按住视觉阈值同源; files 长按从App层迁入 SDK
meow_ui.a 4335c33a→6de89c27; hello→72fb20da; files→b1c4f58f 宿主 widgets(含6条长按断言)/p1p2p3/ime_fix/test_fsx 全 PASS; 未改 meow_ui_events 结构(防 -Wmissing-field-initializers 破坏既有App)
This commit is contained in:
1 parent
60072a08f1
commit
e95552b949
14 files changed
+200
-35
No files matched your search
@@ -74,8 +74,10 @@ gcc -O2 -Wall -Wextra -DFSX_SD_ROOT='"/tmp/meowfsx_fsx_test"' -Ilogic \
|
||||
(行数据源 `browser_src2` 填 `meow_list_item`)。图标(目录/文件内置符号)、名称、大小/时间副标题、
|
||||
右侧 `⋯` 操作钮、虚拟化、空态/页脚、禁用行不响应均由 SDK 收口;`fsx_scan_dir` 仍以有界数组缓存
|
||||
(`FSX_MAX_ENTRIES=1024`),列表虚拟化只画可见行——大目录不一次全读进内存。
|
||||
- **long-press 由 App 层保持**:SDK listview 无内建长按;`browser_tick` 的「按下→≥500ms 未拖动→
|
||||
BottomSheet」逻辑不依赖控件渲染,保留在 App 层(触摸命中用 `meow_listview_hit` 行号)。
|
||||
- **long-press 已下沉 SDK(§6.3)**:SDK 通用长按判定「按下 ≥ 阈值(默认 500ms,可配)未抬手且
|
||||
位移 ≤ 容忍」→ 经 `meow_ui_set_long_press_cb` 注册的回调带坐标交给本页;`browser_on_long_press`
|
||||
用 `meow_listview_hit` 行命中打开 BottomSheet。App 层长按计时(`browser_tick`/`g_press_ms`)已删除,
|
||||
其抬手 TAP 由 SDK 抑制(长按不再触发点击)。
|
||||
2. **中文字形**:SDK 默认 `common` 字库(≈4k)不含 CJK 全量;exFAT 中文文件名/中文文本预览在 common 档会显示缺字豆腐。
|
||||
预览页不声明 `fonts`(app.json 未加 `"fonts":"full"`/`"gbk"`),如需中文预览可在 app.json 声明大字号档。
|
||||
3. **预览仅文本**:按扩展名白名单 + 首 512 字节 NUL 嗅探判文本;二进制/图片无预览(提示「not a text file」)。
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/* app.c — files 应用装配层:main + 组装 + 事件分发。
|
||||
*
|
||||
* 职责(对齐 hello_app/app.c):main 只做初始化/建页/跑事件循环/清理;把 meow_ui_run 的平铺输入
|
||||
* 回调(key/tap/swipe/tick/touch)路由到当前活动页(browser/viewer)。页面切换统一走
|
||||
* 回调(key/tap/swipe/tick/touch)路由到当前活动页(browser/viewer);通用长按走独立注册
|
||||
* (meow_ui_set_long_press_cb,§6.3)路由到 browser。页面切换统一走
|
||||
* meow_view_page_push/pop(活动栈 + on_enter/on_leave 唯一驱动)。
|
||||
*
|
||||
* 铁律(APPS.md §3.4.1 / WORK_STATE.md):物理键禁映射——不处理任何 key 语义;返回=左缘左滑
|
||||
@@ -66,12 +67,16 @@ static void app_on_touch_move(int x, int y)
|
||||
else if (browser_is_active()) browser_touch_move(x, y);
|
||||
}
|
||||
|
||||
/* on_tick:长按检测(browser 页)。 */
|
||||
static void app_on_tick(void)
|
||||
/* 通用长按(§6.3):SDK 判定「按下 ≥ 阈值未抬手且位移 ≤ 容忍」后带坐标回调;
|
||||
* browser 据此行命中打开 BottomSheet。viewer 无长按语义。 */
|
||||
static void app_on_long_press(int x, int y)
|
||||
{
|
||||
if (browser_is_active()) browser_tick(meow_ui_time_ms());
|
||||
if (browser_is_active()) browser_on_long_press(x, y);
|
||||
}
|
||||
|
||||
/* on_tick:本 App 无帧动画/时钟(长按计时已下沉 SDK §6.3),保留为空槽。 */
|
||||
static void app_on_tick(void) { }
|
||||
|
||||
/* ============================================================ */
|
||||
/* main */
|
||||
/* ============================================================ */
|
||||
@@ -95,6 +100,8 @@ int main(void)
|
||||
app_on_key, app_on_tap, app_on_swipe, app_on_tick, app_on_swipe_progress,
|
||||
app_on_touch_down, app_on_touch_move,
|
||||
};
|
||||
/* 通用长按走独立注册(§6.3):不进 meow_ui_events(避免位置初始化在 -Wextra 下告警)。 */
|
||||
meow_ui_set_long_press_cb(app_on_long_press);
|
||||
meow_ui_run(&ev);
|
||||
|
||||
/* 清理:meow_view_free 触发各页 on_destroy(控件 + 文本缓冲) */
|
||||
|
||||
Binary file not shown.
@@ -54,7 +54,7 @@ int browser_on_tap(int x, int y); /* 1=已消费 */
|
||||
void browser_swipe(int dir, int dist);
|
||||
void browser_touch_down(int x, int y);
|
||||
void browser_touch_move(int x, int y);
|
||||
void browser_tick(uint64_t now);
|
||||
void browser_on_long_press(int x, int y); /* SDK 通用长按(§6.3)→ 行 BottomSheet */
|
||||
int browser_go_up(void); /* 1=回到上级;0=已在根(未动作) */
|
||||
int browser_at_root(void);
|
||||
void browser_reload(void);
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
* 「图标 + 名称 + 大小/时间 + 右侧 ⋯ 操作钮」行:行数据源 browser_src2 逐行填充
|
||||
* meow_list_item(icon_kind=目录/文件符号、副标题=大小/时间、right=⋯)。滚动/选中命中由
|
||||
* SDK 收口(视口裁剪、局部 dirty、disabled 不响应),App 只在 on_tap/touch_move 驱动
|
||||
* scroll/sel 并分发:行体=进目录/开预览;右侧 ⋯ 或长按 → BottomSheet(删除/重命名/新建/属性);
|
||||
* scroll/sel 并分发:行体=进目录/开预览;右侧 ⋯ → BottomSheet;**长按=SDK 通用长按事件
|
||||
* (§6.3,≥500ms 未抬手且位移≤容忍)** 由 SDK 判定后经 on_long_press 回调带坐标交给本页,
|
||||
* App 据此行命中打开同一 BottomSheet(App 层长按计时逻辑已删,交给 SDK);
|
||||
* - 空态/错误(无卡/空目录/权限)与底部信息行用 meow_draw_custom_register 注册为非控件绘制物
|
||||
* (app_draw_empty / app_draw_footer)——列表视口不含页脚,行不压页脚;invalidate/paint_full
|
||||
* 自动重画它们;
|
||||
@@ -28,10 +30,8 @@ static fsx_entry g_entries[FSX_MAX_ENTRIES];
|
||||
static int g_n; /* 当前目录项数 */
|
||||
static char g_cur[FSX_MAX_PATH];
|
||||
static int g_err; /* fsx_scan_dir 返回(0=ok,<0=空态码) */
|
||||
static int g_press_row; /* 按下行(-1=无);长按检测 */
|
||||
static uint64_t g_press_ms;
|
||||
static int g_press_tapped; /* 长按已消费本按 */
|
||||
static int g_press_delta; /* 按下后累计位移(>阈值取消长按) */
|
||||
static int g_press_row; /* 按下行(-1=无);按下高亮 + 拖动识别(长按已交 SDK §6.3) */
|
||||
static int g_press_delta; /* 按下后累计位移(>阈值清除按下高亮) */
|
||||
static int g_dragging; /* 本次触摸起点是否在列表(拖动滚列表) */
|
||||
static int g_drag_last_y; /* 拖拽上一帧 y */
|
||||
|
||||
@@ -45,6 +45,7 @@ static char g_title[FSX_MAX_PATH];
|
||||
|
||||
/* 预览/操作辅助(前向声明) */
|
||||
static void browser_open_sheet(int row);
|
||||
void browser_on_long_press(int x, int y); /* 跨 TU(app.c 经 §6.3 回调调用);files_internal.h */
|
||||
static void browser_enter_dir(const char *path);
|
||||
static void browser_open_file(const char *path);
|
||||
static void browser_rename_entry(const fsx_entry *e);
|
||||
@@ -57,7 +58,6 @@ static void browser_report_ret(int r);
|
||||
static void browser_drag_reset(void)
|
||||
{
|
||||
g_press_row = -1;
|
||||
g_press_tapped = 0;
|
||||
g_press_delta = 0;
|
||||
g_dragging = 0;
|
||||
g_drag_last_y = 0;
|
||||
@@ -312,7 +312,6 @@ static void browser_open_file(const char *path)
|
||||
|
||||
int browser_on_tap(int x, int y)
|
||||
{
|
||||
if (g_press_tapped) { browser_drag_reset(); return 1; }
|
||||
if (g_tb) {
|
||||
int ah = meow_topappbar_hit(g_tb, x, y);
|
||||
if (ah == MEOW_TOPBAR_BACK) { browser_drag_reset(); browser_go_up(); return 1; }
|
||||
@@ -344,7 +343,6 @@ void browser_touch_down(int x, int y)
|
||||
int row = meow_listview_hit(g_list, x, y);
|
||||
if (row >= 0) {
|
||||
g_press_row = row;
|
||||
g_press_ms = meow_ui_time_ms();
|
||||
meow_listview_set_sel(g_list, row); /* 按下高亮(§5.8.3 selected) */
|
||||
}
|
||||
g_dragging = 1;
|
||||
@@ -357,13 +355,13 @@ void browser_touch_move(int x, int y)
|
||||
{
|
||||
(void)x;
|
||||
if (!g_dragging) return;
|
||||
if (g_press_row >= 0) { /* 拖动取消长按 */
|
||||
if (g_press_row >= 0) { /* 拖动超阈值:清除按下高亮 */
|
||||
int d = y - g_drag_last_y;
|
||||
if (d < 0) d = -d;
|
||||
if (d > 0) g_press_delta += d;
|
||||
g_press_delta += d;
|
||||
if (g_press_delta > 10) {
|
||||
g_press_row = -1;
|
||||
meow_listview_set_sel(g_list, -1); /* 拖动取消按下高亮 */
|
||||
meow_listview_set_sel(g_list, -1); /* 拖动清除按下高亮 */
|
||||
}
|
||||
}
|
||||
int dy = y - g_drag_last_y;
|
||||
@@ -386,15 +384,19 @@ void browser_swipe(int dir, int dist)
|
||||
meow_ui_invalidate(r_list.x, r_list.y, r_list.w, r_list.h);
|
||||
}
|
||||
|
||||
/* on_tick:长按(≥500ms 未拖动)→ 打开该行 BottomSheet。 */
|
||||
void browser_tick(uint64_t now)
|
||||
/* SDK 通用长按(§6.3,≥阈值未抬手且位移≤容忍)→ 打开该行 BottomSheet。
|
||||
* App 层长按计时已删(g_press_ms/g_press_tapped 移除);长按触发后 SDK 已抑制其抬手
|
||||
* TAP(不再触发行体/打开动作),故这里无需再吞后续 tap;打开前清按下高亮与拖动态。 */
|
||||
void browser_on_long_press(int x, int y)
|
||||
{
|
||||
if (g_press_row >= 0 && !g_press_tapped && now - g_press_ms >= 500) {
|
||||
g_press_tapped = 1;
|
||||
int row = g_press_row;
|
||||
g_press_row = -1;
|
||||
browser_open_sheet(row); /* 内部:写操作后自行 reload */
|
||||
}
|
||||
if (g_err != 0 || g_n == 0) return;
|
||||
if (!meow_widget_hit(g_list, x, y)) return;
|
||||
int row = meow_listview_hit(g_list, x, y);
|
||||
if (row < 0) return;
|
||||
g_press_row = -1;
|
||||
g_dragging = 0;
|
||||
meow_listview_set_sel(g_list, -1); /* 清除按下高亮(sheet 打开在即) */
|
||||
browser_open_sheet(row); /* 内部:写操作后自行 reload */
|
||||
}
|
||||
|
||||
/* ---- 页 view 生命周期 ---- */
|
||||
|
||||
Reference in new issue
Block a user