Anbernic RG 系列掌机图形化系统设置工具。
# 放入 /mnt/sdcard/Roms/APPS/ 后,掌机菜单中选中运行
/mnt/sdcard/Roms/APPS/RgMenuStart.sh入口脚本 RgMenuStart.sh 启动 RgMenu/main.py,日志写入 RgMenu/log.txt。
RgMenu/
├── main.py # 入口:SDL2 引导 → App.run()
├── app.py # 主循环:poll → handle → timer.update → render
├── board.py # 硬件常量(机型探测 / 分辨率 / 路径),无重依赖
├── model.py # Node 数据类 + menu_config.json 加载
├── config.py # system.cfg 原子读写(tmp + os.replace)
├── input.py # PollInput:poll + timeout + 一次 open O_NONBLOCK
├── dirty.py # 全局脏标记:set_dirty() / take_dirty()
├── timer_mgr.py # 最小堆定时器(单位:100ms)
├── toast.py # ToastManager:show / dismiss / 到期回调
├── menu_config.json # 菜单树(声明式,支持任意深度)
├── sdl2.zip # SDL2 离线安装包(fallback)
├── LICENSE
├── ui/
│ ├── graphic.py # SDL2 + PIL 渲染(解耦 main 依赖,纹理复用)
│ └── listview.py # ListView:光标 / 翻页 / 分页渲染 / ● 状态高亮
└── actions/
├── __init__.py # dispatch() + check_state() + self_check()
├── _common.py # 共享:run_command / net_ok / service_toggle
└── test.py # 假动作(测试用)
input(poll+timeout) timer_mgr(最小堆)
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ App (事件循环 / 屏幕栈) │
│ poll → handle → timer.update → render │
│ 栈顶 ListView ←→ Node 树 │
└───────────────────┬─────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
ListView toast_mgr dirty flag
(通用列表) (show/dismiss) (按需重绘)
menu 和 option 是同一种东西。 一个 Node 要么有 items(子菜单),要么有 action(可执行)。递归嵌套,任意深度零成本。
屏幕栈取代字符串分发。 stack: list[ListView],push = 下钻,pop = 返回,不再有 current_window == "menu"/"options"。
全局脏标记。 任何组件(输入、timer、toast)需要重绘时调 set_dirty(),主循环用 take_dirty() 消费。空闲时不渲染。
最小堆定时器。 TimerManager 管理所有异步任务:IP 轮询(recurring, 每 1 秒)、toast 到期清除(one-shot)。next_timeout_ms() 为 poll 提供精准超时。
Toast 生命周期自管理。 ToastManager 持有 TimerManager 引用,show() 自动注册到期回调,dismiss() 自动取消。任意按键即 dismiss。
Action 插件式。 actions/<name>.py 暴露 action(params) → (ok, msg) 和可选 state() → str | None。框架动态 import,加动作 = 新建文件。
{
"label": "菜单项",
"help": "帮助文字",
"state": "action_name", // 可选:查询当前生效值(打 ● + 光标定位)
"items": [...], // 有 items = 子菜单
"action": "action_name", // 有 action = 叶子(可执行)
"params": ["arg1", "arg2"], // 传给 action() 的参数列表
"need_net": false // 可选:执行前需联网检查
}| 按键 | 功能 |
|---|---|
| ↑↓ (DY) | 移动光标 |
| A | 确认 / 下钻 / 执行 |
| B | 返回上一层 |
| L1 / R1 | 整页翻 (max_elem 项) |
| L2 / R2 | 快翻 100 项 |
| SELECT | 退出程序 |