pyscreeps-arena 0.5.9.0__py3-none-any.whl → 0.5.9b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyscreeps_arena/compiler.py +7 -10
- pyscreeps_arena/core/const.py +1 -1
- pyscreeps_arena/project.7z +0 -0
- pyscreeps_arena/ui/project_ui.py +75 -695
- {pyscreeps_arena-0.5.9.0.dist-info → pyscreeps_arena-0.5.9b0.dist-info}/METADATA +1 -1
- {pyscreeps_arena-0.5.9.0.dist-info → pyscreeps_arena-0.5.9b0.dist-info}/RECORD +9 -9
- {pyscreeps_arena-0.5.9.0.dist-info → pyscreeps_arena-0.5.9b0.dist-info}/WHEEL +0 -0
- {pyscreeps_arena-0.5.9.0.dist-info → pyscreeps_arena-0.5.9b0.dist-info}/entry_points.txt +0 -0
- {pyscreeps_arena-0.5.9.0.dist-info → pyscreeps_arena-0.5.9b0.dist-info}/top_level.txt +0 -0
pyscreeps_arena/compiler.py
CHANGED
|
@@ -53,7 +53,6 @@ def replace_src_prefix(file_list):
|
|
|
53
53
|
# """
|
|
54
54
|
# return PYFILE_PRAGMA_INSERTS + "\n" + content
|
|
55
55
|
class Compiler_Const:
|
|
56
|
-
CALLED_FUNCTIONS = ['behavior', 'sequence', 'selector', 'parallel', 'listen']
|
|
57
56
|
PROTO_DEFINES_DIRS = ["builtin", "library"]
|
|
58
57
|
FILE_STRONG_REPLACE = {
|
|
59
58
|
"std": {
|
|
@@ -110,14 +109,14 @@ export var loop = function () {
|
|
|
110
109
|
if (know.now === 1) {
|
|
111
110
|
std.show_welcome();
|
|
112
111
|
init (know);
|
|
113
|
-
|
|
112
|
+
|
|
114
113
|
}
|
|
115
114
|
step (know);
|
|
116
115
|
timeLine = get.cpu_us();
|
|
117
116
|
if (get._SCH_FLAG) sch.handle();
|
|
118
117
|
stepCost = get.cpu_us() - timeLine;
|
|
119
|
-
std.show_usage ();
|
|
120
|
-
print("knowCost:", knowCost, "monitorCost:", monitorCost, "stepCost:", stepCost);
|
|
118
|
+
//std.show_usage ();
|
|
119
|
+
//print("knowCost:", knowCost, "monitorCost:", monitorCost, "stepCost:", stepCost);
|
|
121
120
|
if (know.draw) know.draw();
|
|
122
121
|
};
|
|
123
122
|
"""
|
|
@@ -668,7 +667,7 @@ class Compiler_Utils(Compiler_Const):
|
|
|
668
667
|
|
|
669
668
|
# 2. 查找所有 @<caller_name>(...) 装饰器(支持多行参数)
|
|
670
669
|
decorator_pattern = re.compile(
|
|
671
|
-
r'^\s*@\s*' + re.escape(caller_name) + r'\s*\((.*?)\)\s*$\n?',
|
|
670
|
+
r'^\s*@\s*' + re.escape(caller_name) + r'\s*\((.*?)\)\s*$\n?',
|
|
672
671
|
re.MULTILINE | re.DOTALL
|
|
673
672
|
)
|
|
674
673
|
|
|
@@ -999,8 +998,6 @@ class Compiler(CompilerBase):
|
|
|
999
998
|
|
|
1000
999
|
# 将PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "")插入到文件开头
|
|
1001
1000
|
content = self.auto_read(fpath)
|
|
1002
|
-
# 移除"""$..."""代码块
|
|
1003
|
-
content = re.sub(r'"""\$[\s\S]*?"""', '', content)
|
|
1004
1001
|
content = self.PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "") + content
|
|
1005
1002
|
# content = self.remove_long_docstring(content) # 移除长注释 | remove long docstring
|
|
1006
1003
|
|
|
@@ -1162,7 +1159,7 @@ class Compiler(CompilerBase):
|
|
|
1162
1159
|
content = self.auto_read(fpath)
|
|
1163
1160
|
content = self.stage_recursive_replace(content) # 调用stage_recursive_replace
|
|
1164
1161
|
# 调用stage_called_replace处理四个装饰器
|
|
1165
|
-
for caller in
|
|
1162
|
+
for caller in ['behavior', 'sequence', 'selector', 'parallel']:
|
|
1166
1163
|
content = self.stage_called_replace(caller, content)
|
|
1167
1164
|
with open(fpath, 'w', encoding='utf-8') as f:
|
|
1168
1165
|
f.write(content)
|
|
@@ -1515,7 +1512,7 @@ if __name__ == '__main__':
|
|
|
1515
1512
|
# compiler.compile()
|
|
1516
1513
|
# compiler.clean()
|
|
1517
1514
|
test = """
|
|
1518
|
-
|
|
1515
|
+
|
|
1519
1516
|
def patrolling(self, c: Creep):
|
|
1520
1517
|
e = self.center.nearest(k.civilian.enemies, 5)
|
|
1521
1518
|
if e:
|
|
@@ -1525,6 +1522,6 @@ def patrolling(self, c: Creep):
|
|
|
1525
1522
|
):
|
|
1526
1523
|
case True: c.move(e, SWAMP_MOTION)
|
|
1527
1524
|
case False: c.move(self.bpos, SWAMP_MOTION)
|
|
1528
|
-
|
|
1525
|
+
|
|
1529
1526
|
"""
|
|
1530
1527
|
print(f"res=\n{Compiler.convert_match_to_if(test)}")
|
pyscreeps_arena/core/const.py
CHANGED
pyscreeps_arena/project.7z
CHANGED
|
Binary file
|
pyscreeps_arena/ui/project_ui.py
CHANGED
|
@@ -4,13 +4,11 @@
|
|
|
4
4
|
"""
|
|
5
5
|
import sys
|
|
6
6
|
import os
|
|
7
|
-
import json
|
|
8
7
|
from pathlib import Path
|
|
9
8
|
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
|
|
10
9
|
QHBoxLayout, QLabel, QLineEdit, QPushButton,
|
|
11
|
-
QFileDialog, QMessageBox, QComboBox
|
|
12
|
-
from
|
|
13
|
-
from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty
|
|
10
|
+
QFileDialog, QMessageBox, QComboBox)
|
|
11
|
+
from PyQt6.QtCore import Qt
|
|
14
12
|
from PyQt6.QtGui import QFont
|
|
15
13
|
from PyQt6.QtGui import QIcon
|
|
16
14
|
from pyscreeps_arena.core import const
|
|
@@ -18,307 +16,36 @@ from pyscreeps_arena.ui.rs_icon import get_pixmap
|
|
|
18
16
|
from pyscreeps_arena.afters import ToConfigAfter, ToEmptyAfter, ToPrefabAfter, ToCustomAfter
|
|
19
17
|
from PyQt6.QtWidgets import QRadioButton, QGroupBox
|
|
20
18
|
|
|
21
|
-
# Language mapping
|
|
22
|
-
LANG = {
|
|
23
|
-
'cn': {
|
|
24
|
-
'window_title': 'PyScreeps Arena - 项目创建器',
|
|
25
|
-
'title': 'PyScreeps Arena',
|
|
26
|
-
'version': '版本: {0}',
|
|
27
|
-
'author': '作者: {0}',
|
|
28
|
-
'github': 'GitHub: {0}',
|
|
29
|
-
'project_name': '项目名称:',
|
|
30
|
-
'name_placeholder': '输入项目名称...',
|
|
31
|
-
'save_location': '保存位置:',
|
|
32
|
-
'path_placeholder': '选择项目保存位置...',
|
|
33
|
-
'browse': '浏览...',
|
|
34
|
-
'language': '语 言:',
|
|
35
|
-
'arena': '竞技场:',
|
|
36
|
-
'difficulty': '难 度:',
|
|
37
|
-
'empty': '空白 (Empty)',
|
|
38
|
-
'basic': '基础 (Basic)',
|
|
39
|
-
'prefab': '预设 (Prefab)',
|
|
40
|
-
'pi': '预设继承 (P&&I)',
|
|
41
|
-
'create_project': '创建项目',
|
|
42
|
-
'cancel': '取消',
|
|
43
|
-
'path_exists': '路径已存在',
|
|
44
|
-
'path_exists_message': "路径 '{0}' 已存在。\n是否继续?",
|
|
45
|
-
'success': '成功',
|
|
46
|
-
'success_message': "项目 '{0}' 创建成功!\n路径: {1}",
|
|
47
|
-
'error': '错误',
|
|
48
|
-
'error_message': '项目创建失败:\n{0}',
|
|
49
|
-
'select_location': '选择项目保存位置',
|
|
50
|
-
'next_page': '下一页',
|
|
51
|
-
'previous_page': '上一页',
|
|
52
|
-
},
|
|
53
|
-
'en': {
|
|
54
|
-
'window_title': 'PyScreeps Arena - Project Creator',
|
|
55
|
-
'title': 'PyScreeps Arena',
|
|
56
|
-
'version': 'Version: {0}',
|
|
57
|
-
'author': 'Author: {0}',
|
|
58
|
-
'github': 'GitHub: {0}',
|
|
59
|
-
'project_name': 'Project Name:',
|
|
60
|
-
'name_placeholder': 'Enter project name...',
|
|
61
|
-
'save_location': 'Save Location:',
|
|
62
|
-
'path_placeholder': 'Select project save location...',
|
|
63
|
-
'browse': 'Browse...',
|
|
64
|
-
'language': 'Language:',
|
|
65
|
-
'arena': 'Arena:',
|
|
66
|
-
'difficulty': 'Difficulty:',
|
|
67
|
-
'empty': 'Empty',
|
|
68
|
-
'basic': 'Basic',
|
|
69
|
-
'prefab': 'Prefab',
|
|
70
|
-
'pi': 'Prefab & Inherit',
|
|
71
|
-
'create_project': 'Create Project',
|
|
72
|
-
'cancel': 'Cancel',
|
|
73
|
-
'path_exists': 'Path Exists',
|
|
74
|
-
'path_exists_message': "Path '{0}' already exists.\nContinue anyway?",
|
|
75
|
-
'success': 'Success',
|
|
76
|
-
'success_message': "Project '{0}' created successfully!\nPath: {1}",
|
|
77
|
-
'error': 'Error',
|
|
78
|
-
'error_message': 'Failed to create project:\n{0}',
|
|
79
|
-
'select_location': 'Select Project Save Location',
|
|
80
|
-
'next_page': 'Next Page',
|
|
81
|
-
'previous_page': 'Previous',
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
19
|
|
|
85
20
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
# Signals
|
|
91
|
-
projectCreated = pyqtSignal(str, str) # (project_name, project_path)
|
|
92
|
-
projectCancelled = pyqtSignal()
|
|
93
|
-
languageChanged = pyqtSignal(str) # (language_code)
|
|
94
|
-
|
|
95
|
-
def __init__(self, parent=None):
|
|
96
|
-
super().__init__(parent)
|
|
21
|
+
class ProjectCreatorUI(QMainWindow):
|
|
22
|
+
def __init__(self):
|
|
23
|
+
super().__init__()
|
|
97
24
|
self._proj_name = ""
|
|
98
25
|
self._proj_path = ""
|
|
99
26
|
self._init_ui()
|
|
100
|
-
|
|
101
|
-
def lang(self, key, *args):
|
|
102
|
-
"""Get translation for the current language"""
|
|
103
|
-
# Get language code from combo box data
|
|
104
|
-
lang = self._lang_combo.currentData() or 'cn'
|
|
105
|
-
|
|
106
|
-
if lang not in LANG:
|
|
107
|
-
lang = 'cn'
|
|
108
|
-
return LANG[lang][key].format(*args)
|
|
109
|
-
|
|
110
|
-
def _get_settings_path(self):
|
|
111
|
-
"""Get cross-platform settings file path"""
|
|
112
|
-
# Get user's home directory
|
|
113
|
-
home_dir = os.path.expanduser("~")
|
|
114
|
-
|
|
115
|
-
# Create settings directory if it doesn't exist
|
|
116
|
-
settings_dir = os.path.join(home_dir, ".psaui")
|
|
117
|
-
os.makedirs(settings_dir, exist_ok=True)
|
|
118
|
-
|
|
119
|
-
# Return settings file path
|
|
120
|
-
return os.path.join(settings_dir, "psaui.json")
|
|
121
|
-
|
|
122
|
-
def _save_settings(self):
|
|
123
|
-
"""Save settings to psaui.json"""
|
|
124
|
-
settings = {
|
|
125
|
-
"language": self._lang_combo.currentIndex(),
|
|
126
|
-
"path": self._path_input.text()
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
try:
|
|
130
|
-
settings_path = self._get_settings_path()
|
|
131
|
-
with open(settings_path, 'w', encoding='utf-8') as f:
|
|
132
|
-
json.dump(settings, f, indent=2, ensure_ascii=False)
|
|
133
|
-
except Exception as e:
|
|
134
|
-
print(f"Error saving settings: {e}")
|
|
135
|
-
|
|
136
|
-
def _load_settings(self):
|
|
137
|
-
"""Load settings from psaui.json if it exists"""
|
|
138
|
-
try:
|
|
139
|
-
settings_path = self._get_settings_path()
|
|
140
|
-
if os.path.exists(settings_path):
|
|
141
|
-
with open(settings_path, 'r', encoding='utf-8') as f:
|
|
142
|
-
settings = json.load(f)
|
|
143
|
-
|
|
144
|
-
# Load language setting
|
|
145
|
-
if "language" in settings:
|
|
146
|
-
language_index = settings["language"]
|
|
147
|
-
if 0 <= language_index < self._lang_combo.count():
|
|
148
|
-
self._lang_combo.setCurrentIndex(language_index)
|
|
149
|
-
|
|
150
|
-
# Load path setting
|
|
151
|
-
if "path" in settings and settings["path"]:
|
|
152
|
-
self._path_input.setText(settings["path"])
|
|
153
|
-
self._proj_path = settings["path"]
|
|
154
|
-
except Exception as e:
|
|
155
|
-
print(f"Error loading settings: {e}")
|
|
156
|
-
|
|
157
|
-
def _update_language_options(self):
|
|
158
|
-
"""Update language combo box options based on current language"""
|
|
159
|
-
# Get current language
|
|
160
|
-
lang_text = self._lang_combo.currentText()
|
|
161
|
-
current_lang = lang_text.split('(')[1].strip(')') if '(' in lang_text else 'cn'
|
|
162
|
-
|
|
163
|
-
# Save current index
|
|
164
|
-
current_index = self._lang_combo.currentIndex()
|
|
165
|
-
|
|
166
|
-
# Disconnect signal to avoid recursion
|
|
167
|
-
self._lang_combo.currentTextChanged.disconnect(self._update_language)
|
|
168
|
-
|
|
169
|
-
# Clear existing items
|
|
170
|
-
self._lang_combo.clear()
|
|
171
|
-
|
|
172
|
-
# Add items based on current language
|
|
173
|
-
if current_lang == 'en':
|
|
174
|
-
# In English mode, show only language codes
|
|
175
|
-
self._lang_combo.addItems(["cn", "en"])
|
|
176
|
-
else:
|
|
177
|
-
# In Chinese mode, show full language names
|
|
178
|
-
self._lang_combo.addItems(["中文 (cn)", "英文 (en)"])
|
|
179
|
-
|
|
180
|
-
# Restore current index
|
|
181
|
-
if current_index < self._lang_combo.count():
|
|
182
|
-
self._lang_combo.setCurrentIndex(current_index)
|
|
183
|
-
|
|
184
|
-
# Reconnect signal
|
|
185
|
-
self._lang_combo.currentTextChanged.connect(self._update_language)
|
|
186
|
-
|
|
187
|
-
def _update_language(self):
|
|
188
|
-
"""Update all UI elements to use the current language"""
|
|
189
|
-
# Get current language code
|
|
190
|
-
current_lang = self._lang_combo.currentData() or 'cn'
|
|
191
|
-
|
|
192
|
-
# Update window title
|
|
193
|
-
self.setWindowTitle(self.lang('window_title'))
|
|
194
|
-
|
|
195
|
-
# Update title
|
|
196
|
-
self._title_label.setText(self.lang('title'))
|
|
197
|
-
|
|
198
|
-
# Update info labels
|
|
199
|
-
self._version_label.setText(self.lang('version', const.VERSION))
|
|
200
|
-
self._author_label.setText(self.lang('author', const.AUTHOR))
|
|
201
|
-
self._github_label.setText(self.lang('github', const.GITHUB_NAME))
|
|
202
|
-
|
|
203
|
-
# Update input labels and placeholders
|
|
204
|
-
current_lang = self._lang_combo.currentData() or 'cn'
|
|
205
|
-
if current_lang == 'en':
|
|
206
|
-
self._name_label.setText('Name:')
|
|
207
|
-
else:
|
|
208
|
-
self._name_label.setText(self.lang('project_name'))
|
|
209
|
-
self._name_input.setPlaceholderText(self.lang('name_placeholder'))
|
|
210
|
-
self._path_label.setText(self.lang('save_location'))
|
|
211
|
-
self._path_input.setPlaceholderText(self.lang('path_placeholder'))
|
|
212
|
-
|
|
213
|
-
# Update buttons
|
|
214
|
-
self._browse_btn.setText(self.lang('browse'))
|
|
215
|
-
if hasattr(self, '_create_btn'):
|
|
216
|
-
self._create_btn.setText(self.lang('create_project'))
|
|
217
|
-
if hasattr(self, '_cancel_btn'):
|
|
218
|
-
self._cancel_btn.setText(self.lang('cancel'))
|
|
219
|
-
|
|
220
|
-
# Update config labels
|
|
221
|
-
self._lang_label.setText(self.lang('language'))
|
|
222
|
-
self._arena_label.setText(self.lang('arena'))
|
|
223
|
-
self._level_label.setText(self.lang('difficulty'))
|
|
224
|
-
|
|
225
|
-
# Update radio buttons
|
|
226
|
-
self._empty_radio.setText(self.lang('empty'))
|
|
227
|
-
self._basic_radio.setText(self.lang('basic'))
|
|
228
|
-
self._prefab_radio.setText(self.lang('prefab'))
|
|
229
|
-
self._pi_radio.setText(self.lang('pi'))
|
|
230
|
-
|
|
231
|
-
# Update language combo box items based on current language
|
|
232
|
-
if current_lang == 'en':
|
|
233
|
-
# In English mode, show only language codes
|
|
234
|
-
self._lang_combo.blockSignals(True)
|
|
235
|
-
current_index = self._lang_combo.currentIndex()
|
|
236
|
-
self._lang_combo.clear()
|
|
237
|
-
self._lang_combo.addItem("cn", "cn")
|
|
238
|
-
self._lang_combo.addItem("en", "en")
|
|
239
|
-
self._lang_combo.setCurrentIndex(current_index)
|
|
240
|
-
self._lang_combo.blockSignals(False)
|
|
241
|
-
|
|
242
|
-
# Update arena combo box items
|
|
243
|
-
self._arena_combo.blockSignals(True)
|
|
244
|
-
current_arena_index = self._arena_combo.currentIndex()
|
|
245
|
-
self._arena_combo.clear()
|
|
246
|
-
self._arena_combo.addItem("gray", "gray")
|
|
247
|
-
self._arena_combo.addItem("green", "green")
|
|
248
|
-
self._arena_combo.addItem("blue", "blue")
|
|
249
|
-
self._arena_combo.addItem("red", "red")
|
|
250
|
-
self._arena_combo.setCurrentIndex(current_arena_index)
|
|
251
|
-
self._arena_combo.blockSignals(False)
|
|
252
|
-
|
|
253
|
-
# Update level combo box items
|
|
254
|
-
self._level_combo.blockSignals(True)
|
|
255
|
-
current_level_index = self._level_combo.currentIndex()
|
|
256
|
-
self._level_combo.clear()
|
|
257
|
-
self._level_combo.addItem("basic", "basic")
|
|
258
|
-
self._level_combo.addItem("advanced", "advanced")
|
|
259
|
-
self._level_combo.setCurrentIndex(current_level_index)
|
|
260
|
-
self._level_combo.blockSignals(False)
|
|
261
|
-
else:
|
|
262
|
-
# In Chinese mode, show full language names
|
|
263
|
-
self._lang_combo.blockSignals(True)
|
|
264
|
-
current_index = self._lang_combo.currentIndex()
|
|
265
|
-
self._lang_combo.clear()
|
|
266
|
-
self._lang_combo.addItem("中文 (cn)", "cn")
|
|
267
|
-
self._lang_combo.addItem("英文 (en)", "en")
|
|
268
|
-
self._lang_combo.setCurrentIndex(current_index)
|
|
269
|
-
self._lang_combo.blockSignals(False)
|
|
270
|
-
|
|
271
|
-
# Update arena combo box items
|
|
272
|
-
self._arena_combo.blockSignals(True)
|
|
273
|
-
current_arena_index = self._arena_combo.currentIndex()
|
|
274
|
-
self._arena_combo.clear()
|
|
275
|
-
self._arena_combo.addItem("灰色 (gray)", "gray")
|
|
276
|
-
self._arena_combo.addItem("绿色 (green)", "green")
|
|
277
|
-
self._arena_combo.addItem("蓝色 (blue)", "blue")
|
|
278
|
-
self._arena_combo.addItem("红色 (red)", "red")
|
|
279
|
-
self._arena_combo.setCurrentIndex(current_arena_index)
|
|
280
|
-
self._arena_combo.blockSignals(False)
|
|
281
|
-
|
|
282
|
-
# Update level combo box items
|
|
283
|
-
self._level_combo.blockSignals(True)
|
|
284
|
-
current_level_index = self._level_combo.currentIndex()
|
|
285
|
-
self._level_combo.clear()
|
|
286
|
-
self._level_combo.addItem("基础 (basic)", "basic")
|
|
287
|
-
self._level_combo.addItem("高级 (advanced)", "advanced")
|
|
288
|
-
self._level_combo.setCurrentIndex(current_level_index)
|
|
289
|
-
self._level_combo.blockSignals(False)
|
|
290
|
-
|
|
291
|
-
# Save settings after language change
|
|
292
|
-
self._save_settings()
|
|
293
27
|
|
|
294
28
|
def _init_ui(self):
|
|
295
29
|
"""初始化UI界面"""
|
|
30
|
+
self.setWindowTitle("PyScreeps Arena - 项目创建器")
|
|
31
|
+
self.setWindowIcon(QIcon(get_pixmap()))
|
|
296
32
|
self.setFixedSize(500, 580)
|
|
297
33
|
|
|
298
|
-
#
|
|
299
|
-
|
|
34
|
+
# 主窗口部件
|
|
35
|
+
central_widget = QWidget()
|
|
36
|
+
self.setCentralWidget(central_widget)
|
|
37
|
+
layout = QVBoxLayout(central_widget)
|
|
300
38
|
layout.setSpacing(15)
|
|
301
|
-
|
|
302
|
-
layout.setContentsMargins(15, 15, 15, 30)
|
|
303
|
-
|
|
304
|
-
# 创建项目创建页面
|
|
305
|
-
self._project_page = QWidget()
|
|
306
|
-
self._project_layout = QVBoxLayout(self._project_page)
|
|
307
|
-
self._project_layout.setSpacing(15)
|
|
308
|
-
self._project_layout.setContentsMargins(0, 0, 0, 0)
|
|
309
|
-
|
|
310
|
-
# 创建堆叠容器
|
|
311
|
-
self._stacked_widget = QStackedWidget()
|
|
312
|
-
layout.addWidget(self._stacked_widget)
|
|
39
|
+
layout.setContentsMargins(30, 30, 30, 30)
|
|
313
40
|
|
|
314
41
|
# 标题
|
|
315
|
-
|
|
316
|
-
|
|
42
|
+
title = QLabel("PyScreeps Arena")
|
|
43
|
+
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
317
44
|
title_font = QFont()
|
|
318
45
|
title_font.setPointSize(18)
|
|
319
46
|
title_font.setBold(True)
|
|
320
|
-
|
|
321
|
-
|
|
47
|
+
title.setFont(title_font)
|
|
48
|
+
layout.addWidget(title)
|
|
322
49
|
|
|
323
50
|
# 项目信息
|
|
324
51
|
info_widget = QWidget()
|
|
@@ -326,27 +53,27 @@ class QProjectBody(QWidget):
|
|
|
326
53
|
info_layout.setSpacing(8)
|
|
327
54
|
|
|
328
55
|
# 版本信息
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
info_layout.addWidget(
|
|
56
|
+
version_label = QLabel(f"版本: {const.VERSION}")
|
|
57
|
+
version_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
58
|
+
info_layout.addWidget(version_label)
|
|
332
59
|
|
|
333
60
|
# 作者信息
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
info_layout.addWidget(
|
|
61
|
+
author_label = QLabel(f"作者: {const.AUTHOR}")
|
|
62
|
+
author_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
63
|
+
info_layout.addWidget(author_label)
|
|
337
64
|
|
|
338
65
|
# GitHub信息
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
info_layout.addWidget(
|
|
66
|
+
github_label = QLabel(f"GitHub: {const.GITHUB_NAME}")
|
|
67
|
+
github_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
68
|
+
info_layout.addWidget(github_label)
|
|
342
69
|
|
|
343
|
-
|
|
70
|
+
layout.addWidget(info_widget)
|
|
344
71
|
|
|
345
72
|
# 分隔线
|
|
346
73
|
separator = QLabel("─" * 50)
|
|
347
74
|
separator.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
348
75
|
separator.setStyleSheet("color: #ccc;")
|
|
349
|
-
|
|
76
|
+
layout.addWidget(separator)
|
|
350
77
|
|
|
351
78
|
# 项目输入区域
|
|
352
79
|
input_widget = QWidget()
|
|
@@ -355,20 +82,20 @@ class QProjectBody(QWidget):
|
|
|
355
82
|
|
|
356
83
|
# 项目名称输入
|
|
357
84
|
name_layout = QHBoxLayout()
|
|
358
|
-
|
|
359
|
-
|
|
85
|
+
name_label = QLabel("项目名称:")
|
|
86
|
+
name_label.setFixedWidth(80)
|
|
360
87
|
self._name_input = QLineEdit()
|
|
361
88
|
self._name_input.setPlaceholderText("输入项目名称...")
|
|
362
89
|
self._name_input.textChanged.connect(self._on_name_changed)
|
|
363
90
|
self._name_input.returnPressed.connect(self._create_project)
|
|
364
|
-
name_layout.addWidget(
|
|
91
|
+
name_layout.addWidget(name_label)
|
|
365
92
|
name_layout.addWidget(self._name_input)
|
|
366
93
|
input_layout.addLayout(name_layout)
|
|
367
94
|
|
|
368
95
|
# 项目路径输入
|
|
369
96
|
path_layout = QHBoxLayout()
|
|
370
|
-
|
|
371
|
-
|
|
97
|
+
path_label = QLabel("保存位置:")
|
|
98
|
+
path_label.setFixedWidth(80)
|
|
372
99
|
self._path_input = QLineEdit()
|
|
373
100
|
self._path_input.setPlaceholderText("选择项目保存位置...")
|
|
374
101
|
self._path_input.setReadOnly(True)
|
|
@@ -377,23 +104,23 @@ class QProjectBody(QWidget):
|
|
|
377
104
|
if os.path.exists(desktop_path):
|
|
378
105
|
self._path_input.setText(desktop_path)
|
|
379
106
|
self._proj_path = desktop_path
|
|
380
|
-
path_layout.addWidget(
|
|
107
|
+
path_layout.addWidget(path_label)
|
|
381
108
|
path_layout.addWidget(self._path_input)
|
|
382
109
|
|
|
383
110
|
# 浏览按钮
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
path_layout.addWidget(
|
|
111
|
+
browse_btn = QPushButton("浏览...")
|
|
112
|
+
browse_btn.setFixedWidth(60)
|
|
113
|
+
browse_btn.clicked.connect(self._browse_path)
|
|
114
|
+
path_layout.addWidget(browse_btn)
|
|
388
115
|
|
|
389
116
|
input_layout.addLayout(path_layout)
|
|
390
|
-
|
|
117
|
+
layout.addWidget(input_widget)
|
|
391
118
|
|
|
392
119
|
# 分隔线
|
|
393
120
|
separator2 = QLabel("─" * 50)
|
|
394
121
|
separator2.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
395
122
|
separator2.setStyleSheet("color: #ccc;")
|
|
396
|
-
|
|
123
|
+
layout.addWidget(separator2)
|
|
397
124
|
|
|
398
125
|
# 配置选项区域(左右布局)
|
|
399
126
|
config_container = QWidget()
|
|
@@ -407,43 +134,34 @@ class QProjectBody(QWidget):
|
|
|
407
134
|
|
|
408
135
|
# 语言选择
|
|
409
136
|
lang_layout = QHBoxLayout()
|
|
410
|
-
|
|
411
|
-
|
|
137
|
+
lang_label = QLabel("语 言:")
|
|
138
|
+
lang_label.setFixedWidth(80)
|
|
412
139
|
self._lang_combo = QComboBox()
|
|
413
|
-
|
|
414
|
-
self._lang_combo.addItem("中文 (cn)", "cn")
|
|
415
|
-
self._lang_combo.addItem("英文 (en)", "en")
|
|
140
|
+
self._lang_combo.addItems(["中文 (cn)", "英文 (en)"])
|
|
416
141
|
self._lang_combo.setCurrentIndex(0)
|
|
417
|
-
|
|
418
|
-
lang_layout.addWidget(self._lang_label)
|
|
142
|
+
lang_layout.addWidget(lang_label)
|
|
419
143
|
lang_layout.addWidget(self._lang_combo)
|
|
420
144
|
left_config_layout.addLayout(lang_layout)
|
|
421
145
|
|
|
422
146
|
# 竞技场选择
|
|
423
147
|
arena_layout = QHBoxLayout()
|
|
424
|
-
|
|
425
|
-
|
|
148
|
+
arena_label = QLabel("竞技场:")
|
|
149
|
+
arena_label.setFixedWidth(80)
|
|
426
150
|
self._arena_combo = QComboBox()
|
|
427
|
-
|
|
428
|
-
self._arena_combo.addItem("灰色 (gray)", "gray")
|
|
429
|
-
self._arena_combo.addItem("绿色 (green)", "green")
|
|
430
|
-
self._arena_combo.addItem("蓝色 (blue)", "blue")
|
|
431
|
-
self._arena_combo.addItem("红色 (red)", "red")
|
|
151
|
+
self._arena_combo.addItems(["灰色 (gray)", "绿色 (green)", "蓝色 (blue)", "红色 (red)"])
|
|
432
152
|
self._arena_combo.setCurrentIndex(0)
|
|
433
|
-
arena_layout.addWidget(
|
|
153
|
+
arena_layout.addWidget(arena_label)
|
|
434
154
|
arena_layout.addWidget(self._arena_combo)
|
|
435
155
|
left_config_layout.addLayout(arena_layout)
|
|
436
156
|
|
|
437
157
|
# 难度级别选择
|
|
438
158
|
level_layout = QHBoxLayout()
|
|
439
|
-
|
|
440
|
-
|
|
159
|
+
level_label = QLabel("难 度:")
|
|
160
|
+
level_label.setFixedWidth(80)
|
|
441
161
|
self._level_combo = QComboBox()
|
|
442
|
-
|
|
443
|
-
self._level_combo.addItem("基础 (basic)", "basic")
|
|
444
|
-
self._level_combo.addItem("高级 (advanced)", "advanced")
|
|
162
|
+
self._level_combo.addItems(["基础 (basic)", "高级 (advanced)"])
|
|
445
163
|
self._level_combo.setCurrentIndex(0)
|
|
446
|
-
level_layout.addWidget(
|
|
164
|
+
level_layout.addWidget(level_label)
|
|
447
165
|
level_layout.addWidget(self._level_combo)
|
|
448
166
|
left_config_layout.addLayout(level_layout)
|
|
449
167
|
|
|
@@ -476,22 +194,7 @@ class QProjectBody(QWidget):
|
|
|
476
194
|
|
|
477
195
|
config_container_layout.addWidget(right_config_widget)
|
|
478
196
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
self._project_layout.addStretch()
|
|
482
|
-
|
|
483
|
-
# 加载设置
|
|
484
|
-
self._load_settings()
|
|
485
|
-
|
|
486
|
-
# 创建预制件管理器页面
|
|
487
|
-
self._prefabs_page = QPrefabsManager()
|
|
488
|
-
|
|
489
|
-
# 添加页面到堆叠容器
|
|
490
|
-
self._stacked_widget.addWidget(self._project_page)
|
|
491
|
-
self._stacked_widget.addWidget(self._prefabs_page)
|
|
492
|
-
|
|
493
|
-
# 连接堆叠容器的页面变化信号
|
|
494
|
-
self._stacked_widget.currentChanged.connect(self._on_page_changed)
|
|
197
|
+
layout.addWidget(config_container)
|
|
495
198
|
|
|
496
199
|
# 按钮区域
|
|
497
200
|
button_layout = QHBoxLayout()
|
|
@@ -499,95 +202,36 @@ class QProjectBody(QWidget):
|
|
|
499
202
|
|
|
500
203
|
# 创建按钮
|
|
501
204
|
self._create_btn = QPushButton("创建项目")
|
|
502
|
-
self._create_btn.setFixedSize(
|
|
503
|
-
self._create_btn.clicked.connect(self.
|
|
205
|
+
self._create_btn.setFixedSize(100, 35)
|
|
206
|
+
self._create_btn.clicked.connect(self._create_project)
|
|
504
207
|
self._create_btn.setEnabled(False)
|
|
505
208
|
self._create_btn.setDefault(True)
|
|
506
209
|
button_layout.addWidget(self._create_btn)
|
|
507
210
|
|
|
508
211
|
# 取消按钮
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
button_layout.addWidget(
|
|
212
|
+
cancel_btn = QPushButton("取消")
|
|
213
|
+
cancel_btn.setFixedSize(80, 35)
|
|
214
|
+
cancel_btn.clicked.connect(self.close)
|
|
215
|
+
button_layout.addWidget(cancel_btn)
|
|
513
216
|
|
|
514
|
-
# 添加按钮区域到主布局
|
|
515
217
|
layout.addLayout(button_layout)
|
|
516
|
-
|
|
517
|
-
# 初始更新语言
|
|
518
|
-
# 延迟调用,确保所有UI元素都已创建
|
|
519
|
-
self._update_language()
|
|
520
|
-
|
|
521
|
-
# 初始更新按钮文本
|
|
522
|
-
self._update_button_texts()
|
|
218
|
+
layout.addStretch()
|
|
523
219
|
|
|
524
220
|
def _on_name_changed(self, text):
|
|
525
221
|
"""项目名称改变时的处理"""
|
|
526
222
|
self._proj_name = text.strip()
|
|
527
223
|
self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
|
|
528
|
-
|
|
529
|
-
def _on_cancel(self):
|
|
530
|
-
"""Handle cancel button click"""
|
|
531
|
-
self.projectCancelled.emit()
|
|
532
|
-
# Exit the application when cancel is clicked
|
|
533
|
-
QApplication.quit()
|
|
534
|
-
|
|
535
|
-
def _on_next_or_create(self):
|
|
536
|
-
"""Handle next or create button click"""
|
|
537
|
-
current_index = self._stacked_widget.currentIndex()
|
|
538
|
-
max_index = self._stacked_widget.count() - 1
|
|
539
|
-
|
|
540
|
-
if current_index < max_index:
|
|
541
|
-
# Go to next page
|
|
542
|
-
self._stacked_widget.setCurrentIndex(current_index + 1)
|
|
543
|
-
else:
|
|
544
|
-
# Create project
|
|
545
|
-
self._create_project()
|
|
546
|
-
|
|
547
|
-
def _on_previous_or_cancel(self):
|
|
548
|
-
"""Handle previous or cancel button click"""
|
|
549
|
-
current_index = self._stacked_widget.currentIndex()
|
|
550
|
-
|
|
551
|
-
if current_index > 0:
|
|
552
|
-
# Go to previous page
|
|
553
|
-
self._stacked_widget.setCurrentIndex(current_index - 1)
|
|
554
|
-
else:
|
|
555
|
-
# Cancel
|
|
556
|
-
self._on_cancel()
|
|
557
|
-
|
|
558
|
-
def _on_page_changed(self, index):
|
|
559
|
-
"""Handle page changed signal"""
|
|
560
|
-
self._update_button_texts()
|
|
561
|
-
|
|
562
|
-
def _update_button_texts(self):
|
|
563
|
-
"""Update button texts based on current page index"""
|
|
564
|
-
current_index = self._stacked_widget.currentIndex()
|
|
565
|
-
max_index = self._stacked_widget.count() - 1
|
|
566
|
-
|
|
567
|
-
# Update create/next button
|
|
568
|
-
if current_index < max_index:
|
|
569
|
-
self._create_btn.setText(self.lang('next_page'))
|
|
570
|
-
else:
|
|
571
|
-
self._create_btn.setText(self.lang('create_project'))
|
|
572
|
-
|
|
573
|
-
# Update cancel/previous button
|
|
574
|
-
if current_index == 0:
|
|
575
|
-
self._cancel_btn.setText(self.lang('cancel'))
|
|
576
|
-
else:
|
|
577
|
-
self._cancel_btn.setText(self.lang('previous_page'))
|
|
578
224
|
|
|
579
225
|
def _browse_path(self):
|
|
580
226
|
"""浏览选择路径"""
|
|
581
227
|
current_path = self._path_input.text() or os.path.expanduser("~")
|
|
582
228
|
path = QFileDialog.getExistingDirectory(
|
|
583
|
-
self,
|
|
229
|
+
self, "选择项目保存位置", current_path
|
|
584
230
|
)
|
|
585
231
|
if path:
|
|
586
232
|
self._path_input.setText(path)
|
|
587
233
|
self._proj_path = path
|
|
588
234
|
self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
|
|
589
|
-
# Save settings after path change
|
|
590
|
-
self._save_settings()
|
|
591
235
|
|
|
592
236
|
def _create_project(self):
|
|
593
237
|
"""创建项目"""
|
|
@@ -600,8 +244,8 @@ class QProjectBody(QWidget):
|
|
|
600
244
|
# 检查路径是否已存在
|
|
601
245
|
if os.path.exists(full_path):
|
|
602
246
|
reply = QMessageBox.question(
|
|
603
|
-
self,
|
|
604
|
-
|
|
247
|
+
self, "路径已存在",
|
|
248
|
+
f"路径 '{full_path}' 已存在。\n是否继续?",
|
|
605
249
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
|
606
250
|
)
|
|
607
251
|
if reply != QMessageBox.StandardButton.Yes:
|
|
@@ -612,22 +256,15 @@ class QProjectBody(QWidget):
|
|
|
612
256
|
self._extract_project_template(full_path)
|
|
613
257
|
|
|
614
258
|
QMessageBox.information(
|
|
615
|
-
self,
|
|
616
|
-
|
|
259
|
+
self, "成功",
|
|
260
|
+
f"项目 '{self._proj_name}' 创建成功!\n路径: {full_path}"
|
|
617
261
|
)
|
|
618
|
-
|
|
619
|
-
# 处理预制件
|
|
620
|
-
self._process_prefabs(full_path)
|
|
621
|
-
|
|
622
|
-
self.projectCreated.emit(self._proj_name, full_path)
|
|
623
|
-
|
|
624
|
-
# 成功创建项目后关闭程序
|
|
625
|
-
QApplication.quit()
|
|
262
|
+
self.close()
|
|
626
263
|
|
|
627
264
|
except Exception as e:
|
|
628
265
|
QMessageBox.critical(
|
|
629
|
-
self,
|
|
630
|
-
|
|
266
|
+
self, "错误",
|
|
267
|
+
f"项目创建失败:\n{str(e)}"
|
|
631
268
|
)
|
|
632
269
|
|
|
633
270
|
def _extract_project_template(self, target_path):
|
|
@@ -650,9 +287,14 @@ class QProjectBody(QWidget):
|
|
|
650
287
|
print(f"[DEBUG] 项目模板已解压到: {target_path}") # 调试输出
|
|
651
288
|
|
|
652
289
|
# 获取用户选择的配置
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
290
|
+
lang_text = self._lang_combo.currentText()
|
|
291
|
+
lang = lang_text.split('(')[1].strip(')')
|
|
292
|
+
|
|
293
|
+
arena_text = self._arena_combo.currentText()
|
|
294
|
+
arena = arena_text.split('(')[1].strip(')')
|
|
295
|
+
|
|
296
|
+
level_text = self._level_combo.currentText()
|
|
297
|
+
level = level_text.split('(')[1].strip(')')
|
|
656
298
|
|
|
657
299
|
# 调用配置方法
|
|
658
300
|
ToConfigAfter(path=target_path, language=lang, arena=arena, level=level)
|
|
@@ -672,268 +314,6 @@ class QProjectBody(QWidget):
|
|
|
672
314
|
print(f"[DEBUG] 执行预设继承模式配置")
|
|
673
315
|
ToPrefabAfter(path=target_path)
|
|
674
316
|
ToCustomAfter(path=target_path)
|
|
675
|
-
|
|
676
|
-
# Properties
|
|
677
|
-
@pyqtProperty(str, constant=False)
|
|
678
|
-
def projectName(self) -> str:
|
|
679
|
-
"""Get project name"""
|
|
680
|
-
return self._proj_name
|
|
681
|
-
|
|
682
|
-
@projectName.setter
|
|
683
|
-
def projectName(self, value: str):
|
|
684
|
-
"""Set project name"""
|
|
685
|
-
self._proj_name = value.strip()
|
|
686
|
-
self._name_input.setText(self._proj_name)
|
|
687
|
-
self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
|
|
688
|
-
|
|
689
|
-
@pyqtProperty(str, constant=False)
|
|
690
|
-
def projectPath(self) -> str:
|
|
691
|
-
"""Get project path"""
|
|
692
|
-
return self._proj_path
|
|
693
|
-
|
|
694
|
-
@projectPath.setter
|
|
695
|
-
def projectPath(self, value: str):
|
|
696
|
-
"""Set project path"""
|
|
697
|
-
self._proj_path = value
|
|
698
|
-
self._path_input.setText(self._proj_path)
|
|
699
|
-
self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
|
|
700
|
-
|
|
701
|
-
@pyqtProperty(str, constant=False)
|
|
702
|
-
def language(self) -> str:
|
|
703
|
-
"""Get current language code"""
|
|
704
|
-
return self._lang_combo.currentData() or 'cn'
|
|
705
|
-
|
|
706
|
-
@language.setter
|
|
707
|
-
def language(self, value: str):
|
|
708
|
-
"""Set language code"""
|
|
709
|
-
if value == 'cn':
|
|
710
|
-
self._lang_combo.setCurrentIndex(0)
|
|
711
|
-
elif value == 'en':
|
|
712
|
-
self._lang_combo.setCurrentIndex(1)
|
|
713
|
-
|
|
714
|
-
def _process_prefabs(self, project_path: str):
|
|
715
|
-
"""
|
|
716
|
-
Process selected prefabs: copy them to src directory, handle naming conflicts,
|
|
717
|
-
and add import statements to main.py
|
|
718
|
-
|
|
719
|
-
Args:
|
|
720
|
-
project_path: Path to the newly created project
|
|
721
|
-
"""
|
|
722
|
-
print(f"Processing prefabs for project: {project_path}")
|
|
723
|
-
|
|
724
|
-
# Check if QPrefabsManager exists and has selected prefabs
|
|
725
|
-
if hasattr(self, '_prefabs_page'):
|
|
726
|
-
# Get selected prefabs as list
|
|
727
|
-
selected_prefabs = self._prefabs_page.selectedPrefabs
|
|
728
|
-
print(f"Selected prefabs: {selected_prefabs}")
|
|
729
|
-
|
|
730
|
-
if selected_prefabs:
|
|
731
|
-
# Convert to dict format using list_to_dict method
|
|
732
|
-
prefabs_dict = self._prefabs_page.list_to_dict(selected_prefabs)
|
|
733
|
-
print(f"Prefabs dict: {prefabs_dict}")
|
|
734
|
-
|
|
735
|
-
# Create src directory if it doesn't exist
|
|
736
|
-
src_dir = os.path.join(project_path, 'src')
|
|
737
|
-
os.makedirs(src_dir, exist_ok=True)
|
|
738
|
-
print(f"Src directory: {src_dir}")
|
|
739
|
-
|
|
740
|
-
# Get existing directory names in src
|
|
741
|
-
existing_dirs = [d for d in os.listdir(src_dir) if os.path.isdir(os.path.join(src_dir, d))]
|
|
742
|
-
print(f"Existing dirs in src: {existing_dirs}")
|
|
743
|
-
|
|
744
|
-
# Process each prefab
|
|
745
|
-
imported_modules = []
|
|
746
|
-
|
|
747
|
-
for name, path in prefabs_dict.items():
|
|
748
|
-
# Clean directory name: replace non-alphanumeric and non-underscore characters with underscore
|
|
749
|
-
clean_name = ''.join(c if c.isalnum() or c == '_' else '_' for c in name)
|
|
750
|
-
|
|
751
|
-
# Handle naming conflicts
|
|
752
|
-
final_name = clean_name
|
|
753
|
-
i = 2
|
|
754
|
-
while final_name in existing_dirs:
|
|
755
|
-
final_name = f"{clean_name}_{i}"
|
|
756
|
-
i += 1
|
|
757
|
-
|
|
758
|
-
# Add to existing_dirs to avoid conflicts with subsequent prefabs
|
|
759
|
-
existing_dirs.append(final_name)
|
|
760
|
-
|
|
761
|
-
# Target directory path
|
|
762
|
-
target_dir = os.path.join(src_dir, final_name)
|
|
763
|
-
|
|
764
|
-
# Copy directory from path to target_dir
|
|
765
|
-
import shutil
|
|
766
|
-
try:
|
|
767
|
-
shutil.copytree(path, target_dir)
|
|
768
|
-
imported_modules.append(final_name)
|
|
769
|
-
print(f"Copied prefab {name} to {target_dir}")
|
|
770
|
-
except Exception as e:
|
|
771
|
-
print(f"Error copying prefab {name}: {e}")
|
|
772
|
-
|
|
773
|
-
# Add import statements to main.py
|
|
774
|
-
if imported_modules:
|
|
775
|
-
main_py_path = os.path.join(project_path, 'src', 'main.py')
|
|
776
|
-
print(f"Main.py path: {main_py_path}")
|
|
777
|
-
if os.path.exists(main_py_path):
|
|
778
|
-
# Read main.py content
|
|
779
|
-
with open(main_py_path, 'r', encoding='utf-8') as f:
|
|
780
|
-
content = f.read()
|
|
781
|
-
print(f"Main.py content:\n{content}")
|
|
782
|
-
|
|
783
|
-
# Find the end of import statements
|
|
784
|
-
import_end = 0
|
|
785
|
-
lines = content.split('\n')
|
|
786
|
-
# Iterate through all lines to find the last import statement
|
|
787
|
-
for i, line in enumerate(lines):
|
|
788
|
-
if line.strip().startswith('from ') or line.strip().startswith('import '):
|
|
789
|
-
import_end = i + 1
|
|
790
|
-
elif import_end > 0 and line.strip() == '':
|
|
791
|
-
# Keep moving past empty lines after imports
|
|
792
|
-
import_end = i + 1
|
|
793
|
-
elif import_end > 0 and line.strip() != '':
|
|
794
|
-
# Stop when we reach non-empty, non-import line
|
|
795
|
-
break
|
|
796
|
-
# If no imports found, add at the beginning
|
|
797
|
-
print(f"Import end position: {import_end}")
|
|
798
|
-
|
|
799
|
-
# Add import statements
|
|
800
|
-
import_lines = []
|
|
801
|
-
for module in imported_modules:
|
|
802
|
-
import_lines.append(f"from {module} import *")
|
|
803
|
-
print(f"Import lines to add: {import_lines}")
|
|
804
|
-
|
|
805
|
-
# Process the content to properly format imports
|
|
806
|
-
# First, separate the content into import section and code section
|
|
807
|
-
import_section = []
|
|
808
|
-
code_section = []
|
|
809
|
-
in_imports = True
|
|
810
|
-
|
|
811
|
-
for line in lines:
|
|
812
|
-
if in_imports:
|
|
813
|
-
if line.strip().startswith('from ') or line.strip().startswith('import '):
|
|
814
|
-
import_section.append(line.strip())
|
|
815
|
-
elif line.strip() == '':
|
|
816
|
-
# Skip empty lines in import section
|
|
817
|
-
pass
|
|
818
|
-
else:
|
|
819
|
-
# Reached end of imports
|
|
820
|
-
in_imports = False
|
|
821
|
-
code_section.append(line)
|
|
822
|
-
else:
|
|
823
|
-
# Add all other lines to code section
|
|
824
|
-
code_section.append(line)
|
|
825
|
-
|
|
826
|
-
# Add new imports to import section
|
|
827
|
-
import_section.extend(import_lines)
|
|
828
|
-
|
|
829
|
-
# Create properly formatted content
|
|
830
|
-
# Join imports without empty lines between them
|
|
831
|
-
import_text = '\n'.join(import_section)
|
|
832
|
-
# Join code section as is
|
|
833
|
-
code_text = '\n'.join(code_section)
|
|
834
|
-
# Combine with exactly two empty lines between imports and code
|
|
835
|
-
new_content = import_text + '\n\n\n' + code_text
|
|
836
|
-
print(f"New main.py content:\n{new_content}")
|
|
837
|
-
|
|
838
|
-
# Write back to main.py
|
|
839
|
-
with open(main_py_path, 'w', encoding='utf-8') as f:
|
|
840
|
-
f.write(new_content)
|
|
841
|
-
|
|
842
|
-
print(f"Added import statements for {len(imported_modules)} modules to main.py")
|
|
843
|
-
|
|
844
|
-
# Verify the changes
|
|
845
|
-
with open(main_py_path, 'r', encoding='utf-8') as f:
|
|
846
|
-
verify_content = f.read()
|
|
847
|
-
print(f"Verified main.py content:\n{verify_content}")
|
|
848
|
-
else:
|
|
849
|
-
print(f"Main.py not found at {main_py_path}")
|
|
850
|
-
else:
|
|
851
|
-
print("No modules to import")
|
|
852
|
-
else:
|
|
853
|
-
print("No selected prefabs")
|
|
854
|
-
else:
|
|
855
|
-
print("No QPrefabsManager found")
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
class ProjectCreatorUI(QMainWindow):
|
|
859
|
-
"""Project creator main window"""
|
|
860
|
-
|
|
861
|
-
def __init__(self):
|
|
862
|
-
super().__init__()
|
|
863
|
-
self._init_ui()
|
|
864
|
-
|
|
865
|
-
def _init_ui(self):
|
|
866
|
-
"""Initialize main window"""
|
|
867
|
-
self.setWindowTitle("PyScreeps Arena - Project Wizard")
|
|
868
|
-
self.setWindowIcon(QIcon(get_pixmap()))
|
|
869
|
-
|
|
870
|
-
# Create central widget
|
|
871
|
-
central_widget = QWidget()
|
|
872
|
-
self.setCentralWidget(central_widget)
|
|
873
|
-
|
|
874
|
-
# Create main layout
|
|
875
|
-
layout = QVBoxLayout(central_widget)
|
|
876
|
-
layout.setContentsMargins(10, 10, 10, 10)
|
|
877
|
-
|
|
878
|
-
# Create project body widget
|
|
879
|
-
self._project_body = QProjectBody()
|
|
880
|
-
|
|
881
|
-
# Connect signals
|
|
882
|
-
self._project_body.projectCreated.connect(self._on_project_created)
|
|
883
|
-
self._project_body.projectCancelled.connect(self._on_project_cancelled)
|
|
884
|
-
self._project_body.languageChanged.connect(self._on_language_changed)
|
|
885
|
-
|
|
886
|
-
# Add project body to layout
|
|
887
|
-
layout.addWidget(self._project_body)
|
|
888
|
-
|
|
889
|
-
# Set window size
|
|
890
|
-
self.setFixedSize(550, 650)
|
|
891
|
-
|
|
892
|
-
def _on_project_created(self, project_name: str, project_path: str):
|
|
893
|
-
"""Handle project created signal"""
|
|
894
|
-
print(f"Project created: {project_name} at {project_path}")
|
|
895
|
-
# You can add additional handling here if needed
|
|
896
|
-
|
|
897
|
-
def _on_project_cancelled(self):
|
|
898
|
-
"""Handle project cancelled signal"""
|
|
899
|
-
print("Project creation cancelled")
|
|
900
|
-
# You can add additional handling here if needed
|
|
901
|
-
|
|
902
|
-
def _on_language_changed(self, language_code: str):
|
|
903
|
-
"""Handle language changed signal"""
|
|
904
|
-
print(f"Language changed to: {language_code}")
|
|
905
|
-
# You can add additional handling here if needed
|
|
906
|
-
|
|
907
|
-
# Properties to expose project body properties
|
|
908
|
-
@pyqtProperty(str, constant=False)
|
|
909
|
-
def projectName(self) -> str:
|
|
910
|
-
"""Get project name"""
|
|
911
|
-
return self._project_body.projectName
|
|
912
|
-
|
|
913
|
-
@projectName.setter
|
|
914
|
-
def projectName(self, value: str):
|
|
915
|
-
"""Set project name"""
|
|
916
|
-
self._project_body.projectName = value
|
|
917
|
-
|
|
918
|
-
@pyqtProperty(str, constant=False)
|
|
919
|
-
def projectPath(self) -> str:
|
|
920
|
-
"""Get project path"""
|
|
921
|
-
return self._project_body.projectPath
|
|
922
|
-
|
|
923
|
-
@projectPath.setter
|
|
924
|
-
def projectPath(self, value: str):
|
|
925
|
-
"""Set project path"""
|
|
926
|
-
self._project_body.projectPath = value
|
|
927
|
-
|
|
928
|
-
@pyqtProperty(str, constant=False)
|
|
929
|
-
def language(self) -> str:
|
|
930
|
-
"""Get current language code"""
|
|
931
|
-
return self._project_body.language
|
|
932
|
-
|
|
933
|
-
@language.setter
|
|
934
|
-
def language(self, value: str):
|
|
935
|
-
"""Set language code"""
|
|
936
|
-
self._project_body.language = value
|
|
937
317
|
|
|
938
318
|
|
|
939
319
|
def run_project_creator():
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
pyscreeps_arena/__init__.py,sha256=GWrCpZnrzPwbBzhNqk8gTvV4VSwkP2DbxK8lR0E_SzY,3223
|
|
2
2
|
pyscreeps_arena/build.py,sha256=DQeGLnID2FjpsWTbnqwt2cOp28olWK68U67bfbFJSOU,177
|
|
3
|
-
pyscreeps_arena/compiler.py,sha256=
|
|
3
|
+
pyscreeps_arena/compiler.py,sha256=QLmpxt_qoCQHp9EQ4wnDAuKndlV1rA8E6_DFEUatEuw,70509
|
|
4
4
|
pyscreeps_arena/localization.py,sha256=Dr0G6n8DvT6syfC0urqwjccYpEPEfcwYyJx3f9s-6a8,6031
|
|
5
|
-
pyscreeps_arena/project.7z,sha256=
|
|
5
|
+
pyscreeps_arena/project.7z,sha256=25YVsfwEr9Ksx33oShFGB7iAGwta2uJD1IVuf5JVXLU,546405
|
|
6
6
|
pyscreeps_arena/afters/__init__.py,sha256=Ze8NKQoMEzIJ3WlyR8Jhhdq21gSXJUtGoINzB8iaQyE,254
|
|
7
7
|
pyscreeps_arena/afters/after_config.py,sha256=Tw8Qry0KAM3hDasmXArKoS1crPuwfiAfWiEeAcKrPdo,2455
|
|
8
8
|
pyscreeps_arena/afters/after_custom.py,sha256=pgI5xkY4X7w_NHFufQ5PUGxpCrv9Ayw6VWFwVJCHLFw,3226
|
|
@@ -11,7 +11,7 @@ pyscreeps_arena/afters/after_prefab.py,sha256=H_2LJbr_7e2yCtxWStxze259-py3TXQlyP
|
|
|
11
11
|
pyscreeps_arena/core/__init__.py,sha256=qoP_rx1TpbDLJoTm5via4XPwEPaV1FXr1SYvoVoHGms,41
|
|
12
12
|
pyscreeps_arena/core/basic.py,sha256=DFvyDTsTXf2bQtnS9s254TrkshvRwajaHcvTyVvJyqw,2790
|
|
13
13
|
pyscreeps_arena/core/config.py,sha256=x_JhVHlVZqB3qA7UyACVnwZjg2gZU-BIs49UxZzwCoE,637
|
|
14
|
-
pyscreeps_arena/core/const.py,sha256=
|
|
14
|
+
pyscreeps_arena/core/const.py,sha256=RQesh9t-dNiLegCOBHMqlF_TFcIuL-cTghUVR3X55BA,590
|
|
15
15
|
pyscreeps_arena/core/core.py,sha256=3Nty8eLKPNgwnYk_sVNBPrWuKxBXI2od8nfEezsEAZQ,5157
|
|
16
16
|
pyscreeps_arena/core/main.py,sha256=-FNSOEjksNlDfCbUqsjtPSUW8vT3qxEdfzXqT5Tdsik,170
|
|
17
17
|
pyscreeps_arena/core/utils.py,sha256=N9OOkORvrqnJakayaFp9qyS0apWhB9lBK4xyyYkhFdo,215
|
|
@@ -20,7 +20,7 @@ pyscreeps_arena/ui/__init__.py,sha256=rxSx5ZPxMNUVokvYgOmGkxHInFUVVYh9InSbbvkgo2
|
|
|
20
20
|
pyscreeps_arena/ui/creeplogic_edit.py,sha256=XlO4aoH48UyWhQQAejyLY57yukpn9BzS0w9QXMMOeeg,314
|
|
21
21
|
pyscreeps_arena/ui/map_render.py,sha256=dS7iL5ywEwlhGEOiif0G9up3bpPI4p20o07mbnDaSD8,30414
|
|
22
22
|
pyscreeps_arena/ui/mapviewer.py,sha256=AWv9loznosIJaQC5L5szRms_zDetDiHXIsY2EEpRNB8,293
|
|
23
|
-
pyscreeps_arena/ui/project_ui.py,sha256=
|
|
23
|
+
pyscreeps_arena/ui/project_ui.py,sha256=6LTwRHqfyb1R2ry13Xtq41vCANEJL96-hqXposNr81M,12580
|
|
24
24
|
pyscreeps_arena/ui/rs_icon.py,sha256=5v8YdTv2dds4iAp9x3MXpqB_5XIOYd0uPqaq83ZNySM,22496
|
|
25
25
|
pyscreeps_arena/ui/qcreeplogic/__init__.py,sha256=FVuJ6TZyDh5WnkYlHjCWjEKGPBWl27LzqIAab-4aeuI,75
|
|
26
26
|
pyscreeps_arena/ui/qcreeplogic/model.py,sha256=_Ba5jbHcFsKQ1el36UcCnXGUimvvWSRHgzo979SpVzs,2833
|
|
@@ -45,8 +45,8 @@ pyscreeps_arena/ui/qmapv/test_simple_array.py,sha256=hPnLXcFrn6I1X4JXFM3RVpBPhU_
|
|
|
45
45
|
pyscreeps_arena/ui/qrecipe/__init__.py,sha256=2Guvr9k5kGkZboiVC0aNF4u48LRbmcCm2dqOhEF52Tw,59
|
|
46
46
|
pyscreeps_arena/ui/qrecipe/model.py,sha256=s3lr_DXtsBgt8bVg1_wLz-dX88QKi77mNkqM5VJsGwE,13200
|
|
47
47
|
pyscreeps_arena/ui/qrecipe/qrecipe.py,sha256=z57VLmlpMripdpGtVCkKR0csJQhw5-WpocZK5l2xTVg,39398
|
|
48
|
-
pyscreeps_arena-0.5.
|
|
49
|
-
pyscreeps_arena-0.5.
|
|
50
|
-
pyscreeps_arena-0.5.
|
|
51
|
-
pyscreeps_arena-0.5.
|
|
52
|
-
pyscreeps_arena-0.5.
|
|
48
|
+
pyscreeps_arena-0.5.9b0.dist-info/METADATA,sha256=2f9814ViuZUlIAKwsXO_i-1nnnQGjerGRb3Ur0r8eAU,2356
|
|
49
|
+
pyscreeps_arena-0.5.9b0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
50
|
+
pyscreeps_arena-0.5.9b0.dist-info/entry_points.txt,sha256=pnpuPPadwQsxQPaR1rXzUo0fUvhOcC7HTHlf7TYXr7M,141
|
|
51
|
+
pyscreeps_arena-0.5.9b0.dist-info/top_level.txt,sha256=l4uLyMR2NOy41ngBMh795jOHTFk3tgYKy64-9cgjVng,16
|
|
52
|
+
pyscreeps_arena-0.5.9b0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|