-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
183 lines (150 loc) · 5.87 KB
/
main.py
File metadata and controls
183 lines (150 loc) · 5.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
"""main.py(Flet App 入口)
責任:
- 組裝各個 View(設定/規則/快取/翻譯/...)並處理切頁。
- 只在 `__main__` 路徑呼叫 bootstrap_runtime() 做一次性的 runtime 初始化。
維護注意:
- main.py 可能被測試 import;因此不能在 import 階段就做 logging/config 初始化。
- 快取搜尋索引重建會在啟動後用背景 thread 執行,避免主畫面卡住。
"""
# =========================================================
# Window Constants - 視窗尺寸常數
# =========================================================
WINDOW_WIDTH_DEFAULT = 1200 # 預設視窗寬度
WINDOW_HEIGHT_DEFAULT = 850 # 預設視窗高度
WINDOW_MIN_WIDTH = 1050 # 視窗最小寬度
WINDOW_MIN_HEIGHT = 760 # 視窗最小高度
import logging
import flet as ft
from app.startup_tasks import start_background_startup_tasks
from app.ui.keyboard_shortcuts import create_keyboard_handler
from app.ui.quick_jump import show_quick_jump_panel
from app.view_registry import build_navigation_destinations, build_view_registry, get_window_size
logger = logging.getLogger("main_app")
def bootstrap_runtime():
"""初始化 runtime(config + logging),只應在 script entry 被呼叫一次。"""
from translation_tool.utils.config_manager import load_config, setup_logging
config = load_config()
setup_logging(config)
root_level = logging.getLogger().getEffectiveLevel()
logger.info(
f"日誌系統初始化成功,根記錄器級別已設為 {logging.getLevelName(root_level)} ({root_level})。"
)
def main(page: ft.Page):
page.title = "Minecraft 模組包繁體化工具"
page.window_width = WINDOW_WIDTH_DEFAULT
page.window_height = WINDOW_HEIGHT_DEFAULT
page.window_min_width = WINDOW_MIN_WIDTH
page.window_min_height = WINDOW_MIN_HEIGHT
page.window_resizable = True
page.bgcolor = "surfaceVariant"
page.theme = ft.Theme(
font_family="Noto Sans TC",
use_material3=True,
color_scheme_seed=ft.Colors.INDIGO,
visual_density=ft.VisualDensity.COMFORTABLE,
)
page.theme_mode = ft.ThemeMode.LIGHT
file_picker = ft.FilePicker()
page.overlay.append(file_picker)
registry = build_view_registry(page, file_picker)
def resize_window_for_view(view_key: str):
width, height = get_window_size(view_key)
try:
page.window.maximized = False
page.window.width = width
page.window.height = height
except Exception:
page.window_width = width
page.window_height = height
content_area = ft.Container(content=registry[0]['view'], expand=True)
# 建立鍵盤快捷鍵處理器
keyboard_handler = create_keyboard_handler(
page, registry, lambda idx: change_view_by_index(idx)
)
def change_view(e):
selected_index = e.control.selected_index
item = registry[selected_index]
content_area.content = item['view']
resize_window_for_view(item['key'])
page.update()
def change_view_by_index(index: int):
"""透過索引直接切換視圖"""
if 0 <= index < len(registry):
item = registry[index]
content_area.content = item['view']
resize_window_for_view(item['key'])
rail.selected_index = index
page.update()
# 註冊鍵盤事件處理
page.on_keyboard_event = keyboard_handler.handle_keyboard
def toggle_theme_mode(e):
is_light = page.theme_mode == ft.ThemeMode.LIGHT
page.theme_mode = ft.ThemeMode.DARK if is_light else ft.ThemeMode.LIGHT
toggle_icon_btn.icon = ft.Icons.LIGHT_MODE if is_light else ft.Icons.DARK_MODE
toggle_icon_btn.tooltip = "切換為淺色模式" if is_light else "切換為深色模式"
page.update()
toggle_icon_btn = ft.IconButton(
icon=ft.Icons.DARK_MODE,
tooltip="切換為深色模式",
on_click=toggle_theme_mode,
)
# 快速跳轉功能
def on_quick_jump(e):
show_quick_jump_panel(page, registry, change_view_by_index)
# 快捷鍵綁定搜尋功能
keyboard_handler.set_search_callback(on_quick_jump)
rail = ft.NavigationRail(
selected_index=0,
label_type=ft.NavigationRailLabelType.ALL,
min_width=80,
min_extended_width=200,
extended=True,
group_alignment=-0.95,
destinations=build_navigation_destinations(registry),
on_change=change_view,
bgcolor=ft.Colors.SURFACE,
leading=ft.Container(
content=ft.Column(
[
ft.IconButton(
ft.Icons.MENU,
on_click=lambda _: (
setattr(rail, "extended", not rail.extended) or page.update()
),
tooltip="收合/展開選單",
),
ft.IconButton(
ft.Icons.SEARCH,
on_click=on_quick_jump,
tooltip="快速跳轉 (Ctrl+P)",
),
],
spacing=5,
alignment=ft.MainAxisAlignment.CENTER,
),
margin=ft.margin.only(bottom=10),
),
trailing=ft.Container(
content=toggle_icon_btn,
margin=ft.margin.only(top=10),
),
)
layout = ft.Row(
controls=[
rail,
ft.VerticalDivider(width=1, thickness=1, color="outlineVariant"),
content_area,
],
expand=True,
spacing=0,
)
page.add(layout)
resize_window_for_view(registry[0]['key'])
page.update()
start_background_startup_tasks()
if __name__ == "__main__":
try:
bootstrap_runtime()
except Exception as e:
print(f"致命錯誤:配置或日誌系統初始化失敗!錯誤: {e}")
ft.app(target=main)