From e8a8364ac283c91caa61ec6a0035649fdd88e190 Mon Sep 17 00:00:00 2001 From: Khopa Date: Fri, 12 Jul 2019 23:13:03 +0200 Subject: [PATCH] Added back the settings menu in the new UI --- qt_ui/uiconstants.py | 11 +- qt_ui/widgets/QTopPanel.py | 4 +- qt_ui/windows/QGameSettings.py | 0 qt_ui/windows/QLiberationWindow.py | 4 - qt_ui/windows/settings/QSettingsWindow.py | 190 ++++++++++++++++++++++ resources/ui/misc/cheat.png | Bin 0 -> 5050 bytes resources/ui/misc/generator.png | Bin 0 -> 6688 bytes resources/ui/misc/missile.png | Bin 0 -> 3795 bytes 8 files changed, 202 insertions(+), 7 deletions(-) delete mode 100644 qt_ui/windows/QGameSettings.py create mode 100644 qt_ui/windows/settings/QSettingsWindow.py create mode 100644 resources/ui/misc/cheat.png create mode 100644 resources/ui/misc/generator.png create mode 100644 resources/ui/misc/missile.png diff --git a/qt_ui/uiconstants.py b/qt_ui/uiconstants.py index 041d4f49..5bb607b9 100644 --- a/qt_ui/uiconstants.py +++ b/qt_ui/uiconstants.py @@ -16,6 +16,9 @@ URLS : Dict[str, str] = { "Issues": "https://github.com/shdwp/dcs_liberation/issues" } +LABELS_OPTIONS = ["Full", "Abbreviated", "Dot Only", "Off"] +SKILL_OPTIONS = ["Average", "Good", "High", "Excellent"] + COLORS: Dict[str, QColor] = { "red": QColor(255, 125, 125), "bright_red": QColor(200, 64, 64), @@ -30,10 +33,10 @@ COLORS: Dict[str, QColor] = { CP_SIZE = 25 - - FONT = QFont("Arial", 12, weight=5, italic=True) + + ICONS: Dict[str, QPixmap] = {} def load_icons(): @@ -62,6 +65,10 @@ def load_icons(): for category in CATEGORY_MAP.keys(): ICONS[category] = QPixmap("./resources/ui/ground_assets/" + category + ".png") + ICONS["Generator"] = QPixmap("./resources/ui/misc/generator.png") + ICONS["Missile"] = QPixmap("./resources/ui/misc/missile.png") + ICONS["Cheat"] = QPixmap("./resources/ui/misc/cheat.png") + EVENT_ICONS: Dict[str, QPixmap] = {} diff --git a/qt_ui/widgets/QTopPanel.py b/qt_ui/widgets/QTopPanel.py index 571af2a1..6127d613 100644 --- a/qt_ui/widgets/QTopPanel.py +++ b/qt_ui/widgets/QTopPanel.py @@ -6,6 +6,7 @@ from qt_ui.widgets.QTurnCounter import QTurnCounter import qt_ui.uiconstants as CONST from qt_ui.windows.GameUpdateSignal import GameUpdateSignal +from qt_ui.windows.settings.QSettingsWindow import QSettingsWindow class QTopPanel(QFrame): @@ -55,7 +56,8 @@ class QTopPanel(QFrame): self.budgetBox.setBudget(self.game.budget, self.game.budget_reward_amount) def openSettings(self): - QMessageBox.information(self, "Settings", "Todo open game settings") + self.subwindow = QSettingsWindow(self.game) + self.subwindow.show() def openStatisticsWindow(self): QMessageBox.information(self, "Stats", "Todo open stats window") diff --git a/qt_ui/windows/QGameSettings.py b/qt_ui/windows/QGameSettings.py deleted file mode 100644 index e69de29b..00000000 diff --git a/qt_ui/windows/QLiberationWindow.py b/qt_ui/windows/QLiberationWindow.py index c8f7e68f..bcc65b97 100644 --- a/qt_ui/windows/QLiberationWindow.py +++ b/qt_ui/windows/QLiberationWindow.py @@ -36,16 +36,12 @@ class QLiberationWindow(QMainWindow): def initUi(self): - hbox = QHBoxLayout() - hbox.addStretch(1) self.liberation_map = QLiberationMap(self.game) - hbox.addWidget(self.liberation_map) vbox = QVBoxLayout() vbox.setMargin(0) vbox.addWidget(QTopPanel(self.game)) vbox.addWidget(self.liberation_map) - #vbox.addLayout(hbox) central_widget = QWidget() central_widget.setLayout(vbox) diff --git a/qt_ui/windows/settings/QSettingsWindow.py b/qt_ui/windows/settings/QSettingsWindow.py new file mode 100644 index 00000000..20c83592 --- /dev/null +++ b/qt_ui/windows/settings/QSettingsWindow.py @@ -0,0 +1,190 @@ +import os + +from PySide2 import QtCore +from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QModelIndex, QPoint +from PySide2.QtGui import QMovie, QStandardItemModel, QStandardItem +from PySide2.QtWidgets import QLabel, QDialog, QVBoxLayout, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \ + QAbstractItemView, QPushButton, QGroupBox, QCheckBox + +from game.game import Event, Game +from qt_ui.windows.GameUpdateSignal import GameUpdateSignal +import qt_ui.uiconstants as CONST +from userdata.debriefing import wait_for_debriefing, Debriefing +from userdata.persistency import base_path + + +class QSettingsWindow(QDialog): + + def __init__(self, game: Game): + super(QSettingsWindow, self).__init__() + + self.game = game + + self.setModal(True) + self.setWindowTitle("Settings") + self.setWindowIcon(CONST.ICONS["Settings"]) + self.setMinimumSize(600, 250) + + self.initUi() + + def initUi(self): + self.layout = QGridLayout() + + self.categoryList = QListView() + self.right_layout = QStackedLayout() + + self.categoryList.setMaximumWidth(175) + + self.categoryModel = QStandardItemModel(self.categoryList) + + difficulty = QStandardItem("Difficulty") + difficulty.setIcon(CONST.ICONS["Missile"]) + difficulty.setEditable(False) + difficulty.setSelectable(True) + + generator = QStandardItem("Mission Generator") + generator.setIcon(CONST.ICONS["Generator"]) + generator.setEditable(False) + generator.setSelectable(True) + + cheat = QStandardItem("Cheat Menu") + cheat.setIcon(CONST.ICONS["Cheat"]) + cheat.setEditable(False) + cheat.setSelectable(True) + + self.categoryList.setIconSize(QSize(32, 32)) + self.categoryModel.appendRow(difficulty) + self.categoryModel.appendRow(generator) + self.categoryModel.appendRow(cheat) + + self.categoryList.setSelectionBehavior(QAbstractItemView.SelectRows) + self.categoryList.setModel(self.categoryModel) + self.categoryList.selectionModel().setCurrentIndex(self.categoryList.indexAt(QPoint(1,1)), QItemSelectionModel.Select) + self.categoryList.selectionModel().selectionChanged.connect(self.onSelectionChanged) + + self.initDifficultyLayout() + self.initGeneratorLayout() + self.initCheatLayout() + + self.right_layout.addWidget(self.difficultyPage) + self.right_layout.addWidget(self.generatorPage) + self.right_layout.addWidget(self.cheatPage) + + self.layout.addWidget(self.categoryList, 0, 0, 1, 1) + self.layout.addLayout(self.right_layout, 0, 1, 5, 1) + + self.setLayout(self.layout) + + def init(self): + pass + + def initDifficultyLayout(self): + + self.difficultyPage = QWidget() + self.difficultyLayout = QGridLayout() + self.difficultyLayout.setAlignment(Qt.AlignTop) + self.difficultyPage.setLayout(self.difficultyLayout) + + self.playerCoalitionSkill = QComboBox() + self.enemyCoalitionSkill = QComboBox() + self.enemyAASkill = QComboBox() + for skill in CONST.SKILL_OPTIONS: + self.playerCoalitionSkill.addItem(skill) + self.enemyCoalitionSkill.addItem(skill) + self.enemyAASkill.addItem(skill) + + self.playerCoalitionSkill.setCurrentIndex(CONST.SKILL_OPTIONS.index(self.game.settings.player_skill)) + self.enemyCoalitionSkill.setCurrentIndex(CONST.SKILL_OPTIONS.index(self.game.settings.enemy_skill)) + self.enemyAASkill.setCurrentIndex(CONST.SKILL_OPTIONS.index(self.game.settings.enemy_vehicle_skill)) + + self.playerCoalitionSkill.currentIndexChanged.connect(self.applySettings) + self.enemyCoalitionSkill.currentIndexChanged.connect(self.applySettings) + self.enemyAASkill.currentIndexChanged.connect(self.applySettings) + + self.difficultyLayout.addWidget(QLabel("Player coalition skill"), 0, 0) + self.difficultyLayout.addWidget(self.playerCoalitionSkill, 0, 1) + self.difficultyLayout.addWidget(QLabel("Enemy skill"), 1, 0) + self.difficultyLayout.addWidget(self.enemyCoalitionSkill, 1, 1) + self.difficultyLayout.addWidget(QLabel("Enemy AA and vehicles skill"), 2, 0) + self.difficultyLayout.addWidget(self.enemyAASkill, 2, 1) + + self.difficultyLabel = QComboBox() + [self.difficultyLabel.addItem(t) for t in CONST.LABELS_OPTIONS] + self.difficultyLabel.setCurrentIndex(CONST.LABELS_OPTIONS.index(self.game.settings.labels)) + self.difficultyLabel.currentIndexChanged.connect(self.applySettings) + + self.difficultyLayout.addWidget(QLabel("In Game Labels"), 3, 0) + self.difficultyLayout.addWidget(self.difficultyLabel, 3, 1) + + self.noNightMission = QCheckBox() + self.noNightMission.setChecked(self.game.settings.night_disabled) + self.noNightMission.toggled.connect(self.applySettings) + self.difficultyLayout.addWidget(QLabel("No night missions"), 4, 0) + self.difficultyLayout.addWidget(self.noNightMission, 4, 1) + + + def initGeneratorLayout(self): + self.generatorPage = QWidget() + self.generatorLayout = QGridLayout() + self.generatorLayout.setAlignment(Qt.AlignTop) + self.generatorPage.setLayout(self.generatorLayout) + + self.coldStart = QCheckBox() + self.coldStart.setChecked(self.game.settings.cold_start) + self.coldStart.toggled.connect(self.applySettings) + self.takeOffOnlyForPlayerGroup = QCheckBox() + self.takeOffOnlyForPlayerGroup.setChecked(self.game.settings.only_player_takeoff) + self.takeOffOnlyForPlayerGroup.toggled.connect(self.applySettings) + + self.generatorLayout.addWidget(QLabel("Aircraft cold start"), 0, 0) + self.generatorLayout.addWidget(self.coldStart, 0, 1) + self.generatorLayout.addWidget(QLabel("Takeoff only for player group"), 1, 0) + self.generatorLayout.addWidget(self.takeOffOnlyForPlayerGroup, 1, 1) + + + def initCheatLayout(self): + + self.cheatPage = QWidget() + self.cheatLayout = QGridLayout() + self.cheatPage.setLayout(self.cheatLayout) + + self.moneyCheatBox = QGroupBox("Money Cheat") + self.moneyCheatBox.setAlignment(Qt.AlignTop) + self.moneyCheatBoxLayout = QGridLayout() + self.moneyCheatBox.setLayout(self.moneyCheatBoxLayout) + + self.cheat25M = QPushButton("Cheat +25M") + self.cheat50M = QPushButton("Cheat +50M") + self.cheat100M = QPushButton("Cheat +100M") + self.cheat200M = QPushButton("Cheat +200M") + + self.cheat25M.clicked.connect(lambda: self.cheatMoney(25)) + self.cheat50M.clicked.connect(lambda: self.cheatMoney(50)) + self.cheat100M.clicked.connect(lambda: self.cheatMoney(100)) + self.cheat200M.clicked.connect(lambda: self.cheatMoney(200)) + + self.moneyCheatBoxLayout.addWidget(self.cheat25M, 0, 0) + self.moneyCheatBoxLayout.addWidget(self.cheat50M, 0, 1) + self.moneyCheatBoxLayout.addWidget(self.cheat100M, 1, 0) + self.moneyCheatBoxLayout.addWidget(self.cheat200M, 1, 1) + + self.cheatLayout.addWidget(self.moneyCheatBox, 0, 0) + + def cheatMoney(self, amount): + self.game.budget += amount + GameUpdateSignal.get_instance().updateGame(self.game) + + def applySettings(self): + self.game.settings.player_skill = CONST.SKILL_OPTIONS[self.playerCoalitionSkill.currentIndex()] + self.game.settings.enemy_skill = CONST.SKILL_OPTIONS[self.enemyCoalitionSkill.currentIndex()] + self.game.settings.enemy_vehicle_skill = CONST.SKILL_OPTIONS[self.enemyAASkill.currentIndex()] + self.game.settings.labels = CONST.LABELS_OPTIONS[self.difficultyLabel.currentIndex()] + self.game.settings.night_disabled = self.noNightMission.isChecked() + self.game.settings.only_player_takeoff = self.takeOffOnlyForPlayerGroup.isChecked() + self.game.settings.cold_start = self.coldStart.isChecked() + + GameUpdateSignal.get_instance().updateGame(self.game) + + def onSelectionChanged(self): + index = self.categoryList.selectionModel().currentIndex().row() + self.right_layout.setCurrentIndex(index) \ No newline at end of file diff --git a/resources/ui/misc/cheat.png b/resources/ui/misc/cheat.png new file mode 100644 index 0000000000000000000000000000000000000000..cfc9d3e45e98503313323ec14f91900f3f9e88d7 GIT binary patch literal 5050 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 literal 0 HcmV?d00001 diff --git a/resources/ui/misc/missile.png b/resources/ui/misc/missile.png new file mode 100644 index 0000000000000000000000000000000000000000..61eadcd6dc741ebcc1e3eba1bd9e882e5c5d9777 GIT binary patch literal 3795 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 literal 0 HcmV?d00001