Update the UI to show sim state.

https://github.com/dcs-liberation/dcs_liberation/issues/1704
This commit is contained in:
Dan Albert
2021-10-31 22:25:11 -07:00
parent 87bf3110c8
commit 03430a4df5
12 changed files with 188 additions and 39 deletions

View File

@@ -1,3 +1,5 @@
from datetime import datetime
from PySide2.QtGui import QPixmap
from PySide2.QtWidgets import (
QFrame,
@@ -12,6 +14,7 @@ from dcs.weather import CloudPreset, Weather as PydcsWeather
import qt_ui.uiconstants as CONST
from game.utils import mps
from game.weather import Conditions, TimeOfDay
from qt_ui.simcontroller import SimController
class QTimeTurnWidget(QGroupBox):
@@ -19,8 +22,9 @@ class QTimeTurnWidget(QGroupBox):
UI Component to display current turn and time info
"""
def __init__(self):
def __init__(self, sim_controller: SimController) -> None:
super(QTimeTurnWidget, self).__init__("Turn")
self.sim_controller = sim_controller
self.setStyleSheet(
"padding: 0px; margin-left: 5px; margin-right: 0px; margin-top: 1ex; margin-bottom: 5px; border-right: 0px"
)
@@ -49,17 +53,30 @@ class QTimeTurnWidget(QGroupBox):
self.time_display = QLabel()
self.time_column.addWidget(self.time_display)
def setCurrentTurn(self, turn: int, conditions: Conditions) -> None:
sim_controller.sim_update.connect(self.on_sim_update)
def on_sim_update(self) -> None:
time = self.sim_controller.current_time_in_sim
if time is None:
self.date_display.setText("")
self.time_display.setText("")
else:
self.set_date_and_time(time)
def set_current_turn(self, turn: int, conditions: Conditions) -> None:
"""Sets the turn information display.
:arg turn Current turn number.
:arg conditions Current time and weather conditions.
"""
self.daytime_icon.setPixmap(self.icons[conditions.time_of_day])
self.date_display.setText(conditions.start_time.strftime("%d %b %Y"))
self.time_display.setText(conditions.start_time.strftime("%H:%M:%S Local"))
self.set_date_and_time(conditions.start_time)
self.setTitle(f"Turn {turn}")
def set_date_and_time(self, time: datetime) -> None:
self.date_display.setText(time.strftime("%d %b %Y"))
self.time_display.setText(time.strftime("%H:%M:%S Local"))
class QWeatherWidget(QGroupBox):
"""
@@ -265,7 +282,7 @@ class QConditionsWidget(QFrame):
UI Component to display Turn Number, Day Time & Hour and weather combined.
"""
def __init__(self):
def __init__(self, sim_controller: SimController) -> None:
super(QConditionsWidget, self).__init__()
self.setProperty("style", "QConditionsWidget")
@@ -275,7 +292,7 @@ class QConditionsWidget(QFrame):
self.layout.setVerticalSpacing(0)
self.setLayout(self.layout)
self.time_turn_widget = QTimeTurnWidget()
self.time_turn_widget = QTimeTurnWidget(sim_controller)
self.time_turn_widget.setStyleSheet("QGroupBox { margin-right: 0px; }")
self.layout.addWidget(self.time_turn_widget, 0, 0)
@@ -292,6 +309,6 @@ class QConditionsWidget(QFrame):
:arg turn Current turn number.
:arg conditions Current time and weather conditions.
"""
self.time_turn_widget.setCurrentTurn(turn, conditions)
self.time_turn_widget.set_current_turn(turn, conditions)
self.weather_widget.setCurrentTurn(turn, conditions)
self.weather_widget.show()

View File

@@ -38,7 +38,7 @@ class QTopPanel(QFrame):
self.setMaximumHeight(70)
self.conditionsWidget = QConditionsWidget()
self.conditionsWidget = QConditionsWidget(sim_controller)
self.budgetBox = QBudgetBox(self.game)
pass_turn_text = "Pass Turn"

View File

@@ -15,6 +15,7 @@ from PySide2.QtWebEngineWidgets import (
from game import Game
from qt_ui.models import GameModel
from qt_ui.simcontroller import SimController
from qt_ui.widgets.map.mapmodel import MapModel
@@ -35,11 +36,13 @@ class LoggingWebPage(QWebEnginePage):
class QLiberationMap(QWebEngineView):
def __init__(self, game_model: GameModel, parent) -> None:
def __init__(
self, game_model: GameModel, sim_controller: SimController, parent
) -> None:
super().__init__(parent)
self.game_model = game_model
self.setMinimumSize(800, 600)
self.map_model = MapModel(game_model)
self.map_model = MapModel(game_model, sim_controller)
self.channel = QWebChannel()
self.channel.registerObject("game", self.map_model)

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
import logging
from datetime import timedelta
from typing import List, Optional, Tuple, Union, Iterator
from typing import Iterator, List, Optional, Tuple, Union
from PySide2.QtCore import Property, QObject, Signal, Slot
from dcs import Point
@@ -10,40 +10,38 @@ from dcs.unit import Unit
from dcs.vehicles import vehicle_map
from shapely.geometry import (
LineString,
MultiLineString,
MultiPolygon,
Point as ShapelyPoint,
Polygon,
MultiPolygon,
MultiLineString,
)
from game import Game
from game.ato.airtaaskingorder import AirTaskingOrder
from game.ato.flight import Flight
from game.ato.flightstate import InFlight
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flightwaypointtype import FlightWaypointType
from game.dcs.groundunittype import GroundUnitType
from game.flightplan import JoinZoneGeometry, HoldZoneGeometry
from game.flightplan import HoldZoneGeometry, JoinZoneGeometry
from game.flightplan.ipzonegeometry import IpZoneGeometry
from game.navmesh import NavMesh, NavMeshPoly
from game.profiling import logged_duration
from game.theater import (
ConflictTheater,
ControlPoint,
TheaterGroundObject,
ControlPointStatus,
FrontLine,
LatLon,
ControlPointStatus,
TheaterGroundObject,
)
from game.threatzones import ThreatZones
from game.transfers import MultiGroupTransport, TransportMap
from game.utils import meters, nautical_miles
from game.ato.airtaaskingorder import AirTaskingOrder
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flight import Flight
from gen.flights.flightplan import (
FlightPlan,
PatrollingFlightPlan,
CasFlightPlan,
)
from game.flightplan.ipzonegeometry import IpZoneGeometry
from gen.flights.flightplan import CasFlightPlan, FlightPlan, PatrollingFlightPlan
from qt_ui.dialogs import Dialog
from qt_ui.models import GameModel, AtoModel
from qt_ui.models import AtoModel, GameModel
from qt_ui.simcontroller import SimController
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.basemenu.QBaseMenu2 import QBaseMenu2
from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu
@@ -537,6 +535,7 @@ class WaypointJs(QObject):
class FlightJs(QObject):
positionChanged = Signal()
flightPlanChanged = Signal()
blueChanged = Signal()
selectedChanged = Signal()
@@ -588,6 +587,13 @@ class FlightJs(QObject):
waypoints.append(waypoint)
return waypoints
@Property(list, notify=positionChanged)
def position(self) -> LeafletLatLon:
if isinstance(self.flight.state, InFlight):
ll = self.theater.point_to_ll(self.flight.state.estimate_position())
return [ll.latitude, ll.longitude]
return []
@Property(list, notify=flightPlanChanged)
def flightPlan(self) -> List[WaypointJs]:
return self._waypoints
@@ -1032,7 +1038,7 @@ class MapModel(QObject):
joinZonesChanged = Signal()
holdZonesChanged = Signal()
def __init__(self, game_model: GameModel) -> None:
def __init__(self, game_model: GameModel, sim_controller: SimController) -> None:
super().__init__()
self.game_model = game_model
self._map_center = [0, 0]
@@ -1059,6 +1065,7 @@ class MapModel(QObject):
GameUpdateSignal.get_instance().flight_selection_changed.connect(
self.set_flight_selection
)
sim_controller.sim_update.connect(self.on_sim_update)
self.reset()
def clear(self) -> None:
@@ -1076,6 +1083,10 @@ class MapModel(QObject):
self._ip_zones = IpZonesJs.empty()
self.cleared.emit()
def on_sim_update(self) -> None:
for flight in self._flights:
flight.positionChanged.emit()
def set_package_selection(self, index: int) -> None:
# Optional[int] isn't a valid type for a Qt signal. None will be converted to
# zero automatically. We use -1 to indicate no selection.