-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathToolBox.py
More file actions
594 lines (525 loc) · 28.8 KB
/
Copy pathToolBox.py
File metadata and controls
594 lines (525 loc) · 28.8 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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
from PyQt5.QtWidgets import (QApplication, QWidget, QGridLayout, QScrollArea, QVBoxLayout,
QSizePolicy, QPushButton, QFileDialog, QApplication, QMessageBox)
from PyQt5.QtCore import Qt, pyqtSignal
import sys, os
import ui_toolbox
import utils.AdaptiveManager as AdaptiveManager
import utils.pattern as pattern
import utils.DataStorage as DataStorage
import utils.tools as tools
import HintPlayer, ShareHub
zoom_level_to_factor = [25,33,50,67,75,80,90,100,110,125,150,175,200,250,300,400,500]
class CommandGeneratorBase:
def __init__(self, design_name, design_size, patterns_dict, version_pattern_index):
self.design_name = design_name
self.design_size = design_size # [width, height]
self.patterns_dict = patterns_dict # {"x:y": "base:pat1:col1:pat2:col2:..."}
self.version_pattern_index = version_pattern_index # 用于检查图案支持的版本
self.group_size = 27
self.generated_count = 0
self.is_over6 = False
self.is_skip = False
def generate(self):
command = ""
for i in range(self.design_size[0] - 1, -1, -1):
for j in range(self.design_size[1]):
key = f"{i}:{j}"
if key not in self.patterns_dict:
continue
banner_data = self.patterns_dict[key].split(":")
if len(banner_data) > 13:
self.is_over6 = True
base_color = int(banner_data[0])
if base_color == 16:
continue
slot = self.generated_count % self.group_size
if slot == 0:
command += self.get_prefix()
item_str = self.format_banner_item(banner_data, slot, (i, j))
command += item_str + ","
self.generated_count += 1
if slot == self.group_size - 1:
command += self.get_suffix()
if self.generated_count % self.group_size != 0:
command += self.get_suffix()
return command
# 子类必须实现
def get_prefix(self):
"""每组开头的命令前缀"""
raise NotImplementedError
def get_suffix(self):
"""每组结尾的命令后缀"""
raise NotImplementedError
def format_banner_item(self, banner_data, slot, position):
"""生成单个旗帜物品的 NBT/组件字符串"""
raise NotImplementedError
class CommandGenerator1_8(CommandGeneratorBase):
def get_prefix(self):
return f'/give @p minecraft:chest 1 0 {{display: {{Name: "{self.design_name}"}},BlockEntityTag:{{Items:['
def get_suffix(self):
return f']}}}}\n___________________________\n'
def format_banner_item(self, banner_data, slot, position):
base_id = int(banner_data[0])
damage = 15 - base_id
pos_str = f"{position[0]}_{position[1]}"
item = f'{{Slot:{slot}b,id:"minecraft:banner",Damage:{damage}s,Count:1b,tag:{{display: {{Name: "{pos_str}"}}'
pattern_types = banner_data[1::2]
pattern_colors = banner_data[2::2]
if any(x != '0' for x in pattern_types):
item += f',BlockEntityTag:{{Patterns:['
for k in range(len(pattern_types)):
ptype = int(pattern_types[k])
if ptype == 0:
continue
if pattern.type_support_version[ptype] <= self.version_pattern_index:
color_id = int(pattern_colors[k])
color_value = 15 - color_id
item += f'{{Pattern:"{pattern.type[ptype]}",Color:{color_value}}},'
else:
self.is_skip = True
item += f']}}'
item += f'}}}}'
return item
class CommandGenerator1_13(CommandGeneratorBase):
def get_prefix(self):
return f'/give @p minecraft:chest{{display: {{Name: \'{{"text":"{self.design_name}","color":"gold"}}\'}},BlockEntityTag:{{Items:['
def get_suffix(self):
return f']}}}}\n___________________________\n'
def format_banner_item(self, banner_data, slot, position):
base_id = int(banner_data[0])
color_name = pattern.color_name[base_id]
pos_str = f"{position[0]}_{position[1]}"
item = f'{{Slot:{slot}b,id:"minecraft:{color_name}_banner",Count:1b,tag:{{display: {{Name: \'{{"text":"{pos_str}"}}\'}}'
pattern_types = banner_data[1::2]
pattern_colors = banner_data[2::2]
if any(x != '0' for x in pattern_types):
item += f',BlockEntityTag:{{Patterns:['
for k in range(len(pattern_types)):
ptype = int(pattern_types[k])
if ptype == 0:
continue
if pattern.type_support_version[ptype] <= self.version_pattern_index:
color_id = int(pattern_colors[k])
item += f'{{Pattern:"{pattern.type[ptype]}",Color:{color_id}}},'
else:
self.is_skip = True
item += f']}}'
item += f'}}}}'
return item
class CommandGenerator1_20_5(CommandGeneratorBase):
# 可用指令示例 give @p chest[custom_name='{text:"bbb",color:"gold"}',container=[{slot:0,item:{id:"red_banner",components:{custom_name:"1_1",banner_patterns:[{pattern:"stripe_top",color:"white"}]}}}]] 1
def get_prefix(self):
return f'/give @p chest[custom_name=\'{{"text":"{self.design_name}","color":"gold"}}\',container=['
def get_suffix(self):
return f']]\n___________________________\n'
def format_banner_item(self, banner_data, slot, position):
base_id = int(banner_data[0])
color_name = pattern.color_name[base_id]
pos_str = f"{position[0]}_{position[1]}"
item = f'{{slot:{slot},item:{{id:"{color_name}_banner",components:{{custom_name:"{pos_str}"'
pattern_types = banner_data[1::2]
pattern_colors = banner_data[2::2]
if any(x != '0' for x in pattern_types):
item += f',banner_patterns:['
for k in range(len(pattern_types)):
ptype = int(pattern_types[k])
if ptype == 0:
continue
if pattern.type_support_version[ptype] <= self.version_pattern_index:
color_id = int(pattern_colors[k])
color_name_pat = pattern.color_name[color_id]
item += f"{{pattern:'{pattern.advanced_type[ptype]}',color:{color_name_pat}}},"
else:
self.is_skip = True
item += f"]"
item += f'}}}}}}'
return item
class ToolBox(QWidget):
LoadDesign = pyqtSignal()
UpdateZoom = pyqtSignal(float, bool) # zoom_factor, real_margin
def __init__(self):
super().__init__()
self.ui = ui_toolbox.Ui_ToolBox()
self.ui.setupUi(self)
DataStorage.get_instance().filepath = "" # 当前文件路径
DataStorage.get_instance().designs = {} # 设计列表: {'name': [row, col, [r1:c1:banner1, ...]]}
DataStorage.get_instance().search_designs = {} # 搜索结果
DataStorage.get_instance().current_design_name = ""
DataStorage.get_instance().current_design_size = [3, 3] # [row, col]
DataStorage.get_instance().current_design_patterns = {} # dict{'r:c': 'b:p:c:p:c:...', ...}
DataStorage.get_instance().zoom_level = 7 # 缩放等级, 对应100%
DataStorage.get_instance().banner_pos = [1, 0] # 当前点击的banner的行列数
self.ui.FileLoadButton.clicked.connect(self.OpenFile)
self.ui.FileSaveButton.clicked.connect(self.SaveFile)
self.ui.DesignSelectComboBox.currentIndexChanged.connect(self.DesignSelected)
self.ui.DesignSearchButton.clicked.connect(self.SearchDesign)
self.ui.DesignRowSpinBox.valueChanged.connect(self.ChangeDesignSize)
self.ui.DesignColumnSpinBox.valueChanged.connect(self.ChangeDesignSize)
self.ui.DesignSelectButton.clicked.connect(self.SelectDesign)
self.ui.ViewZoomUpButton.clicked.connect(lambda: self.SetZoom(ZoomUp=True))
self.ui.ViewZoomDownButton.clicked.connect(lambda: self.SetZoom(ZoomUp=False))
self.ui.ViewPaddingCheckBox.stateChanged.connect(lambda: self.UpdateZoom.emit(zoom_level_to_factor[DataStorage.get_instance().zoom_level] / 100, self.ui.ViewPaddingCheckBox.isChecked()))
self.ui.UtilsGenCommandButton.clicked.connect(self.GenerateCommand)
self.ui.UtilsDyeCalcButton.clicked.connect(self.CalculateDesignDye)
self.ui.ViewRealtimeDisplayCheckBox.stateChanged.connect(self.__setRealtimeCheckboxText)
self.ui.ViewBackgroundRedSchollbar.valueChanged.connect(self.SetBackgroundColor)
self.ui.ViewBackgroundGreenSchollbar.valueChanged.connect(self.SetBackgroundColor)
self.ui.ViewBackgroundBlueSchollbar.valueChanged.connect(self.SetBackgroundColor)
self.ui.UtilsShortCutButton.clicked.connect(self.__openHintPlayer)
self.ui.UtilsShareHubButton.clicked.connect(self.__openShareHub)
self.ui.UtilsUpdateButton.clicked.connect(self.CheckUpdate)
self.ui.UtilsAuthorButton.clicked.connect(self.ShowAuthorInfo)
self.adaptive_components = [
self.ui.FileLabel, self.ui.FilePathText, self.ui.FileLoadButton, self.ui.FileSaveButton,
self.ui.DesignLabel, self.ui.DesignNameHintLabel, self.ui.DesignNameText, self.ui.DesignSelectHintLabel, self.ui.DesignSelectComboBox, self.ui.DesignSearchButton, self.ui.DesignSelectButton, self.ui.DesignRowHintLabel, self.ui.DesignRowSpinBox, self.ui.DesignColumnHintLabel, self.ui.DesignColumnSpinBox,
self.ui.ViewLabel, self.ui.ViewPaddingCheckBox, self.ui.ViewZoomLabel, self.ui.ViewZoomUpButton, self.ui.ViewZoomDownButton, self.ui.ViewRealtimeDisplayCheckBox,
self.ui.ViewBackgroundColorLabel, self.ui.ViewBackgroundRedSchollbar, self.ui.ViewBackgroundGreenSchollbar, self.ui.ViewBackgroundBlueSchollbar,
self.ui.UtilsLabel, self.ui.UtilsDyeCalcButton, self.ui.UtilsGenCommandButton, self.ui.UtilsShortCutButton, self.ui.UtilsAuthorButton, self.ui.UtilsUpdateButton, self.ui.UtilsShareHubButton,
self.ui.VersionLabel, self.ui.VersionCmdSelectLabel, self.ui.VersionCmdSelectComboBox, self.ui.VersionPatternSelectLabel, self.ui.VersionPatternSelectComboBox,
self.ui.KeyShow
]
self.adaptive_manager = AdaptiveManager.AdaptiveManager(self, self.adaptive_components)
self.ui.VersionCmdSelectComboBox.setCurrentIndex(1)
self.ui.VersionPatternSelectComboBox.setCurrentIndex(2)
def resizeEvent(self, a0):
super().resizeEvent(a0)
self.adaptive_manager.AdaptiveResize()
def __setRealtimeCheckboxText(self):
if self.ui.ViewRealtimeDisplayCheckBox.isChecked():
self.ui.ViewRealtimeDisplayCheckBox.setText("开启实时渲染")
else:
self.ui.ViewRealtimeDisplayCheckBox.setText("重新勾选后渲染")
def __openHintPlayer(self):
"""打开图片播放器窗口"""
self.hint_player = None
if self.hint_player is None or not self.hint_player.isVisible():
self.hint_player = HintPlayer.HintPlayer()
self.hint_player.show()
else:
self.hint_player.raise_() # 如果窗口已存在,将其提到最前
self.hint_player.activateWindow()
def __openShareHub(self):
"""打开分享中心窗口"""
self.share_hub = None
if self.share_hub is None or not self.share_hub.isVisible():
self.share_hub = ShareHub.ShareHub()
self.share_hub.show()
else:
self.share_hub.raise_() # 如果窗口已存在,将其提到最前
self.share_hub.activateWindow()
def OpenFile(self):
path, _ = QFileDialog.getSaveFileName(self, "选择旗帜文件", "", "旗帜文件(*.banner)")
if path:
DataStorage.get_instance().designs = {}
DataStorage.get_instance().filepath = path
self.ui.FilePathText.setText(path)
if os.path.exists(path):
self.ui.DesignSelectComboBox.clear()
# 使用UTF-8编码打开
try:
with open(path, "r", encoding="utf-8") as f:
for line in f.readlines():
try:
line = line.strip().split(",")
if len(line) < 3: # 检验必要部分
raise Exception("缺少关键信息")
for banner in line[3:]: # 依次检验旗帜部分是否符合格式
if banner == '':
continue
elems = banner.split(":")
for elem_index, elem in enumerate(elems): # 图案0~40, 颜色0~15
if elem_index >= 2:
if elem_index % 2 == 0:
if int(elem) < 0 or int(elem) > 15 + (elem_index == 2): # 不能转换int会报错
raise Exception("颜色值错误")
else:
if int(elem) < 0 or int(elem) > len(pattern.type):
raise Exception("图案值错误")
else:
if int(elem) < 0:
raise Exception("坐标不能为负数")
except Exception as e:
print(e)
continue
# 存储
DataStorage.get_instance().designs[line[0]] = [int(line[1]), int(line[2]), line[3:]]
self.ui.DesignSelectComboBox.addItem(line[0])
# 加载第一个
if DataStorage.get_instance().designs != {}:
self.ui.DesignSelectComboBox.setCurrentIndex(0)
self.DesignSelected()
except UnicodeDecodeError:
QMessageBox.warning(self, "错误", "文件编码不支持")
def SaveFile(self):
# 检查路径是否为空
if DataStorage.get_instance().filepath == "":
DataStorage.get_instance().filepath, _ = QFileDialog.getSaveFileName(self, "选择旗帜文件", "", "旗帜文件(*.banner)")
# 打开文件
if DataStorage.get_instance().filepath != "":
# 使用UTF-8编码保存
with open(DataStorage.get_instance().filepath, "w", encoding="utf-8") as f:
for name in DataStorage.get_instance().designs:
design = DataStorage.get_instance().designs[name]
design_str = f"{name},{design[0]},{design[1]},"
for banner in design[2]:
_, banner_list = tools.StrBannerToList(banner)
if banner_list[0] < design[0] and banner_list[1] < design[1] and banner_list[2] != 16: # 范围外不进行保存, 精简文件
design_str = design_str + banner + ","
f.write(f"{design_str[:-1]}\n")
def DesignSelected(self):
if self.ui.DesignSelectComboBox.currentText():
DataStorage.get_instance().current_design_name = self.ui.DesignSelectComboBox.currentText()
r = DataStorage.get_instance().designs[self.ui.DesignSelectComboBox.currentText()][0]
c = DataStorage.get_instance().designs[self.ui.DesignSelectComboBox.currentText()][1]
self.ui.DesignRowSpinBox.setValue(r) # 加载行数
self.ui.DesignColumnSpinBox.setValue(c) # 加载列数
design = DataStorage.get_instance().designs[DataStorage.get_instance().current_design_name]
patterns_data = {}
for banner in design[2]:
b = banner.split(":", 2)
key = b[0] + ":" + b[1]
patterns_data[key] = b[2]
DataStorage.get_instance().current_design_patterns = patterns_data
DataStorage.get_instance().current_design_size = [r,c]
DataStorage.get_instance().banner_pos = [1,0]
self.LoadDesign.emit()
def ChangeDesignSize(self):
if self.ui.DesignSelectComboBox.currentText():
DataStorage.get_instance().designs[self.ui.DesignSelectComboBox.currentText()][0] = self.ui.DesignRowSpinBox.value()
DataStorage.get_instance().designs[self.ui.DesignSelectComboBox.currentText()][1] = self.ui.DesignColumnSpinBox.value()
DataStorage.get_instance().current_design_size = [DataStorage.get_instance().designs[self.ui.DesignSelectComboBox.currentText()][0],
DataStorage.get_instance().designs[self.ui.DesignSelectComboBox.currentText()][1]]
self.LoadDesign.emit()
def SearchDesign(self):
'''匹配搜索'''
DataStorage.get_instance().search_designs = {}
for design_name in DataStorage.get_instance().designs:
if self.ui.DesignNameText.text() in design_name:
DataStorage.get_instance().search_designs[design_name] = DataStorage.get_instance().designs[design_name]
self.ui.DesignSelectComboBox.clear()
for name in DataStorage.get_instance().search_designs:
self.ui.DesignSelectComboBox.addItem(name)
self.ui.DesignSelectComboBox.setFocus()
# 展开下拉
self.ui.DesignSelectComboBox.showPopup()
def UpdateFocus(self):
'''轮换设置聚焦 失焦-设计选择框-设计名输入框'''
# 判断是否聚焦以及聚焦的控件
f1 = self.ui.DesignSelectComboBox.hasFocus()
f2 = self.ui.DesignNameText.hasFocus()
if f1:
self.ui.DesignNameText.setFocus()
self.ui.DesignSelectComboBox.hidePopup()
elif f2:
self.ui.DesignNameText.clearFocus()
else:
self.ui.DesignSelectComboBox.setFocus()
self.ui.DesignSelectComboBox.showPopup()
def SelectDesign(self):
name = self.ui.DesignNameText.text()
if name != "":
if ',' in name or ':' in name:
self.ui.DesignNameText.setText("无效的名称")
return
if name in DataStorage.get_instance().designs: # 名称已存在
DataStorage.get_instance().current_design_name = name
self.ui.DesignSelectComboBox.setCurrentText(name)
self.DesignSelected()
else:
DataStorage.get_instance().designs[name] = [3,3,[]]
self.ui.DesignSelectComboBox.addItem(name)
self.ui.DesignSelectComboBox.setCurrentText(name)
DataStorage.get_instance().current_design_name = name
self.DesignSelected()
self.ui.DesignNameText.setText("")
else:
self.ui.DesignNameText.setText("设计名不能为空")
def ReplaceAllBannerColor(self, mode, color1, color2):
'''替换整个Design中的一种颜色'''
# mode=0替换染色步骤, =1替换旗帜颜色
current_patterns = DataStorage.get_instance().current_design_patterns
for banner_key in current_patterns:
_, banner_list = tools.StrBannerToList(current_patterns[banner_key])
if mode == 0:
for i in range(2, len(banner_list), 2):
if banner_list[i] == color1:
banner_list[i] = color2
elif mode == 1:
if banner_list[0] == color1:
banner_list[0] = color2
DataStorage.get_instance().current_design_patterns[banner_key] = tools.ListToStrBanner(banner_list)
print(tools.ListToStrBanner(banner_list))
def SaveCurrentDesign(self):
'''保存当前设计到designs列表中'''
cd = []
for banner_key in DataStorage.get_instance().current_design_patterns:
cd.append(f"{banner_key}:{DataStorage.get_instance().current_design_patterns[banner_key]}")
DataStorage.get_instance().designs[DataStorage.get_instance().current_design_name] = [DataStorage.get_instance().current_design_size[0], DataStorage.get_instance().current_design_size[1], cd]
def SetZoom(self, ZoomUp=True):
if ZoomUp:
if DataStorage.get_instance().zoom_level < len(zoom_level_to_factor) - 1:
DataStorage.get_instance().zoom_level += 1
else:
if DataStorage.get_instance().zoom_level > 0:
DataStorage.get_instance().zoom_level -= 1
self.ui.ViewZoomLabel.setText(f"缩放: {zoom_level_to_factor[DataStorage.get_instance().zoom_level]}%")
self.UpdateZoom.emit(zoom_level_to_factor[DataStorage.get_instance().zoom_level] / 100, self.ui.ViewPaddingCheckBox.isChecked())
def SetBackgroundColor(self):
DataStorage.get_instance().background_color = [self.ui.ViewBackgroundRedSchollbar.value(),
self.ui.ViewBackgroundGreenSchollbar.value(),
self.ui.ViewBackgroundBlueSchollbar.value()]
def SetDefaultBackgroundColor(self, color_id: int):
'''设置旗帜库中颜色作为背景'''
self.ui.ViewBackgroundRedSchollbar.setValue(pattern.color[pattern.color_name[color_id]][0])
self.ui.ViewBackgroundGreenSchollbar.setValue(pattern.color[pattern.color_name[color_id]][1])
self.ui.ViewBackgroundBlueSchollbar.setValue(pattern.color[pattern.color_name[color_id]][2])
def GenerateCommand(self):
storage = DataStorage.get_instance()
design_name = storage.current_design_name
design_size = storage.current_design_size
patterns_dict = storage.current_design_patterns
version_cmd_index = self.ui.VersionCmdSelectComboBox.currentIndex()
version_pattern_index = self.ui.VersionPatternSelectComboBox.currentIndex()
# 根据版本选择对应的生成器
if version_cmd_index == 0:
generator = CommandGenerator1_8(design_name, design_size, patterns_dict, version_pattern_index)
elif version_cmd_index == 1:
generator = CommandGenerator1_13(design_name, design_size, patterns_dict, version_pattern_index)
elif version_cmd_index == 2:
generator = CommandGenerator1_20_5(design_name, design_size, patterns_dict, version_pattern_index)
else:
QMessageBox.warning(self, '错误', '尚不支持的版本')
return
command = generator.generate()
generated_num = generator.generated_count
isover6 = generator.is_over6
isskip = generator.is_skip
# 复制剪贴板
app = QApplication.instance() or QApplication(sys.argv)
app.clipboard().setText(command)
text = f'已复制指令到剪贴板,共{(generated_num - 1) // 27 + 1}条'
if isover6:
text += ',存在大于6次染色的旗帜'
if isskip:
text += ',已自动忽略当前版本不支持的图案'
QMessageBox.information(self, '生成成功!', text)
def CalculateDesignDye(self):
dye = [0] * 16
empty_banner = [0] * 16
for key in DataStorage.get_instance().current_design_patterns:
banner = [int(i) for i in DataStorage.get_instance().current_design_patterns[key].split(":")]
if banner[0] == 16:
continue
# dye[banner[0]] += 6
empty_banner[banner[0]] += 1
for idx in range((len(banner) - 1) // 2):
if banner[2 * idx + 1] != 0:
dye[banner[2 * idx + 2]] += 1
msg = QMessageBox(self)
msg.setWindowTitle("染料计算")
htm_str = ""
for i in range(16):
htm_str += f'''
<p>{str(dye[i] + empty_banner[i] * 6)}({empty_banner[i]}面旗帜*6+{dye[i]}次染色)</p>
<img src="images/dyes/{str(i)}.png" width="26" height="26">
'''
# 1132*52
html_content = f"""
<div style="text-align:center">
<p>{htm_str}</p>
<p>适用18w43a/1.14以上版本</p>
</div>
"""
msg.setText(html_content)
msg.exec_()
def ShowAuthorInfo(self):
msg = QMessageBox(self)
msg.setWindowTitle("神秘内容")
html_content = '''
<style>a {color: inherit; text-decoration: none;}</style>
<div>
<img src="images/userheads/1.png" width="32" height="32">
<font size=4><a href="https://www.bilibili.com/video/BV1nqi3BWE61/">介绍视频</a></font>
</div><div>
<img src="images/userheads/2.png" width="32" height="32">
<font size=4><a href="https://github.com/345ljh/MinecraftBannerDesigner">编辑器开源(GitHub)</a></font>
</div><div>
<img src="images/userheads/5.png" width="32" height="32">
<font size=4><a href="https://space.bilibili.com/506932686">iliqiIiq</a></font>
</div><div>
<font size=3>主要开发成员</font>
</div><div>
<img src="images/userheads/3.png" width="32" height="32">
<font size=4><a href="https://space.bilibili.com/503514777">神奇矿工王百五</a></font>
</div><div>
<font size=3>旗帜画&旗帜汉字up,持续更新一级字中</font>
</div><div>
<img src="images/userheads/4.png" width="32" height="32">
<font size=4><a href="https://space.bilibili.com/3690991626226222">形意流芳计划</a></font>
</div><div>
<font size=3>旗帜还原高校校徽计划</font>
</div><div>
'''
msg.setText(html_content)
msg.exec_()
def CheckUpdate(self, isSilent: bool = False):
import utils.VersionController as vc
new_version = vc.get_version()
if new_version == -1:
if not isSilent:
QMessageBox.information(self, '检查更新失败', '请检查网络连接')
return
elif vc.current_version >= new_version:
if not isSilent:
QMessageBox.information(self, '检查更新', f'当前已是最新版本({new_version})')
return
else:
msg = QMessageBox(self)
msg.setWindowTitle("发现新版本")
msg.setText(f"当前版本: {vc.current_version}\n最新版本: {new_version}")
download_button = QPushButton("下载")
download_button.clicked.connect(vc.get_update)
msg.addButton(download_button, QMessageBox.YesRole)
msg.exec_()
def RowColumnOperation(self, isAdd: bool = True, isRow: bool = True, inverted: bool = False):
'''
从右或上/左或下添加/删除一行/一列
isAdd: true - 添加 false - 删除
isRow: true - 行 false - 列
inverted: true - 从左或下操作 false - 从右或上操作
'''
if inverted:
new_patterns = {}
design_copy = DataStorage.get_instance().current_design_patterns.copy()
for b_key in DataStorage.get_instance().current_design_patterns:
if isRow and isAdd:
key_split = b_key.split(":")
n_key = f"{int(key_split[0]) + 1}:{key_split[1]}"
new_patterns[n_key] = design_copy[b_key]
elif isRow and not isAdd:
key_split = b_key.split(":")
if int(key_split[0]) <= 0:
continue
n_key = f"{int(key_split[0]) - 1}:{key_split[1]}"
new_patterns[n_key] = design_copy[b_key]
elif not isRow and isAdd:
key_split = b_key.split(":")
n_key = f"{key_split[0]}:{int(key_split[1]) + 1}"
new_patterns[n_key] = design_copy[b_key]
elif not isRow and not isAdd:
key_split = b_key.split(":")
if int(key_split[1]) <= 0:
continue
n_key = f"{key_split[0]}:{int(key_split[1]) - 1}"
new_patterns[n_key] = design_copy[b_key]
DataStorage.get_instance().current_design_patterns = new_patterns
if isRow:
self.ui.DesignRowSpinBox.setValue(self.ui.DesignRowSpinBox.value() + 1 if isAdd else self.ui.DesignRowSpinBox.value() - 1)
else:
self.ui.DesignColumnSpinBox.setValue(self.ui.DesignColumnSpinBox.value() + 1 if isAdd else self.ui.DesignColumnSpinBox.value() - 1)
self.SaveCurrentDesign()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = ToolBox()
window.show()
sys.exit(app.exec_())