pyscreeps-arena 0.5.9b2__py3-none-any.whl → 0.5.9b3__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/ui/project_ui.py +695 -75
- {pyscreeps_arena-0.5.9b2.dist-info → pyscreeps_arena-0.5.9b3.dist-info}/METADATA +1 -1
- {pyscreeps_arena-0.5.9b2.dist-info → pyscreeps_arena-0.5.9b3.dist-info}/RECORD +6 -6
- {pyscreeps_arena-0.5.9b2.dist-info → pyscreeps_arena-0.5.9b3.dist-info}/WHEEL +0 -0
- {pyscreeps_arena-0.5.9b2.dist-info → pyscreeps_arena-0.5.9b3.dist-info}/entry_points.txt +0 -0
- {pyscreeps_arena-0.5.9b2.dist-info → pyscreeps_arena-0.5.9b3.dist-info}/top_level.txt +0 -0
pyscreeps_arena/ui/project_ui.py
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
"""
|
|
5
5
|
import sys
|
|
6
6
|
import os
|
|
7
|
+
import json
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
|
|
9
10
|
QHBoxLayout, QLabel, QLineEdit, QPushButton,
|
|
10
|
-
QFileDialog, QMessageBox, QComboBox)
|
|
11
|
-
from
|
|
11
|
+
QFileDialog, QMessageBox, QComboBox, QStackedWidget)
|
|
12
|
+
from pyscreeps_arena.ui.qprefabs.qprefabs import QPrefabsManager
|
|
13
|
+
from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty
|
|
12
14
|
from PyQt6.QtGui import QFont
|
|
13
15
|
from PyQt6.QtGui import QIcon
|
|
14
16
|
from pyscreeps_arena.core import const
|
|
@@ -16,36 +18,307 @@ from pyscreeps_arena.ui.rs_icon import get_pixmap
|
|
|
16
18
|
from pyscreeps_arena.afters import ToConfigAfter, ToEmptyAfter, ToPrefabAfter, ToCustomAfter
|
|
17
19
|
from PyQt6.QtWidgets import QRadioButton, QGroupBox
|
|
18
20
|
|
|
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
|
+
}
|
|
19
84
|
|
|
20
85
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
86
|
+
|
|
87
|
+
class QProjectBody(QWidget):
|
|
88
|
+
"""Project creation body widget"""
|
|
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)
|
|
24
97
|
self._proj_name = ""
|
|
25
98
|
self._proj_path = ""
|
|
26
99
|
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()
|
|
27
293
|
|
|
28
294
|
def _init_ui(self):
|
|
29
295
|
"""初始化UI界面"""
|
|
30
|
-
self.setWindowTitle("PyScreeps Arena - 项目创建器")
|
|
31
|
-
self.setWindowIcon(QIcon(get_pixmap()))
|
|
32
296
|
self.setFixedSize(500, 580)
|
|
33
297
|
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
self.setCentralWidget(central_widget)
|
|
37
|
-
layout = QVBoxLayout(central_widget)
|
|
298
|
+
# 主布局
|
|
299
|
+
layout = QVBoxLayout(self)
|
|
38
300
|
layout.setSpacing(15)
|
|
39
|
-
|
|
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)
|
|
40
313
|
|
|
41
314
|
# 标题
|
|
42
|
-
|
|
43
|
-
|
|
315
|
+
self._title_label = QLabel("PyScreeps Arena")
|
|
316
|
+
self._title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
44
317
|
title_font = QFont()
|
|
45
318
|
title_font.setPointSize(18)
|
|
46
319
|
title_font.setBold(True)
|
|
47
|
-
|
|
48
|
-
|
|
320
|
+
self._title_label.setFont(title_font)
|
|
321
|
+
self._project_layout.addWidget(self._title_label)
|
|
49
322
|
|
|
50
323
|
# 项目信息
|
|
51
324
|
info_widget = QWidget()
|
|
@@ -53,27 +326,27 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
53
326
|
info_layout.setSpacing(8)
|
|
54
327
|
|
|
55
328
|
# 版本信息
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
info_layout.addWidget(
|
|
329
|
+
self._version_label = QLabel(f"版本: {const.VERSION}")
|
|
330
|
+
self._version_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
331
|
+
info_layout.addWidget(self._version_label)
|
|
59
332
|
|
|
60
333
|
# 作者信息
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
info_layout.addWidget(
|
|
334
|
+
self._author_label = QLabel(f"作者: {const.AUTHOR}")
|
|
335
|
+
self._author_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
336
|
+
info_layout.addWidget(self._author_label)
|
|
64
337
|
|
|
65
338
|
# GitHub信息
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
info_layout.addWidget(
|
|
339
|
+
self._github_label = QLabel(f"GitHub: {const.GITHUB_NAME}")
|
|
340
|
+
self._github_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
341
|
+
info_layout.addWidget(self._github_label)
|
|
69
342
|
|
|
70
|
-
|
|
343
|
+
self._project_layout.addWidget(info_widget)
|
|
71
344
|
|
|
72
345
|
# 分隔线
|
|
73
346
|
separator = QLabel("─" * 50)
|
|
74
347
|
separator.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
75
348
|
separator.setStyleSheet("color: #ccc;")
|
|
76
|
-
|
|
349
|
+
self._project_layout.addWidget(separator)
|
|
77
350
|
|
|
78
351
|
# 项目输入区域
|
|
79
352
|
input_widget = QWidget()
|
|
@@ -82,20 +355,20 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
82
355
|
|
|
83
356
|
# 项目名称输入
|
|
84
357
|
name_layout = QHBoxLayout()
|
|
85
|
-
|
|
86
|
-
|
|
358
|
+
self._name_label = QLabel("项目名称:")
|
|
359
|
+
self._name_label.setFixedWidth(80)
|
|
87
360
|
self._name_input = QLineEdit()
|
|
88
361
|
self._name_input.setPlaceholderText("输入项目名称...")
|
|
89
362
|
self._name_input.textChanged.connect(self._on_name_changed)
|
|
90
363
|
self._name_input.returnPressed.connect(self._create_project)
|
|
91
|
-
name_layout.addWidget(
|
|
364
|
+
name_layout.addWidget(self._name_label)
|
|
92
365
|
name_layout.addWidget(self._name_input)
|
|
93
366
|
input_layout.addLayout(name_layout)
|
|
94
367
|
|
|
95
368
|
# 项目路径输入
|
|
96
369
|
path_layout = QHBoxLayout()
|
|
97
|
-
|
|
98
|
-
|
|
370
|
+
self._path_label = QLabel("保存位置:")
|
|
371
|
+
self._path_label.setFixedWidth(80)
|
|
99
372
|
self._path_input = QLineEdit()
|
|
100
373
|
self._path_input.setPlaceholderText("选择项目保存位置...")
|
|
101
374
|
self._path_input.setReadOnly(True)
|
|
@@ -104,23 +377,23 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
104
377
|
if os.path.exists(desktop_path):
|
|
105
378
|
self._path_input.setText(desktop_path)
|
|
106
379
|
self._proj_path = desktop_path
|
|
107
|
-
path_layout.addWidget(
|
|
380
|
+
path_layout.addWidget(self._path_label)
|
|
108
381
|
path_layout.addWidget(self._path_input)
|
|
109
382
|
|
|
110
383
|
# 浏览按钮
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
path_layout.addWidget(
|
|
384
|
+
self._browse_btn = QPushButton("浏览...")
|
|
385
|
+
self._browse_btn.setFixedWidth(80)
|
|
386
|
+
self._browse_btn.clicked.connect(self._browse_path)
|
|
387
|
+
path_layout.addWidget(self._browse_btn)
|
|
115
388
|
|
|
116
389
|
input_layout.addLayout(path_layout)
|
|
117
|
-
|
|
390
|
+
self._project_layout.addWidget(input_widget)
|
|
118
391
|
|
|
119
392
|
# 分隔线
|
|
120
393
|
separator2 = QLabel("─" * 50)
|
|
121
394
|
separator2.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
122
395
|
separator2.setStyleSheet("color: #ccc;")
|
|
123
|
-
|
|
396
|
+
self._project_layout.addWidget(separator2)
|
|
124
397
|
|
|
125
398
|
# 配置选项区域(左右布局)
|
|
126
399
|
config_container = QWidget()
|
|
@@ -134,34 +407,43 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
134
407
|
|
|
135
408
|
# 语言选择
|
|
136
409
|
lang_layout = QHBoxLayout()
|
|
137
|
-
|
|
138
|
-
|
|
410
|
+
self._lang_label = QLabel("语 言:")
|
|
411
|
+
self._lang_label.setFixedWidth(80)
|
|
139
412
|
self._lang_combo = QComboBox()
|
|
140
|
-
|
|
413
|
+
# 语言选项
|
|
414
|
+
self._lang_combo.addItem("中文 (cn)", "cn")
|
|
415
|
+
self._lang_combo.addItem("英文 (en)", "en")
|
|
141
416
|
self._lang_combo.setCurrentIndex(0)
|
|
142
|
-
|
|
417
|
+
self._lang_combo.currentIndexChanged.connect(self._update_language)
|
|
418
|
+
lang_layout.addWidget(self._lang_label)
|
|
143
419
|
lang_layout.addWidget(self._lang_combo)
|
|
144
420
|
left_config_layout.addLayout(lang_layout)
|
|
145
421
|
|
|
146
422
|
# 竞技场选择
|
|
147
423
|
arena_layout = QHBoxLayout()
|
|
148
|
-
|
|
149
|
-
|
|
424
|
+
self._arena_label = QLabel("竞技场:")
|
|
425
|
+
self._arena_label.setFixedWidth(80)
|
|
150
426
|
self._arena_combo = QComboBox()
|
|
151
|
-
|
|
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")
|
|
152
432
|
self._arena_combo.setCurrentIndex(0)
|
|
153
|
-
arena_layout.addWidget(
|
|
433
|
+
arena_layout.addWidget(self._arena_label)
|
|
154
434
|
arena_layout.addWidget(self._arena_combo)
|
|
155
435
|
left_config_layout.addLayout(arena_layout)
|
|
156
436
|
|
|
157
437
|
# 难度级别选择
|
|
158
438
|
level_layout = QHBoxLayout()
|
|
159
|
-
|
|
160
|
-
|
|
439
|
+
self._level_label = QLabel("难 度:")
|
|
440
|
+
self._level_label.setFixedWidth(80)
|
|
161
441
|
self._level_combo = QComboBox()
|
|
162
|
-
|
|
442
|
+
# 难度选项
|
|
443
|
+
self._level_combo.addItem("基础 (basic)", "basic")
|
|
444
|
+
self._level_combo.addItem("高级 (advanced)", "advanced")
|
|
163
445
|
self._level_combo.setCurrentIndex(0)
|
|
164
|
-
level_layout.addWidget(
|
|
446
|
+
level_layout.addWidget(self._level_label)
|
|
165
447
|
level_layout.addWidget(self._level_combo)
|
|
166
448
|
left_config_layout.addLayout(level_layout)
|
|
167
449
|
|
|
@@ -194,7 +476,22 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
194
476
|
|
|
195
477
|
config_container_layout.addWidget(right_config_widget)
|
|
196
478
|
|
|
197
|
-
|
|
479
|
+
self._project_layout.addWidget(config_container)
|
|
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)
|
|
198
495
|
|
|
199
496
|
# 按钮区域
|
|
200
497
|
button_layout = QHBoxLayout()
|
|
@@ -202,36 +499,95 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
202
499
|
|
|
203
500
|
# 创建按钮
|
|
204
501
|
self._create_btn = QPushButton("创建项目")
|
|
205
|
-
self._create_btn.setFixedSize(
|
|
206
|
-
self._create_btn.clicked.connect(self.
|
|
502
|
+
self._create_btn.setFixedSize(120, 35)
|
|
503
|
+
self._create_btn.clicked.connect(self._on_next_or_create)
|
|
207
504
|
self._create_btn.setEnabled(False)
|
|
208
505
|
self._create_btn.setDefault(True)
|
|
209
506
|
button_layout.addWidget(self._create_btn)
|
|
210
507
|
|
|
211
508
|
# 取消按钮
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
button_layout.addWidget(
|
|
509
|
+
self._cancel_btn = QPushButton("取消")
|
|
510
|
+
self._cancel_btn.setFixedSize(80, 35)
|
|
511
|
+
self._cancel_btn.clicked.connect(self._on_previous_or_cancel)
|
|
512
|
+
button_layout.addWidget(self._cancel_btn)
|
|
216
513
|
|
|
514
|
+
# 添加按钮区域到主布局
|
|
217
515
|
layout.addLayout(button_layout)
|
|
218
|
-
|
|
516
|
+
|
|
517
|
+
# 初始更新语言
|
|
518
|
+
# 延迟调用,确保所有UI元素都已创建
|
|
519
|
+
self._update_language()
|
|
520
|
+
|
|
521
|
+
# 初始更新按钮文本
|
|
522
|
+
self._update_button_texts()
|
|
219
523
|
|
|
220
524
|
def _on_name_changed(self, text):
|
|
221
525
|
"""项目名称改变时的处理"""
|
|
222
526
|
self._proj_name = text.strip()
|
|
223
527
|
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'))
|
|
224
578
|
|
|
225
579
|
def _browse_path(self):
|
|
226
580
|
"""浏览选择路径"""
|
|
227
581
|
current_path = self._path_input.text() or os.path.expanduser("~")
|
|
228
582
|
path = QFileDialog.getExistingDirectory(
|
|
229
|
-
self,
|
|
583
|
+
self, self.lang('select_location'), current_path
|
|
230
584
|
)
|
|
231
585
|
if path:
|
|
232
586
|
self._path_input.setText(path)
|
|
233
587
|
self._proj_path = path
|
|
234
588
|
self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
|
|
589
|
+
# Save settings after path change
|
|
590
|
+
self._save_settings()
|
|
235
591
|
|
|
236
592
|
def _create_project(self):
|
|
237
593
|
"""创建项目"""
|
|
@@ -244,8 +600,8 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
244
600
|
# 检查路径是否已存在
|
|
245
601
|
if os.path.exists(full_path):
|
|
246
602
|
reply = QMessageBox.question(
|
|
247
|
-
self,
|
|
248
|
-
|
|
603
|
+
self, self.lang('path_exists'),
|
|
604
|
+
self.lang('path_exists_message', full_path),
|
|
249
605
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
|
250
606
|
)
|
|
251
607
|
if reply != QMessageBox.StandardButton.Yes:
|
|
@@ -256,15 +612,22 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
256
612
|
self._extract_project_template(full_path)
|
|
257
613
|
|
|
258
614
|
QMessageBox.information(
|
|
259
|
-
self,
|
|
260
|
-
|
|
615
|
+
self, self.lang('success'),
|
|
616
|
+
self.lang('success_message', self._proj_name, full_path)
|
|
261
617
|
)
|
|
262
|
-
|
|
618
|
+
|
|
619
|
+
# 处理预制件
|
|
620
|
+
self._process_prefabs(full_path)
|
|
621
|
+
|
|
622
|
+
self.projectCreated.emit(self._proj_name, full_path)
|
|
623
|
+
|
|
624
|
+
# 成功创建项目后关闭程序
|
|
625
|
+
QApplication.quit()
|
|
263
626
|
|
|
264
627
|
except Exception as e:
|
|
265
628
|
QMessageBox.critical(
|
|
266
|
-
self,
|
|
267
|
-
|
|
629
|
+
self, self.lang('error'),
|
|
630
|
+
self.lang('error_message', str(e))
|
|
268
631
|
)
|
|
269
632
|
|
|
270
633
|
def _extract_project_template(self, target_path):
|
|
@@ -287,14 +650,9 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
287
650
|
print(f"[DEBUG] 项目模板已解压到: {target_path}") # 调试输出
|
|
288
651
|
|
|
289
652
|
# 获取用户选择的配置
|
|
290
|
-
|
|
291
|
-
|
|
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(')')
|
|
653
|
+
lang = self._lang_combo.currentData() or 'cn'
|
|
654
|
+
arena = self._arena_combo.currentData() or 'gray'
|
|
655
|
+
level = self._level_combo.currentData() or 'basic'
|
|
298
656
|
|
|
299
657
|
# 调用配置方法
|
|
300
658
|
ToConfigAfter(path=target_path, language=lang, arena=arena, level=level)
|
|
@@ -314,6 +672,268 @@ class ProjectCreatorUI(QMainWindow):
|
|
|
314
672
|
print(f"[DEBUG] 执行预设继承模式配置")
|
|
315
673
|
ToPrefabAfter(path=target_path)
|
|
316
674
|
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 - 项目创建器")
|
|
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
|
|
317
937
|
|
|
318
938
|
|
|
319
939
|
def run_project_creator():
|
|
@@ -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=VusL7WBC5LSUd9XS7CYlI4D1VIpX-vihWU6bZacQ6eE,39189
|
|
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.9b3.dist-info/METADATA,sha256=V5O710ylo1CQB8-w1GeId6ghhlyATcZotV-fXJ8aUUU,2356
|
|
49
|
+
pyscreeps_arena-0.5.9b3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
50
|
+
pyscreeps_arena-0.5.9b3.dist-info/entry_points.txt,sha256=pnpuPPadwQsxQPaR1rXzUo0fUvhOcC7HTHlf7TYXr7M,141
|
|
51
|
+
pyscreeps_arena-0.5.9b3.dist-info/top_level.txt,sha256=l4uLyMR2NOy41ngBMh795jOHTFk3tgYKy64-9cgjVng,16
|
|
52
|
+
pyscreeps_arena-0.5.9b3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|