Files
MeowOS-SDK/tuku/app.c
T
AskaEth 3cbcaaaac1 图库: 修系统返回语义与打开册资源路径(M15)
- 返回手势:书库列表排除左缘 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 链路)。
2026-11-05 13:03:20 +08:00

145 lines
4.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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;
}