增添 S5 支持

This commit is contained in:
riseforever2026
2026-10-03 00:01:12 +08:00
parent d4dff20600
commit 9a80b9de30
338 changed files with 9463 additions and 64 deletions
+29 -6
View File
@@ -37,6 +37,13 @@ def prepare(name):
shutil.copyfile(os.path.join(ov, 'watchface', 'fprj', f'{name}.fprj'),
os.path.join(dst, 'watchface', 'fprj', f'{name}.fprj'))
# projectName 现在就是「手表上显示的表盘名」(见 make_overlays.py 的 DISPLAY_NAME)。
# 官方 scripts/build_face.ps1 先跑 sync_watchface_config.ps1:它按 projectName 找
# watchface/fprj/<projectName>.fprj,找不到就把目录里**唯一**那份 .fprj 改名成它,
# 并把该 fprj 的 <Screen Title> 覆盖成 projectName —— 所以这条流水线里真正进 .face 的
# 显示名就是这个 projectName。注意 fprj 目录里必须**只有一份** .fprj:Compiler.exe 会
# 按目录里每份 .fprj 把资源各打包一遍,多放一份副本会让 .face 直接翻倍。
disp = cfg['projectName']
shutil.copyfile(os.path.join(ov, 'watchface', 'fprj', 'images', 'preview.png'),
os.path.join(dst, 'watchface', 'fprj', 'images', 'preview.png'))
shutil.copyfile(os.path.join(ov, 'watchface', 'fprj', 'app', 'lua', 'main.lua'),
@@ -51,18 +58,34 @@ def prepare(name):
shutil.rmtree(tgt)
shutil.copytree(os.path.join(ovimg, d), tgt)
print(f' {name}: app/images/{d}/ -> {len(os.listdir(tgt))} files')
return dst
return dst, cfg['projectName']
def build(dst):
def build(dst, name, disp):
ps = os.path.join(dst, 'scripts', 'build_face.ps1')
r = subprocess.run(['powershell', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', ps],
# 显式指定产物名:build_face.ps1 默认按 projectName(现在 = 显示名,可能带空格/点)命名产物,
# 这里仍然用 NAME,保证 bin/<NAME>.face、dist/<NAME>.face 这些标识路径不变。
r = subprocess.run(['powershell', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', ps,
'-FaceName', f'{name}.face'],
capture_output=True, text=True, errors='replace')
for l in [x for x in (r.stdout or '').splitlines() if x.strip()][-6:]:
print(' |', l)
if r.returncode != 0:
print(' !! build failed, rc=', r.returncode)
return r.returncode == 0
return False
# sync 已经把 .fprj 改名成 <显示名>.fprj(里面的 <Screen Title> 也写成了显示名);
# 这里改回 NAME,好让下游 finalize_faces.compile_raw 仍按 fprj/<NAME>.fprj 找它。
fprj_ident = os.path.join(dst, 'watchface', 'fprj', f'{name}.fprj')
fprj_disp = os.path.join(dst, 'watchface', 'fprj', f'{disp}.fprj')
if disp != name and os.path.exists(fprj_disp) and not os.path.exists(fprj_ident):
os.replace(fprj_disp, fprj_ident)
# 官方脚本按 projectName 命名产物(bin/<显示名>.face);-FaceName 已经把它压成 NAME,
# 万一没生效,这里再兜一次(内容一样,只差文件名)。
face = os.path.join(dst, 'bin', f'{name}.face')
alt = os.path.join(dst, 'bin', f'{disp}.face')
if disp != name and os.path.exists(alt) and not os.path.exists(face):
os.replace(alt, face)
return True
if __name__ == '__main__':
@@ -71,8 +94,8 @@ if __name__ == '__main__':
if only and name != only:
continue
print(f'== {name} (id={TARGETS[name][0]}) ==')
dst = prepare(name)
ok = build(dst)
dst, disp = prepare(name)
build(dst, name, disp)
face = os.path.join(dst, 'bin', f'{name}.face')
if os.path.exists(face):
print(f' OK {face} {os.path.getsize(face)} bytes')
+5 -2
View File
@@ -10,6 +10,9 @@ DEVICE_TYPE = "362" # 与官方模板一致(362 = S4 家族)
ENTRY_WIDGET = "app_lua%2Fmain.lua"
PREVIEW_SIZE = 326 # Compiler.exe 对 362 设备强制 326x326
SCREEN_SIZE = 466
# 手表上显示的表盘名:写进 .fprj 的 <Screen Title>,同样也是 watchface.config.json 的 projectName。
# 只是「显示名」—— 路径/标识(NAME、.fprj 文件名、dist/<NAME>.face、表盘 id)全部不变。
DISPLAY_NAME = 'S4e Pt.1'
WF_ID = "491552801"
FONTS = [r'C:\Windows\Fonts\msyhbd.ttc', r'C:\Windows\Fonts\msyh.ttc',
r'C:\Windows\Fonts\arialbd.ttf', r'C:\Windows\Fonts\arial.ttf']
@@ -48,12 +51,12 @@ def build(name):
os.makedirs(os.path.join(fprj, 'images'), exist_ok=True)
os.makedirs(os.path.join(fprj, 'app', 'lua'), exist_ok=True)
cfg = {"projectName": name, "watchfaceId": WF_ID, "power_consumption": "3",
cfg = {"projectName": DISPLAY_NAME, "watchfaceId": WF_ID, "power_consumption": "3",
"resourceBin": {"lvglVersion": 9, "colorFormat": "I8", "compress": "NONE",
"input": "watchface/fprj/images/preview.png", "name": "preview"}}
json.dump(cfg, open(os.path.join(base, 'watchface.config.json'), 'w', encoding='utf-8'),
indent=4, ensure_ascii=False)
write_fprj(os.path.join(fprj, f'{name}.fprj'), name)
write_fprj(os.path.join(fprj, f'{name}.fprj'), DISPLAY_NAME)
make_preview(os.path.join(fprj, 'images', 'preview.png'))
shutil.copyfile(os.path.join(PROJ, 'main.lua'),
os.path.join(fprj, 'app', 'lua', 'main.lua'))
+2 -2
View File
@@ -75,7 +75,7 @@ def big_button(y=365, text='确认替换'):
# ---------------------------------------------------------------- 1. 首页
PAGE_HOME = [
clock(),
title('OS4 Icons'),
title('S4e Pt.1'),
*item(85, 'MdiLightbulbOutline.png', '快速帮助'),
*item(181, 'MdiBandage.png', '开始替换'),
*item(277, 'MdiInformationOutline.png', '关于'),
@@ -162,7 +162,7 @@ PAGE_ABOUT = [
dict(kind='rect', x=52, y=79, w=362, h=204, bg=PLATE, radius=30),
dict(kind='image', x=194, y=108, w=78, h=78,
src=os.path.join(DOCS, 'logo_preview.png')),
dict(kind='label', x=164, y=192, w=138, h=38, text='OS4 Icons',
dict(kind='label', x=178, y=192, w=111, h=38, text='S4e Pt.1',
size=28, weight=S500, color=WHITE, align='left', vtop=True, lh=38),
dict(kind='label', x=210, y=227, w=45, h=27, text='1.0.0',
size=20, weight=S500, color=GRAY, align='left', vtop=True, lh=27),