Author SHA1 Message Date
MCLauncher 393aa91302 feat: v1.3.0-Alpha 蓝色主题UI重构
Build Installers / Build Linux (push) Has been cancelled
Build Installers / Build Windows (push) Has been cancelled
Build Installers / Build macOS (push) Has been cancelled
Build Installers / 发布 Release (push) Has been cancelled
- 黑色深色主题改为明亮蓝色主题
- 新增窗口淡入动画与启动按钮忙碌动画
- 标签页选中蓝色高亮, 表格/日志区浅色化
- 版本号升级 1.3.0-Alpha
2026-08-06 12:44:29 +08:00
+45 -13
View File
@@ -39,7 +39,7 @@ from pathlib import Path
VERSION_MANIFEST_URL = "https://launchermeta.mojang.com/mc/game/version_manifest_v2.json" VERSION_MANIFEST_URL = "https://launchermeta.mojang.com/mc/game/version_manifest_v2.json"
AUTHLIB_INJECTOR_API = "https://api.github.com/repos/yushijinhun/authlib-injector/releases/latest" AUTHLIB_INJECTOR_API = "https://api.github.com/repos/yushijinhun/authlib-injector/releases/latest"
VERSION = "1.2.926" VERSION = "1.3.0-Alpha"
USER_AGENT = "Mozilla/5.0 (MeowLauncher/%s)" % VERSION USER_AGENT = "Mozilla/5.0 (MeowLauncher/%s)" % VERSION
OS_NAME = {"Windows": "windows", "Linux": "linux", "Darwin": "osx"}.get(platform.system(), "linux") OS_NAME = {"Windows": "windows", "Linux": "linux", "Darwin": "osx"}.get(platform.system(), "linux")
@@ -553,11 +553,13 @@ except Exception:
class MeowLauncherApp: class MeowLauncherApp:
BG = "#1e1e2e" BG = "#eef2f9"
CARD = "#2a2a3d" CARD = "#ffffff"
ACCENT = "#4ade80" ACCENT = "#2563eb"
TEXT = "#e2e8f0" ACCENT_LIGHT = "#60a5fa"
DIM = "#94a3b8" ACCENT_DARK = "#1d4ed8"
TEXT = "#1e293b"
DIM = "#64748b"
def __init__(self): def __init__(self):
self.root = tk.Tk() self.root = tk.Tk()
@@ -577,6 +579,7 @@ class MeowLauncherApp:
self._build_ui() self._build_ui()
self.root.after(100, self._poll_queue) self.root.after(100, self._poll_queue)
self.refresh_versions() self.refresh_versions()
self._fade_in()
@@ -596,19 +599,27 @@ class MeowLauncherApp:
style.configure("Title.TLabel", background=self.BG, foreground=self.ACCENT, style.configure("Title.TLabel", background=self.BG, foreground=self.ACCENT,
font=("Microsoft YaHei UI", 18, "bold")) font=("Microsoft YaHei UI", 18, "bold"))
style.configure("Dim.TLabel", background=self.BG, foreground=self.DIM) style.configure("Dim.TLabel", background=self.BG, foreground=self.DIM)
style.configure("Accent.TButton", background=self.ACCENT, foreground="#0f172a", style.configure("Accent.TButton", background=self.ACCENT, foreground="#ffffff",
font=("Microsoft YaHei UI", 11, "bold")) font=("Microsoft YaHei UI", 11, "bold"), padding=(16, 10))
style.map("Accent.TButton", style.map("Accent.TButton",
background=[("active", "#22c55e"), ("pressed", "#16a34a")]) background=[("active", self.ACCENT_LIGHT), ("pressed", self.ACCENT_DARK)])
style.configure("TCombobox", fieldbackground=self.CARD, background=self.CARD, style.configure("TCombobox", fieldbackground=self.CARD, background=self.CARD,
foreground=self.TEXT, arrowcolor=self.TEXT) foreground=self.TEXT, arrowcolor=self.TEXT)
style.configure("TEntry", fieldbackground=self.CARD, foreground=self.TEXT) style.configure("TEntry", fieldbackground=self.CARD, foreground=self.TEXT)
style.configure("TCheckbutton", background=self.BG, foreground=self.TEXT) style.configure("TCheckbutton", background=self.BG, foreground=self.TEXT)
style.configure("Horizontal.TProgressbar", background=self.ACCENT, troughcolor=self.CARD) style.configure("Horizontal.TProgressbar", background=self.ACCENT, troughcolor="#e2e8f0")
style.configure("TRadiobutton", background=self.BG, foreground=self.TEXT) style.configure("TRadiobutton", background=self.BG, foreground=self.TEXT)
style.configure("TNotebook", background=self.BG, borderwidth=0)
style.configure("TNotebook.Tab", background=self.CARD, foreground=self.DIM,
padding=(18, 8), font=("Microsoft YaHei UI", 10))
style.map("TNotebook.Tab",
background=[("selected", self.ACCENT)],
foreground=[("selected", "#ffffff")])
style.configure("Treeview", background=self.CARD, fieldbackground=self.CARD, style.configure("Treeview", background=self.CARD, fieldbackground=self.CARD,
foreground=self.TEXT) foreground=self.TEXT)
style.configure("Treeview.Heading", background=self.CARD, foreground=self.TEXT) style.configure("Treeview.Heading", background="#eef2f9", foreground=self.TEXT)
style.map("Treeview", background=[("selected", self.ACCENT_LIGHT)],
foreground=[("selected", "#ffffff")])
@@ -707,7 +718,7 @@ class MeowLauncherApp:
ttk.Button(row, text="浏览", command=self._pick_dir).pack(side="left", padx=4) ttk.Button(row, text="浏览", command=self._pick_dir).pack(side="left", padx=4)
log_card = self._card(self.tab_launch, "日志") log_card = self._card(self.tab_launch, "日志")
self.log_box = scrolledtext.ScrolledText(log_card, height=8, bg="#151521", self.log_box = scrolledtext.ScrolledText(log_card, height=8, bg="#f8fafc",
fg=self.TEXT, font=("Consolas", 9), fg=self.TEXT, font=("Consolas", 9),
relief="flat", state="disabled") relief="flat", state="disabled")
self.log_box.pack(fill="x") self.log_box.pack(fill="x")
@@ -758,7 +769,7 @@ class MeowLauncherApp:
self.res_tree.pack(fill="x", pady=6) self.res_tree.pack(fill="x", pady=6)
ttk.Button(dmod, text="下载选中项", command=self._download_selected).pack(anchor="w") ttk.Button(dmod, text="下载选中项", command=self._download_selected).pack(anchor="w")
self.res_log = scrolledtext.ScrolledText(self.tab_res, height=5, bg="#151521", self.res_log = scrolledtext.ScrolledText(self.tab_res, height=5, bg="#f8fafc",
fg=self.TEXT, font=("Consolas", 9), fg=self.TEXT, font=("Consolas", 9),
relief="flat", state="disabled") relief="flat", state="disabled")
self.res_log.pack(fill="x", padx=14, pady=(4, 6)) self.res_log.pack(fill="x", padx=14, pady=(4, 6))
@@ -871,6 +882,26 @@ class MeowLauncherApp:
self.msg_queue.put(("log", "[版本] 获取失败: %s" % e)) self.msg_queue.put(("log", "[版本] 获取失败: %s" % e))
threading.Thread(target=worker, daemon=True).start() threading.Thread(target=worker, daemon=True).start()
def _fade_in(self, step=0):
"""窗口淡入动画 (alpha 0 -> 1)。"""
try:
self.root.attributes("-alpha", min(step * 0.1, 1.0))
except Exception:
return
if step < 10:
self.root.after(18, lambda: self._fade_in(step + 1))
def _busy_button(self, text):
"""启动按钮忙碌状态 (文字闪烁)。"""
state = [0]
def tick():
if str(self.launch_btn["state"]) != "disabled":
return
state[0] += 1
self.launch_btn.configure(text=text + "." * (state[0] % 4))
self.root.after(400, tick)
tick()
def _poll_queue(self): def _poll_queue(self):
"""定时轮询消息队列, 把后台线程的日志/结果刷到界面。""" """定时轮询消息队列, 把后台线程的日志/结果刷到界面。"""
try: try:
@@ -922,6 +953,7 @@ class MeowLauncherApp:
def _on_launch(self): def _on_launch(self):
"""点击启动游戏: 禁用按钮并开后台线程。""" """点击启动游戏: 禁用按钮并开后台线程。"""
self.launch_btn.config(state="disabled") self.launch_btn.config(state="disabled")
self._busy_button("启动中")
threading.Thread(target=self._launch_worker, daemon=True).start() threading.Thread(target=self._launch_worker, daemon=True).start()
def _launch_worker(self): def _launch_worker(self):