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

+63
View File
@@ -0,0 +1,63 @@
/* logic/library.h — 漫画书库扫描/排序(纯 C,不依赖 meow_ui.h)。
*
* 分层契约同 examples/hello:logic 层只含文件系统与纯数据,宿主 gcc 可直接裸测。
* 书库语义:
* - 从 TF 卡根(MR_ROOT_DIR)起列「直接子目录」;
* - 只保留自身含 PNG/JPEG/BMP 的目录,或子树中最终含图的中间目录(可继续导航);
* - 行的 pages=该目录直接图片数;subdirs=其下含图子目录数(中间目录用于副标题);
* - cover=缩略图源文件:优先该目录自然序第一张图,否则取第一个含图子目录的 cover;
* - 条目按名称自然排序(page2 < page10),含前导零与数字/字母混合名。
*
* 深度上限 MR_LIB_MAX_DEPTH 用于防止坏卡/超大树的无限递归;隐藏目录与系统目录
* (. 开头、MeowAPPs/MeowData/MeowOS/lost+found)不参与书库。符号链接跳过(防环)。
*/
#ifndef MR_LIBRARY_H
#define MR_LIBRARY_H
#ifdef __cplusplus
extern "C" {
#endif
#define MR_PATH_MAX 512
#define MR_NAME_MAX 256
#define MR_LIB_MAX_DEPTH 8
typedef struct mr_library_entry {
char name[MR_NAME_MAX]; /* 目录名(行主标题) */
char path[MR_PATH_MAX]; /* 完整路径(导航/进 reader 用) */
char cover[MR_PATH_MAX]; /* 缩略图源图(空=none) */
char subtitle[48]; /* 预先格式化好的 "N pages" / "N folders" */
int pages; /* 本目录直接图片数 */
int subdirs; /* 本目录下含图子目录数 */
int has_images; /* 1=本目录直接含图(点入进 reader) */
} mr_library_entry;
typedef struct mr_library {
mr_library_entry *items;
int count;
int cap;
} mr_library;
/* 扩展名判断:png/jpg/jpeg/bmp(大小写不敏感)。1=受支持图片。 */
int mr_path_is_image(const char *name);
/* 自然排序比较:数字段按数值比(page2 < page10),数字相等时前导零少的在前;
* 非数字段 ASCII 大小写不敏感,完全等价时按原始字节序定序。 */
int mr_natural_cmp(const char *a, const char *b);
/* 扫描 dir 的直接子目录,写入 lib(先释放 lib 旧内容)。
* 返回条目数(>=0);dir 不可读返回 -1(lib 仍为空且可安全 mr_library_free)。
* max_depth<=0 或超过 MR_LIB_MAX_DEPTH 时按上限处理。 */
int mr_library_scan(mr_library *lib, const char *dir, int max_depth);
/* 释放条目数组并清零(可重复调用)。 */
void mr_library_free(mr_library *lib);
/* 取父目录路径(去掉末尾 '/' 后截断最后一段)。根 "/" 返回 "/"。
* 成功 0;参数非法/输出缓冲不足 -1。 */
int mr_path_parent(const char *path, char *out, int outsz);
#ifdef __cplusplus
}
#endif
#endif /* MR_LIBRARY_H */