- folder 模式从「按第一级目录分段」改为当前目录视图:子目录在前(带子树书数), 直接书在后;进入/返回只过滤已扫平的 g_books,不 readdir、不重扫(M32 索引不动)。 - 纯函数 shelf_build_rows_at(books,n,folder,cwd,...) + nav 工具(enter/up/breadcrumb/ count)全部宿主可测;format 模式行序列/副题逐字不变,path 仍是完整路径(进度键不变)。 - 交互:点目录进入;顶栏返回箭头/左缘返回手势回上一级,根层再返回退出 App;顶栏标题= 当前目录名(按像素宽截断),副题行=面包屑全路径+当前层书数;list/grid 均支持导航。 - 状态:folder↔format、list↔grid 切换保留 cwd;刷新重扫后 cwd 失效则收缩到有书的祖先。 - 边界:空目录不显示(导航只读 g_books,不额外 readdir);深层目录逐级进入;真实名为 「未分类」的目录按普通目录处理,不与根层书合并。 - 测试:shelf_group_smoke 63→99 断言;M27 的按第一级分组断言改写为「逐级进入后可见该书」 (同等强度),新增进入/返回/面包屑/计数/空目录/纯内存/rowcap/UTF-8 截断断言。 - 交付 0.1.7/code8(M32 已占用任务书里的 0.1.6/code7);真机 0.1.4 未被覆盖。
89 lines
3.0 KiB
C
89 lines
3.0 KiB
C
/* app.c — os.meow.reader 应用装配层:main + 初始化 + 事件分发。
|
||
*
|
||
* 职责(SDK_VIEW_FRAMEWORK_DESIGN.md §B.2):main 只做 init/建页/跑事件循环/清理;把
|
||
* meow_ui_run 的平铺输入回调(key/tap/swipe/tick/touch)路由到当前活动页(shelf/reader)。
|
||
* 页面切换走 meow_view_page_push/pop(on_enter/on_leave 唯一入口)。
|
||
*/
|
||
#include "reader_internal.h"
|
||
#include "meow_ui_internal.h" /* 阅读页 blit 需要 back_buf 访问器(决策见报告) */
|
||
#include "app/reader_ipc.h"
|
||
#include <signal.h>
|
||
|
||
static meow_view *g_shelf_view;
|
||
static meow_view *g_reader_view;
|
||
static meow_view *g_settings_view;
|
||
|
||
static void on_sigterm(int s) { (void)s; meow_ui_request_exit(); }
|
||
|
||
static void app_on_key(int keycode, int is_down) { (void)keycode; (void)is_down; }
|
||
|
||
static void app_on_tap(int x, int y)
|
||
{
|
||
if (settings_is_active()) { settings_on_tap(x, y); return; }
|
||
if (reader_is_active()) { reader_on_tap(x, y); return; }
|
||
shelf_on_tap(x, y);
|
||
}
|
||
|
||
static void app_on_swipe(int dir, int dx, int dy)
|
||
{
|
||
(void)dy; (void)dx;
|
||
if (settings_is_active()) { return; } /* 设置页滑动不翻页 */
|
||
if (reader_is_active()) { reader_on_swipe(dir, dx, dy); return; }
|
||
if (shelf_is_active()) {
|
||
/* 书架根页左缘右滑(返回手势):
|
||
* folder 模式且不在 Books 根 → 回上一级目录(M33);
|
||
* 已在根 / format 模式 → 退出 App(与既有行为一致)。 */
|
||
if (dir == MEOW_SWIPE_LEFT) {
|
||
if (shelf_back()) return;
|
||
meow_ui_request_exit();
|
||
return;
|
||
}
|
||
shelf_on_swipe(dir, dx, dy); return;
|
||
}
|
||
if (dir == MEOW_SWIPE_LEFT) { meow_ui_request_exit(); }
|
||
}
|
||
|
||
static void app_on_tick(void)
|
||
{
|
||
uint64_t now = meow_ui_time_ms();
|
||
if (reader_is_active()) { reader_on_tick(now); return; }
|
||
if (shelf_is_active()) { shelf_on_tick(now); return; }
|
||
}
|
||
|
||
static void app_on_touch_down(int x, int y)
|
||
{
|
||
if (reader_is_active()) { reader_on_touch_down(x, y); return; }
|
||
}
|
||
static void app_on_touch_move(int x, int y)
|
||
{
|
||
if (reader_is_active()) { reader_on_touch_move(x, y); return; }
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
meow_log(MEOW_LOG_INFO, "start");
|
||
meow_ui_opts o = { 480, 720 };
|
||
if (meow_ui_init(&o) != 0) { meow_log(MEOW_LOG_ERROR, "init failed"); return 1; }
|
||
meow_theme_add_listener(NULL);
|
||
signal(SIGTERM, on_sigterm);
|
||
|
||
g_shelf_view = shelf_view_create();
|
||
g_reader_view = reader_view_create();
|
||
g_settings_view = settings_view_create();
|
||
|
||
meow_view_page_push(ACT_SHELF);
|
||
reader_ipc_start(); /* E:系统翻页信号接收(后台线程,best-effort) */
|
||
|
||
meow_ui_events ev = { app_on_key, app_on_tap, app_on_swipe, app_on_tick,
|
||
NULL, app_on_touch_down, app_on_touch_move };
|
||
meow_ui_run(&ev);
|
||
|
||
reader_ipc_stop();
|
||
meow_view_free(g_settings_view);
|
||
meow_view_free(g_reader_view);
|
||
meow_view_free(g_shelf_view);
|
||
meow_ui_shutdown();
|
||
meow_log(MEOW_LOG_INFO, "exit");
|
||
return 0;
|
||
}
|