Skip to content

Commit ef7846b

Browse files
authored
Merge pull request #917 from Wolfy76700/feature/color_menu
Added team color menu for games with color data
2 parents f1e7c4f + 5c26df5 commit ef7846b

3 files changed

Lines changed: 216 additions & 18 deletions

File tree

src/TSHGameAssetManager.py

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ def __init__(self, parent=None) -> None:
3030
self.games = {}
3131
self.characters = {}
3232
self.variants = {}
33+
self.colors = []
3334
self.selectedGame = {}
3435
self.stockIcons = {}
3536
self.startgg_id_to_character = {}
3637

3738
self.characterModel = QStandardItemModel()
3839
self.skinModels = {}
3940
self.variantModel = QStandardItemModel()
41+
self.colorModel = QStandardItemModel()
4042
self.stageModel = QStandardItemModel()
4143
self.stageModelWithBlank = QStandardItemModel()
4244

@@ -267,6 +269,7 @@ def run(self):
267269
if gameObj != None:
268270
self.parent().characters = gameObj.get("character_to_codename", {})
269271
self.parent().variants = gameObj.get("variant_to_codename", {})
272+
self.parent().colors = gameObj.get("preset_colors", [])
270273

271274
assetsKey = ""
272275
if len(list(gameObj.get("assets", {}).keys())) > 0:
@@ -502,6 +505,45 @@ def run(self):
502505
except:
503506
logger.error(traceback.format_exc())
504507

508+
# Load translations for colors
509+
try:
510+
for c in range(len(self.parent().colors)):
511+
display_name = self.parent().colors[c].get("name")
512+
export_name = self.parent().colors[c].get("name")
513+
en_name = self.parent().colors[c].get("name")
514+
515+
if self.parent().colors[c].get("locale"):
516+
locale = TSHLocaleHelper.programLocale
517+
if locale.replace("-", "_") in self.parent().colors[c]["locale"]:
518+
display_name = self.parent().colors[
519+
c]["locale"][locale.replace("-", "_")]
520+
elif re.split("-|_", locale)[0] in self.parent().colors[c]["locale"]:
521+
display_name = self.parent().colors[
522+
c]["locale"][re.split("-|_", locale)[0]]
523+
elif TSHLocaleHelper.GetRemaps(TSHLocaleHelper.programLocale) in self.parent().colors[c]["locale"]:
524+
display_name = self.parent().colors[c]["locale"][TSHLocaleHelper.GetRemaps(
525+
TSHLocaleHelper.programLocale)]
526+
527+
locale = TSHLocaleHelper.exportLocale
528+
if locale.replace("-", "_") in self.parent().colors[c]["locale"]:
529+
export_name = self.parent().colors[
530+
c]["locale"][locale.replace("-", "_")]
531+
elif re.split("-|_", locale)[0] in self.parent().colors[c]["locale"]:
532+
export_name = self.parent().colors[
533+
c]["locale"][re.split("-|_", locale)[0]]
534+
elif TSHLocaleHelper.GetRemaps(TSHLocaleHelper.exportLocale) in self.parent().colors[c]["locale"]:
535+
export_name = self.parent().colors[c]["locale"][TSHLocaleHelper.GetRemaps(
536+
TSHLocaleHelper.exportLocale)]
537+
538+
self.parent(
539+
).colors[c]["display_name"] = display_name
540+
self.parent(
541+
).colors[c]["export_name"] = export_name
542+
self.parent(
543+
).colors[c]["en_name"] = en_name
544+
except:
545+
logger.error(traceback.format_exc())
546+
505547
with StateManager.SaveBlock():
506548
StateManager.Set(f"game", {
507549
"name": self.parent().selectedGame.get("name"),
@@ -511,13 +553,15 @@ def run(self):
511553
"defaults": self.parent().selectedGame.get("defaults"),
512554
"mods_active": self.mods_active,
513555
"has_stages": bool(self.parent().selectedGame.get("stage_to_codename")),
514-
"has_variants": bool(self.parent().selectedGame.get("variant_to_codename"))
556+
"has_variants": bool(self.parent().selectedGame.get("variant_to_codename")),
557+
"has_colors": bool(self.parent().selectedGame.get("preset_colors"))
515558
})
516559

517560
self.parent().has_modded_content = False
518561
self.parent().UpdateCharacterModel(self.mods_active)
519562
self.parent().UpdateSkinModel()
520563
self.parent().UpdateVariantModel()
564+
self.parent().UpdateColorModel()
521565
self.parent().UpdateStageModel(self.mods_active)
522566

523567
StateManager.Set(f"game.has_modded_content", self.parent().has_modded_content)
@@ -561,6 +605,7 @@ def run(self, mods_active=False, mods_reload_mode=False):
561605
if gameObj != None:
562606
self.parent.characters = gameObj.get("character_to_codename", {})
563607
self.parent.variants = gameObj.get("variant_to_codename", {})
608+
self.parent.colors = gameObj.get("preset_colors", {})
564609

565610
assetsKey = ""
566611
if len(list(gameObj.get("assets", {}).keys())) > 0:
@@ -790,6 +835,42 @@ def run(self, mods_active=False, mods_reload_mode=False):
790835
except:
791836
logger.error(traceback.format_exc())
792837

838+
# Load translations for colors
839+
try:
840+
for c in self.parent.colors.keys():
841+
display_name = c
842+
export_name = c
843+
en_name = c
844+
845+
if self.parent.colors[c].get("locale"):
846+
locale = TSHLocaleHelper.programLocale
847+
if locale.replace("-", "_") in self.parent.colors[c]["locale"]:
848+
display_name = self.parent.colors[
849+
c]["locale"][locale.replace("-", "_")]
850+
elif re.split("-|_", locale)[0] in self.parent.colors[c]["locale"]:
851+
display_name = self.parent.colors[
852+
c]["locale"][re.split("-|_", locale)[0]]
853+
elif TSHLocaleHelper.GetRemaps(TSHLocaleHelper.programLocale) in self.parent.colors[c]["locale"]:
854+
display_name = self.parent.colors[c]["locale"][TSHLocaleHelper.GetRemaps(
855+
TSHLocaleHelper.programLocale)]
856+
857+
locale = TSHLocaleHelper.exportLocale
858+
if locale.replace("-", "_") in self.parent.colors[c]["locale"]:
859+
export_name = self.parent.colors[
860+
c]["locale"][locale.replace("-", "_")]
861+
elif re.split("-|_", locale)[0] in self.parent.colors[c]["locale"]:
862+
export_name = self.parent.colors[
863+
c]["locale"][re.split("-|_", locale)[0]]
864+
elif TSHLocaleHelper.GetRemaps(TSHLocaleHelper.exportLocale) in self.parent.colors[c]["locale"]:
865+
export_name = self.parent.colors[c]["locale"][TSHLocaleHelper.GetRemaps(
866+
TSHLocaleHelper.exportLocale)]
867+
868+
self.parent.colors[c]["display_name"] = display_name
869+
self.parent.colors[c]["export_name"] = export_name
870+
self.parent.colors[c]["en_name"] = en_name
871+
except:
872+
logger.error(traceback.format_exc())
873+
793874
StateManager.Set(f"game", {
794875
"name": self.parent.selectedGame.get("name"),
795876
"smashgg_id": self.parent.selectedGame.get("smashgg_game_id"),
@@ -798,13 +879,15 @@ def run(self, mods_active=False, mods_reload_mode=False):
798879
"defaults": self.parent.selectedGame.get("defaults"),
799880
"mods_active": mods_active,
800881
"has_stages": bool(self.parent.selectedGame.get("stage_to_codename")),
801-
"has_variants": bool(self.parent.selectedGame.get("variant_to_codename"))
882+
"has_variants": bool(self.parent.selectedGame.get("variant_to_codename")),
883+
"has_colors": bool(self.parent.selectedGame.get("preset_colors"))
802884
})
803885

804886
self.parent.has_modded_content = False
805887
self.parent.UpdateCharacterModel(mods_active)
806888
self.parent.UpdateSkinModel()
807889
self.parent.UpdateVariantModel()
890+
self.parent.UpdateColorModel()
808891
self.parent.UpdateStageModel(mods_active)
809892

810893
StateManager.Set(f"game.has_modded_content", self.parent.has_modded_content)
@@ -1012,6 +1095,45 @@ def UpdateCharacterModel(self, mods_active = True):
10121095
except:
10131096
logger.error(traceback.format_exc())
10141097

1098+
def UpdateColorModel(self):
1099+
try:
1100+
self.colorModel = QStandardItemModel()
1101+
1102+
# Add one empty
1103+
item = QStandardItem("")
1104+
self.colorModel.appendRow(item)
1105+
1106+
for c in range(len(self.colors)):
1107+
name = self.colors[c].get("name")
1108+
item = QStandardItem()
1109+
item.setData(name, Qt.ItemDataRole.EditRole)
1110+
logger.info(name)
1111+
1112+
data = {
1113+
"name": self.colors[c].get("export_name"),
1114+
"en_name": c,
1115+
"display_name": self.colors[c].get("display_name"),
1116+
"value": self.colors[c].get("value"),
1117+
"force_opponent": self.colors[c].get("force_opponent")
1118+
}
1119+
1120+
icon = QPixmap(100,100)
1121+
icon.fill(QColor("#" + self.colors[c].get("value")))
1122+
item.setIcon(QIcon(icon))
1123+
1124+
1125+
if self.colors[c].get("display_name") != name:
1126+
item.setData(
1127+
f'{self.colors[c].get("display_name")} / {name}', Qt.ItemDataRole.EditRole)
1128+
1129+
item.setData(data, Qt.ItemDataRole.UserRole)
1130+
self.colorModel.appendRow(item)
1131+
1132+
self.colorModel.sort(0)
1133+
except:
1134+
logger.error(traceback.format_exc())
1135+
1136+
10151137
def UpdateVariantModel(self):
10161138
try:
10171139
self.variantModel = QStandardItemModel()

src/TSHScoreboardWidget.py

Lines changed: 90 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ def __init__(self, scoreboardNumber=1, *args):
355355
self.columns.layout().addWidget(self.team1column)
356356
self.team1column.findChild(QLabel, "teamLabel").setText(
357357
QApplication.translate("app", "TEAM {0}").format(1))
358+
self.team1column.findChild(QLabel, "teamLabel").setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
359+
360+
colorGroup1 = QWidget()
361+
colorGroup1.setLayout(QHBoxLayout())
362+
colorGroup1.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
358363

359364
DEFAULT_TEAM1_COLOR = SettingsManager.Get("general.team_1_default_color", "#fe3636")
360365
self.colorButton1 = TSHColorButton(color=DEFAULT_TEAM1_COLOR)
@@ -367,8 +372,26 @@ def __init__(self, scoreboardNumber=1, *args):
367372
])
368373
self.CommandTeamColor(0, DEFAULT_TEAM1_COLOR)
369374

370-
self.team1column.findChild(QHBoxLayout, "horizontalLayout_2").layout(
371-
).insertWidget(0, self.colorButton1)
375+
self.colorMenu1 = QComboBox()
376+
self.colorMenu1.setVisible(False)
377+
self.colorMenu1.setModel(TSHGameAssetManager.instance.colorModel)
378+
self.colorMenu1.setEditable(True)
379+
self.colorMenu1.completer().setFilterMode(Qt.MatchFlag.MatchContains)
380+
self.colorMenu1.completer().setCompletionMode(QCompleter.PopupCompletion)
381+
self.colorMenu1.setMaximumWidth(200)
382+
self.colorMenu1.setIconSize(QSize(24, 24))
383+
384+
colorGroup1.layout().addWidget(self.colorButton1)
385+
colorGroup1.layout().addWidget(self.colorMenu1)
386+
387+
self.colorMenu1.currentIndexChanged.connect(
388+
lambda element=self.colorMenu1: [
389+
self.CommandTeamColor(0, element),
390+
self.CommandTeamColor(1, element, force_opponent=True)
391+
]
392+
)
393+
394+
self.team1column.findChild(QHBoxLayout, "horizontalLayout_2").layout().insertWidget(0, colorGroup1)
372395
self.team1column.findChild(QScrollArea).setWidget(QWidget())
373396
self.team1column.findChild(
374397
QScrollArea).widget().setLayout(QVBoxLayout())
@@ -392,10 +415,15 @@ def __init__(self, scoreboardNumber=1, *args):
392415
self.scoreColumn = uic.loadUi(TSHResolve("src/layout/TSHScoreboardScore.ui"))
393416
self.columns.layout().addWidget(self.scoreColumn)
394417

418+
colorGroup2 = QWidget()
419+
colorGroup2.setLayout(QHBoxLayout())
420+
colorGroup2.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
421+
395422
self.team2column = uic.loadUi(TSHResolve("src/layout/TSHScoreboardTeam.ui"))
396423
self.columns.layout().addWidget(self.team2column)
397424
self.team2column.findChild(QLabel, "teamLabel").setText(
398425
QApplication.translate("app", "TEAM {0}").format(2))
426+
self.team2column.findChild(QLabel, "teamLabel").setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
399427

400428
DEFAULT_TEAM2_COLOR = SettingsManager.Get("general.team_2_default_color", "#2e89ff")
401429
self.colorButton2 = TSHColorButton(color=DEFAULT_TEAM2_COLOR)
@@ -408,8 +436,26 @@ def __init__(self, scoreboardNumber=1, *args):
408436
# self.colorButton2.setText(QApplication.translate("app", "COLOR"))
409437
self.CommandTeamColor(1, DEFAULT_TEAM2_COLOR)
410438

411-
self.team2column.findChild(QHBoxLayout, "horizontalLayout_2").layout(
412-
).insertWidget(0, self.colorButton2)
439+
self.colorMenu2 = QComboBox()
440+
self.colorMenu2.setVisible(False)
441+
self.colorMenu2.setModel(TSHGameAssetManager.instance.colorModel)
442+
self.colorMenu2.setEditable(True)
443+
self.colorMenu2.completer().setFilterMode(Qt.MatchFlag.MatchContains)
444+
self.colorMenu2.completer().setCompletionMode(QCompleter.PopupCompletion)
445+
self.colorMenu2.setMaximumWidth(200)
446+
self.colorMenu2.setIconSize(QSize(24, 24))
447+
448+
colorGroup2.layout().addWidget(self.colorButton2)
449+
colorGroup2.layout().addWidget(self.colorMenu2)
450+
451+
self.colorMenu2.currentIndexChanged.connect(
452+
lambda element=self.colorMenu2: [
453+
self.CommandTeamColor(1, element),
454+
self.CommandTeamColor(0, element, force_opponent=True)
455+
]
456+
)
457+
458+
self.team2column.findChild(QHBoxLayout, "horizontalLayout_2").layout().insertWidget(0, colorGroup2)
413459

414460
self.team2column.findChild(QScrollArea).setWidget(QWidget())
415461
self.team2column.findChild(
@@ -558,7 +604,11 @@ def __init__(self, scoreboardNumber=1, *args):
558604
TSHGameAssetManager.instance.signals.onLoad.connect(
559605
lambda: [
560606
self.SetDefaultsFromAssets(),
561-
self.scoreColumn.findChild(QSpinBox, "best_of").valueChanged.emit(self.scoreColumn.findChild(QSpinBox, "best_of").value())
607+
self.scoreColumn.findChild(QSpinBox, "best_of").valueChanged.emit(self.scoreColumn.findChild(QSpinBox, "best_of").value()),
608+
self.colorMenu1.setModel(TSHGameAssetManager.instance.colorModel),
609+
self.colorMenu2.setModel(TSHGameAssetManager.instance.colorModel),
610+
self.colorMenu1.setVisible(StateManager.Get(f"game.has_colors", False)),
611+
self.colorMenu2.setVisible(StateManager.Get(f"game.has_colors", False))
562612
]
563613
)
564614

@@ -1126,16 +1176,41 @@ def ClearScore(self):
11261176
self.team1column.findChild(QCheckBox, "losers").setChecked(False)
11271177
self.team2column.findChild(QCheckBox, "losers").setChecked(False)
11281178

1129-
def CommandTeamColor(self, team: int, color):
1130-
if team == 0:
1131-
self.colorButton1.setColor(color)
1132-
if team == 1:
1133-
self.colorButton2.setColor(color)
1134-
if team in (0, 1):
1135-
StateManager.BlockSaving()
1136-
StateManager.Set(
1137-
f"score.{self.scoreboardNumber}.team.{team + 1}.color", color)
1138-
StateManager.ReleaseSaving()
1179+
def CommandTeamColor(self, team: int, color, force_opponent=False):
1180+
if color:
1181+
value = None
1182+
if type(color) is str:
1183+
value = color
1184+
if type(color) is int and color > 0:
1185+
value = TSHGameAssetManager.instance.colorModel.item(color).data(Qt.ItemDataRole.UserRole)
1186+
if force_opponent:
1187+
value = value.get("force_opponent")
1188+
else:
1189+
value = value.get("value")
1190+
if value:
1191+
value = "#" + value
1192+
1193+
if value:
1194+
if team == 0:
1195+
self.colorButton1.setColor(value)
1196+
if team == 1:
1197+
self.colorButton2.setColor(value)
1198+
if team in (0, 1):
1199+
StateManager.BlockSaving()
1200+
StateManager.Set(
1201+
f"score.{self.scoreboardNumber}.team.{team + 1}.color", value)
1202+
StateManager.ReleaseSaving()
1203+
1204+
# Set in menu if recognized
1205+
if type(color) is int and force_opponent:
1206+
for i in range(1, TSHGameAssetManager.instance.colorModel.rowCount()):
1207+
current_menu_item_data = TSHGameAssetManager.instance.colorModel.item(i).data(Qt.ItemDataRole.UserRole)
1208+
if current_menu_item_data.get("value") in value:
1209+
if team == 0:
1210+
self.colorMenu1.setCurrentIndex(i)
1211+
if team == 1:
1212+
self.colorMenu2.setCurrentIndex(i)
1213+
11391214

11401215
# Modifies the current set data. Does not check for id, so do not call this with data that may lead to another hbox incident
11411216
def ChangeSetData(self, data):

src/TSHWebServerActions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@ def get_games(self):
279279
"challonge_game_id": TSHGameAssetManager.instance.games[key].get("challonge_game_id"),
280280
"smashgg_game_id": TSHGameAssetManager.instance.games[key].get("smashgg_game_id"),
281281
"has_stages": bool(TSHGameAssetManager.instance.games[key].get("stage_to_codename")),
282-
"has_variants": bool(TSHGameAssetManager.instance.games[key].get("variant_to_codename"))
282+
"has_variants": bool(TSHGameAssetManager.instance.games[key].get("variant_to_codename")),
283+
"has_colors": bool(TSHGameAssetManager.instance.games[key].get("preset_colors"))
283284
}
284285

285286
return data

0 commit comments

Comments
 (0)