Waiting and Debriefing Window, QT UI is now functionnal.

This commit is contained in:
Khopa 2019-07-11 21:31:16 +02:00
parent c4dc432be1
commit adb9e38ff4
11 changed files with 246 additions and 51 deletions

View File

@ -1,17 +1,31 @@
import logging
import os
import sys
from time import sleep
import dcs
from PySide2.QtGui import QPixmap
from PySide2.QtWidgets import QApplication, QLabel, QSplashScreen
from qt_ui import uiconstants
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.QLiberationWindow import QLiberationWindow
from userdata import persistency
from userdata import persistency, logging as logging_module
if __name__ == "__main__":
assert len(sys.argv) >= 3, "__init__.py should be started with two mandatory arguments: %UserProfile% location and application version"
persistency.setup(sys.argv[1])
dcs.planes.FlyingType.payload_dirs = [
os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources\\payloads")]
VERSION_STRING = sys.argv[2]
logging_module.setup_version_string(VERSION_STRING)
logging.info("Using {} as userdata folder".format(persistency.base_path()))
app = QApplication(sys.argv)
# Splash screen setup
@ -38,4 +52,5 @@ if __name__ == "__main__":
window.show()
splash.finish(window)
sys.exit(app.exec_())
sys.exit(app.exec_())

View File

@ -52,7 +52,12 @@ class QMapControlPoint(QGraphicsRectItem):
self.update()
def contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent):
openBaseMenu = QAction("Open base menu")
if self.model.captured:
openBaseMenu = QAction("Open base menu")
else:
openBaseMenu = QAction("Open intel menu")
openBaseMenu.triggered.connect(self.openBaseMenu)
menu = QMenu("Menu", self.parent)

View File

@ -15,7 +15,6 @@ class QMapEvent(QGraphicsRectItem):
self.parent = parent
self.setAcceptHoverEvents(True)
self.setZValue(2)
print(x,y,w,h)
self.setToolTip(str(self.gameEvent))
def paint(self, painter, option, widget=None):
@ -31,7 +30,6 @@ class QMapEvent(QGraphicsRectItem):
painter.setBrush(CONST.COLORS["red"])
painter.drawRect(option.rect)
print(option.rect)
painter.drawPixmap(option.rect, CONST.EVENT_ICONS[self.gameEvent.__class__])
painter.restore()
@ -39,5 +37,5 @@ class QMapEvent(QGraphicsRectItem):
self.openBriefing()
def openBriefing(self):
self.briefing = QBriefingWindow(self.window(), self.gameEvent)
self.briefing = QBriefingWindow(self.gameEvent)
self.briefing.show()

View File

@ -1,11 +1,22 @@
from PySide2.QtCore import QObject, Signal
from game import Game
from game.event import Event, Debriefing
class DebriefingSignal:
def __init__(self, game, gameEvent, debriefing):
self.game = game
self.gameEvent = gameEvent
self.debriefing = debriefing
class GameUpdateSignal(QObject):
instance = None
gameupdated = Signal(Game)
debriefingReceived = Signal(DebriefingSignal)
def __init__(self):
super(GameUpdateSignal, self).__init__()
@ -14,6 +25,11 @@ class GameUpdateSignal(QObject):
def updateGame(self, game: Game):
self.gameupdated.emit(game)
def sendDebriefing(self, game: Game, gameEvent: Event, debriefing: Debriefing):
sig = DebriefingSignal(game, gameEvent, debriefing)
self.gameupdated.emit(game)
self.debriefingReceived.emit(sig)
@staticmethod
def get_instance():
return GameUpdateSignal.instance

View File

@ -1,6 +1,7 @@
from PySide2.QtCore import Qt
from PySide2.QtGui import QWindow, QCloseEvent
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget, QFrame, QDialog, QVBoxLayout, QGridLayout, QPushButton
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget, QFrame, QDialog, QVBoxLayout, QGridLayout, QPushButton, \
QGroupBox
from dcs.unittype import UnitType
from game.event import UnitsDeliveryEvent
@ -30,7 +31,7 @@ class QBaseMenu(QDialog):
self.deliveryEvent = self.game.units_delivery_event(self.cp)
self.setWindowFlags(Qt.WindowStaysOnTopHint)
self.setMinimumSize(200, 200)
self.setMinimumSize(300, 200)
self.setModal(True)
self.initUi()
@ -52,13 +53,22 @@ class QBaseMenu(QDialog):
self.topLayoutWidget.setProperty("style", "baseMenuHeader")
self.topLayoutWidget.setLayout(self.topLayout)
units = {
CAP: db.find_unittype(CAP, self.game.player_name),
Embarking: db.find_unittype(Embarking, self.game.player_name),
AirDefence: db.find_unittype(AirDefence, self.game.player_name),
CAS: db.find_unittype(CAS, self.game.player_name),
PinpointStrike: db.find_unittype(PinpointStrike, self.game.player_name),
}
if self.cp.captured:
units = {
CAP: db.find_unittype(CAP, self.game.player_name),
Embarking: db.find_unittype(Embarking, self.game.player_name),
CAS: db.find_unittype(CAS, self.game.player_name),
PinpointStrike: db.find_unittype(PinpointStrike, self.game.player_name),
AirDefence: db.find_unittype(AirDefence, self.game.player_name),
}
else:
units = {
CAP: db.find_unittype(CAP, self.game.enemy_name),
Embarking: db.find_unittype(Embarking, self.game.enemy_name),
AirDefence: db.find_unittype(AirDefence, self.game.enemy_name),
CAS: db.find_unittype(CAS, self.game.enemy_name),
PinpointStrike: db.find_unittype(PinpointStrike, self.game.enemy_name),
}
self.mainLayout = QVBoxLayout()
self.mainLayout.addWidget(self.topLayoutWidget)
@ -111,8 +121,33 @@ class QBaseMenu(QDialog):
for unit_type in units_column:
add_purchase_row(unit_type)
self.mainLayout.addLayout(self.unitLayout)
else:
intel = QGroupBox("Intel")
intelLayout = QVBoxLayout()
row = 0
for task_type in units.keys():
units_column = list(set(units[task_type]))
if sum([self.cp.base.total_units_of_type(u) for u in units_column]) > 0:
group = QGroupBox(db.task_name(task_type))
groupLayout = QGridLayout()
group.setLayout(groupLayout)
row = 0
for unit_type in units_column:
existing_units = self.cp.base.total_units_of_type(unit_type)
if existing_units == 0:
continue
groupLayout.addWidget(QLabel("<b>" + db.unit_type_name(unit_type) + "</b>"), row, 0)
groupLayout.addWidget(QLabel(str(existing_units)), row, 1)
row += 1
intelLayout.addWidget(group)
self.mainLayout.addLayout(intelLayout)
self.mainLayout.addLayout(self.unitLayout)
self.setLayout(self.mainLayout)

View File

@ -7,14 +7,15 @@ from pip._internal.utils import typing
from game.game import AWACS_BUDGET_COST, PinpointStrike, db, Event, FrontlineAttackEvent, FrontlinePatrolEvent, Task, \
UnitType
from qt_ui.windows.QWaitingForMissionResultWindow import QWaitingForMissionResultWindow
from userdata.persistency import base_path
import qt_ui.uiconstants as CONST
class QBriefingWindow(QDialog):
def __init__(self, parent, gameEvent: Event):
super(QBriefingWindow, self).__init__(parent)
def __init__(self, gameEvent: Event):
super(QBriefingWindow, self).__init__()
self.gameEvent = gameEvent
self.setWindowTitle("Briefing : " + str(gameEvent))
self.setMinimumSize(200,200)
@ -40,7 +41,7 @@ class QBriefingWindow(QDialog):
self.depart_from = QComboBox()
for cp in [b for b in self.game.theater.controlpoints if b.captured]:
self.depart_from.addItem(str(cp.name))
self.depart_from.addItem(str(cp.name), cp)
self.depart_layout.addWidget(self.depart_from_label)
self.depart_layout.addWidget(self.depart_from)
@ -91,24 +92,11 @@ class QBriefingWindow(QDialog):
scramble_row(flight_task, t, c, True, row)
row += 1
# Options
"""
header("Ready?")
self.error_label = label("", columnspan=4)
self.error_label["fg"] = RED
Button(self.frame, text="Commit", command=self.start, **STYLES["btn-primary"]).grid(column=0, row=row,
sticky=E, padx=5,
pady=(10, 10))
Button(self.frame, text="Back", command=self.dismiss, **STYLES["btn-warning"]).grid(column=3, row=row,
sticky=E, padx=5,
pady=(10, 10))"""
self.action_layout = QHBoxLayout()
self.commit_button = QPushButton("Commit")
self.back_button = QPushButton("Commit")
self.back_button = QPushButton("Cancel")
self.commit_button.clicked.connect(self.start)
self.back_button.clicked.connect(self.close)
self.action_layout.addWidget(self.commit_button)
self.action_layout.addWidget(self.back_button)
@ -169,7 +157,6 @@ class QBriefingWindow(QDialog):
def debriefing_directory_location(self) -> str:
return os.path.join(base_path(), "liberation_debriefings")
def start(self):
if self.awacs_checkbox.isChecked() == 1:
@ -185,6 +172,11 @@ class QBriefingWindow(QDialog):
ca_slots = 0
self.gameEvent.ca_slots = ca_slots
# Resolve Departure CP
self.gameEvent.departure_cp = self.depart_from.itemData(self.depart_from.currentIndex())
flights = {k: {} for k in self.gameEvent.tasks} # type: db.TaskForceDict
units_scramble_counts = {} # type: typing.Dict[typing.Type[UnitType], int]
tasks_scramble_counts = {} # type: typing.Dict[typing.Type[Task], int]
@ -243,11 +235,12 @@ class QBriefingWindow(QDialog):
self.gameEvent.player_defending(flights)
self.gameEvent.departure_cp = self.gameEvent.from_cp
self.game.initiate_event(self.gameEvent)
# EventResultsMenu(self.window, self.parent, self.game, self.gameEvent).display()
waiting = QWaitingForMissionResultWindow(self.gameEvent, self.game)
waiting.show()
self.close()
def showErrorMessage(self, text):
about = QMessageBox()

View File

@ -1,17 +1,82 @@
from PySide2.QtGui import QWindow
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget
import os
from PySide2 import QtCore
from PySide2.QtGui import QMovie
from PySide2.QtWidgets import QLabel, QDialog, QVBoxLayout, QGroupBox, QGridLayout, QPushButton
from game.game import Event, db, Game
from userdata.debriefing import wait_for_debriefing, Debriefing
from userdata.persistency import base_path
class QDebriefingWindow(QWindow):
class QDebriefingWindow(QDialog):
def __init__(self, parent):
super(QDebriefingWindow, self).__init__(parent)
self.initUi()
def __init__(self, debriefing: Debriefing, gameEvent: Event, game: Game):
super(QDebriefingWindow, self).__init__()
def initUi(self):
layout = QHBoxLayout()
layout.addWidget(QLabel("TODO : This will be the debriefing menu"))
self.setModal(True)
self.setWindowTitle("Debriefing")
self.setMinimumSize(300, 200)
central_widget = QWidget()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
self.game = game
self.gameEvent = gameEvent
self.debriefing = debriefing
self.player_losses = debriefing.destroyed_units.get(self.game.player_country, {})
self.enemy_losses = debriefing.destroyed_units.get(self.game.enemy_country, {})
self.initUI()
def initUI(self):
self.layout = QVBoxLayout()
# Result
if self.gameEvent.is_successfull(self.debriefing):
title = QLabel("<b>Operation Succesfull !</b>")
title.setProperty("style", "title-success")
else:
title = QLabel("<b>Operation failed !</b>")
title.setProperty("style", "title-danger")
self.layout.addWidget(title)
# Player lost units
lostUnits = QGroupBox(self.game.player_country + "'s lost units :")
lostUnitsLayout = QGridLayout()
lostUnits.setLayout(lostUnitsLayout)
row = 0
for unit_type, count in self.player_losses.items():
lostUnitsLayout.addWidget(QLabel(db.unit_type_name(unit_type)), row, 0)
lostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
row += 1
self.layout.addWidget(lostUnits)
# Enemy lost units
enemylostUnits = QGroupBox(self.game.enemy_country + "'s lost units :")
enemylostUnitsLayout = QGridLayout()
enemylostUnits.setLayout(enemylostUnitsLayout)
row = 0
if self.debriefing.destroyed_objects:
enemylostUnitsLayout.addWidget(QLabel("Ground assets"), row, 0)
enemylostUnitsLayout.addWidget(QLabel("{}".format(len(self.debriefing.destroyed_objects))), row, 1)
row += 1
for unit_type, count in self.enemy_losses.items():
if count == 0:
continue
enemylostUnitsLayout.addWidget(QLabel(db.unit_type_name(unit_type)), row, 0)
enemylostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
row += 1
self.layout.addWidget(enemylostUnits)
# confirm button
okay = QPushButton("Okay")
okay.clicked.connect(self.close)
self.layout.addWidget(okay)
self.setLayout(self.layout)

View File

@ -8,7 +8,8 @@ from game import Game
from qt_ui.uiconstants import URLS
from qt_ui.widgets.QTopPanel import QTopPanel
from qt_ui.widgets.map.QLiberationMap import QLiberationMap
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal, DebriefingSignal
from qt_ui.windows.QDebriefingWindow import QDebriefingWindow
from qt_ui.windows.QNewGameWizard import NewGameWizard
from userdata import persistency
@ -52,6 +53,7 @@ class QLiberationWindow(QMainWindow):
def connectSignals(self):
GameUpdateSignal.get_instance().gameupdated.connect(self.setGame)
GameUpdateSignal.get_instance().debriefingReceived.connect(self.onDebriefing)
def initActions(self):
self.newGameAction = QAction("New Game", self)
@ -154,3 +156,8 @@ class QLiberationWindow(QMainWindow):
about.setText(text)
print(about.textFormat())
about.exec_()
def onDebriefing(self, debrief: DebriefingSignal):
print("On Debriefing")
self.debriefing = QDebriefingWindow(debrief.debriefing, debrief.gameEvent, debrief.game)
self.debriefing.show()

View File

@ -0,0 +1,61 @@
import os
from PySide2 import QtCore
from PySide2.QtGui import QMovie
from PySide2.QtWidgets import QLabel, QDialog, QVBoxLayout
from game.game import Event, Game
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from userdata.debriefing import wait_for_debriefing, Debriefing
from userdata.persistency import base_path
class QWaitingForMissionResultWindow(QDialog):
def __init__(self, gameEvent: Event, game: Game):
super(QWaitingForMissionResultWindow, self).__init__()
self.setModal(True)
self.gameEvent = gameEvent
self.game = game
self.setWindowTitle("Waiting for mission completion.")
self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False)
self.initUi()
wait_for_debriefing(lambda debriefing: self.process_debriefing(debriefing))
def initUi(self):
self.layout = QVBoxLayout()
self.layout.addWidget(QLabel("<b>You are clear for takeoff !</b>"))
self.layout.addWidget(QLabel("In DCS open and play the mission : "))
self.layout.addWidget(QLabel("<i>liberation_nextturn</i>"))
self.layout.addWidget(QLabel("or"))
self.layout.addWidget(QLabel("<i>liberation_nextturn_quick</i>"))
self.layout.addWidget(QLabel("<b>Then save the debriefing to the folder :</b>"))
self.layout.addWidget(QLabel(self.debriefing_directory_location()))
progress = QLabel("")
progress.setAlignment(QtCore.Qt.AlignCenter)
progressBar = QMovie("./resources/ui/loader.gif")
progress.setMovie(progressBar)
self.layout.addWidget(progress)
progressBar.start()
self.setLayout(self.layout)
def process_debriefing(self, debriefing: Debriefing):
print("DEBRIEFING !!")
debriefing.calculate_units(regular_mission=self.gameEvent.operation.regular_mission,
quick_mission=self.gameEvent.operation.quick_mission,
player_country=self.game.player_country,
enemy_country=self.game.enemy_country)
self.game.finish_event(event=self.gameEvent, debriefing=debriefing)
self.game.pass_turn(ignored_cps=[self.gameEvent.to_cp, ])
GameUpdateSignal.get_instance().sendDebriefing(self.game, self.gameEvent, debriefing)
self.close()
def debriefing_directory_location(self) -> str:
return os.path.join(base_path(), "liberation_debriefings")

BIN
resources/ui/loader.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -139,7 +139,7 @@ class Debriefing:
for unit in group.units:
if unit.id in self._dead_units:
unit_type = db.unit_type_of(unit)
logging.info("debriefing: found dead unit {} ({}, {})".format(str(unit.name), unit.id, unit_type))
logging.info("debriefing: found dead unit {} ({}, {}) for country {}".format(str(unit.name), unit.id, unit_type, country_name))
assert country_name
assert unit_type