feat(tuku): 图库 M3 骨架——书库浏览/主题同步/阅读器与锁屏接缝

- 新增顶层 tuku/ 工程(package dev.tuku.app、二进制 tuku):app.c/internal 头/logic/ui 分层、app.json、build/pack 脚本
- 书库:从 TF 卡根浏览文件夹,含图目录=一本书;logic/library 纯 C 扫描+自然排序(page2<page10)
- 流式缩略图:后台线程解码+meow_img_downscale(96),首帧/滚动不阻塞;磁盘缓存 MeowData/<pkg>/cache(mtime 失效+LRU)
- 列表 meow_listview 虚拟化 + meow_scroll fling/snap;行=缩略图+目录名+页数
- 主题:全部语义色 + meow_theme_add_listener 即时重绘;明暗/风格族两态可读
- 导航:meow_view page push/pop、TopAppBar ⚙→设置;reader/settings/lock 最小桩
- 接缝:mr_reader_get/set_direction(默认 RTL)、lock_view_should_show()(桩 0)
- 宿主 gcc 测试 46 项 PASS;交叉构建静态 MIPS32r2 ELF、-Wall -Wextra 零警告
This commit is contained in:
AskaEth committed 2026-11-04 19:44:18 +08:00
1 parent c0396e40ce
commit bed6a95485
17 files changed
+1676

No files matched your search

+137
View File
@@ -0,0 +1,137 @@
/* 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 不拦截;
* - 左缘返回:书库内逐级上移,根目录才退出。
*
* 主题同步:注册 meow_theme_add_listener;明暗/风格族切换时更新页面底色并整帧 invalidate,
* 各页 on_draw / SDK 控件下一帧即用新语义色重绘(不缓存颜色)。
*/
#include "tuku_internal.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);
}
static void app_on_touch_down(int x, int y)
{
if (app_active() == ACT_LIBRARY) library_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);
}
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;
}