- 返回手势:书库列表排除左缘 24px 系统返回带并清空残留拖拽态;library_go_up 到 TF 根返回 0(app.c 退出 App),不再上溯系统目录;顶栏返回改为显式 library_go_parent(访问放开,可越过 TF 根到 /)。lock 页继续自行消费返回。 - 打开册:缩略图源图改用预算解码(meow_img_load_file_dim,峰值数十 MB→~1MB); 离开书库页停止后台探测/缩略图线程,避免与 open_book 争内存/FD;打开失败按 errno 记日志,ENOMEM/EMFILE/ENFILE/EAGAIN/EINTR 自动重试一次;修 open_book 自拷贝 snprintf 的未定义行为。 - 测试:test_browse_ui_host 增加 TF 根退出/顶栏上级/左缘不拖拽断言;新增 test_open_book_host(封面图+含图子目录的父目录 → reader 打开的完整 UI 链路)。
145 lines
4.6 KiB
C
145 lines
4.6 KiB
C
/* app.c — 图库装配层:main + 建页 + meow_ui_run 回调路由 + 主题监听。
|
||
*
|
||
* 契约(docs/APP_DEV_GUIDE.md §2-§3):
|
||
* - main 只做 meow_ui_init → 建 view → meow_ui_run → 清理;退出走 meow_ui_request_exit;
|
||
* - 页面切换统一走 meow_view_page_push/pop(activity 栈 + on_enter/on_leave 唯一入口);
|
||
* - 物理键不映射返回/确认(on_key 仅日志);屏底上滑由 SDK 系统手势接管,App 不拦截;
|
||
* - 左缘返回:reader/settings=pop;lock 页自行消费;书库逐级上移,
|
||
* **TF 根=退出 App**(系统返回语义,不再上溯系统目录);TF 根以外的上级浏览
|
||
* 走顶栏显式「上级」动作。
|
||
*
|
||
* 主题同步:注册 meow_theme_add_listener;明暗/风格族切换时更新页面底色并整帧 invalidate,
|
||
* 各页 on_draw / SDK 控件下一帧即用新语义色重绘(不缓存颜色)。
|
||
*/
|
||
#include "tuku_internal.h"
|
||
#include "ui/reader/reader.h"
|
||
#include "meow_ui_nav.h"
|
||
|
||
#include <signal.h>
|
||
|
||
static void on_sigterm(int s)
|
||
{
|
||
(void)s;
|
||
meow_ui_request_exit();
|
||
}
|
||
|
||
/* 向 launcher 上报当前页栈深/顶层,供系统导航栈跟随。各页 on_enter 调用。 */
|
||
void mr_nav_report(void)
|
||
{
|
||
int depth = meow_ui_activity_depth();
|
||
if (depth <= 0) depth = 1;
|
||
int id = meow_ui_activity_active();
|
||
const char *top = (id == ACT_READER) ? "reader"
|
||
: (id == ACT_SETTINGS) ? "settings"
|
||
: (id == ACT_LOCK) ? "lock"
|
||
: "library";
|
||
meow_ui_nav_report((uint32_t)depth, top);
|
||
}
|
||
|
||
/* 主题切换:页面底色 + 整帧重绘(控件与 on_draw 全部从 meow_theme_get() 取色)。 */
|
||
static void app_theme_changed(meow_theme_mode m)
|
||
{
|
||
(void)m;
|
||
meow_ui_set_page_bg(meow_theme_get()->bg);
|
||
meow_ui_invalidate(0, 0, meow_ui_width(), meow_ui_height());
|
||
}
|
||
|
||
static int app_active(void)
|
||
{
|
||
return meow_ui_activity_active();
|
||
}
|
||
|
||
static void app_on_key(int keycode, int is_down)
|
||
{
|
||
(void)keycode; (void)is_down; /* 物理键是系统语义,不做返回/确认映射 */
|
||
meow_log(MEOW_LOG_DEBUG, "key");
|
||
}
|
||
|
||
static void app_on_tap(int x, int y)
|
||
{
|
||
switch (app_active()) {
|
||
case ACT_LIBRARY: library_on_tap(x, y); break;
|
||
case ACT_READER: reader_on_tap(x, y); break;
|
||
default: break;
|
||
}
|
||
}
|
||
|
||
static void app_on_swipe(int dir, int dx, int dy)
|
||
{
|
||
(void)dy;
|
||
if (dir == MEOW_SWIPE_LEFT) {
|
||
if (app_active() == ACT_LIBRARY) {
|
||
if (!library_go_up()) {
|
||
meow_log(MEOW_LOG_INFO, "exit:swipe");
|
||
meow_ui_request_exit();
|
||
}
|
||
} else {
|
||
meow_view_page_pop();
|
||
}
|
||
return;
|
||
}
|
||
/* SDK 的 on_swipe 把位移量放在第二参(第三参为 0):UP/DOWN 时 dx=纵向位移。 */
|
||
if (app_active() == ACT_LIBRARY) library_on_swipe(dir, dx);
|
||
}
|
||
|
||
static void app_on_tick(void)
|
||
{
|
||
library_on_tick();
|
||
}
|
||
|
||
static void app_on_swipe_progress(int x_start, int dx)
|
||
{
|
||
meow_ui_swipe_hint(x_start + dx);
|
||
}
|
||
|
||
/* 跟手拖动路由(M6):ACT_READER 需要原始 down/move 算位移;其余页保持原语义。
|
||
* 屏底热区/左缘的避让由 reader 侧按同一口径判断(reader_on_touch_down)。 */
|
||
static void app_on_touch_down(int x, int y)
|
||
{
|
||
if (app_active() == ACT_LIBRARY) library_on_touch_down(x, y);
|
||
else if (app_active() == ACT_READER) reader_on_touch_down(x, y);
|
||
}
|
||
|
||
static void app_on_touch_move(int x, int y)
|
||
{
|
||
if (app_active() == ACT_LIBRARY) library_on_touch_move(x, y);
|
||
else if (app_active() == ACT_READER) reader_on_touch_move(x, y);
|
||
}
|
||
|
||
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(app_theme_changed);
|
||
meow_ui_set_page_bg(meow_theme_get()->bg);
|
||
meow_ui_nav_init();
|
||
signal(SIGTERM, on_sigterm);
|
||
|
||
/* 先建全部页面(on_create 建各自控件/扫描书库),再按启动锁状态进根页。 */
|
||
meow_view *library = library_view_create();
|
||
meow_view *reader = reader_view_create();
|
||
meow_view *settings = settings_view_create();
|
||
meow_view *lock = lock_view_create();
|
||
|
||
meow_view_page_push(lock_view_should_show() ? ACT_LOCK : ACT_LIBRARY);
|
||
|
||
meow_ui_events ev = {
|
||
app_on_key, app_on_tap, app_on_swipe, app_on_tick,
|
||
app_on_swipe_progress, app_on_touch_down, app_on_touch_move,
|
||
};
|
||
meow_ui_run(&ev);
|
||
|
||
meow_view_free(lock);
|
||
meow_view_free(settings);
|
||
meow_view_free(reader);
|
||
meow_view_free(library);
|
||
meow_ui_shutdown();
|
||
meow_log(MEOW_LOG_INFO, "exit");
|
||
return 0;
|
||
}
|