Add base selection UI to startup.

https://github.com/dcs-liberation/dcs_liberation/issues/1145
This commit is contained in:
Dan Albert 2021-08-14 18:32:21 -07:00
parent 90ad1f4a61
commit 9768fb3493

View File

@ -1,4 +1,4 @@
from typing import Optional, Callable from typing import Optional, Callable, Iterable
from PySide2.QtCore import ( from PySide2.QtCore import (
QItemSelectionModel, QItemSelectionModel,
@ -24,11 +24,13 @@ from PySide2.QtWidgets import (
QHBoxLayout, QHBoxLayout,
QStackedLayout, QStackedLayout,
QTabWidget, QTabWidget,
QComboBox,
) )
from game import Game from game import Game
from game.dcs.aircrafttype import AircraftType from game.dcs.aircrafttype import AircraftType
from game.squadrons import AirWing, Pilot, Squadron from game.squadrons import AirWing, Pilot, Squadron
from game.theater import ControlPoint, ConflictTheater
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
from qt_ui.models import AirWingModel, SquadronModel from qt_ui.models import AirWingModel, SquadronModel
from qt_ui.uiconstants import AIRCRAFT_ICONS from qt_ui.uiconstants import AIRCRAFT_ICONS
@ -96,8 +98,41 @@ class AllowedMissionTypeControls(QVBoxLayout):
self.allowed_mission_types.remove(task) self.allowed_mission_types.remove(task)
class SquadronBaseSelector(QComboBox):
"""A combo box for selecting a squadrons home air base.
The combo box will automatically be populated with all air bases compatible with the
squadron.
"""
def __init__(
self,
bases: Iterable[ControlPoint],
squadron: Squadron,
) -> None:
super().__init__()
self.bases = list(bases)
self.squadron = squadron
self.setSizeAdjustPolicy(self.AdjustToContents)
for base in self.bases:
if not base.can_operate(self.squadron.aircraft):
continue
self.addItem(base.name, base)
self.model().sort(0)
self.setCurrentText(self.squadron.location.name)
@property
def available(self) -> int:
origin = self.currentData()
if origin is None:
return 0
inventory = self.global_inventory.for_control_point(origin)
return inventory.available(self.aircraft)
class SquadronConfigurationBox(QGroupBox): class SquadronConfigurationBox(QGroupBox):
def __init__(self, squadron: Squadron) -> None: def __init__(self, squadron: Squadron, theater: ConflictTheater) -> None:
super().__init__() super().__init__()
self.setCheckable(True) self.setCheckable(True)
self.squadron = squadron self.squadron = squadron
@ -119,6 +154,13 @@ class SquadronConfigurationBox(QGroupBox):
self.nickname_edit.textChanged.connect(self.on_nickname_changed) self.nickname_edit.textChanged.connect(self.on_nickname_changed)
left_column.addWidget(self.nickname_edit) left_column.addWidget(self.nickname_edit)
left_column.addWidget(QLabel("Base:"))
self.base_selector = SquadronBaseSelector(
theater.control_points_for(squadron.player), squadron
)
self.base_selector.currentIndexChanged.connect(self.on_base_changed)
left_column.addWidget(self.base_selector)
if squadron.player: if squadron.player:
player_label = QLabel( player_label = QLabel(
"Players (one per line, leave empty for an AI-only squadron):" "Players (one per line, leave empty for an AI-only squadron):"
@ -149,6 +191,12 @@ class SquadronConfigurationBox(QGroupBox):
def on_nickname_changed(self, text: str) -> None: def on_nickname_changed(self, text: str) -> None:
self.squadron.nickname = text self.squadron.nickname = text
def on_base_changed(self, index: int) -> None:
base = self.base_selector.itemData(index)
if base is None:
raise RuntimeError("Base cannot be none")
self.squadron.assign_to_base(base)
def reset_title(self) -> None: def reset_title(self) -> None:
self.setTitle(f"{self.squadron.name} - {self.squadron.aircraft}") self.setTitle(f"{self.squadron.name} - {self.squadron.aircraft}")
@ -165,11 +213,11 @@ class SquadronConfigurationBox(QGroupBox):
class SquadronConfigurationLayout(QVBoxLayout): class SquadronConfigurationLayout(QVBoxLayout):
def __init__(self, squadrons: list[Squadron]) -> None: def __init__(self, squadrons: list[Squadron], theater: ConflictTheater) -> None:
super().__init__() super().__init__()
self.squadron_configs = [] self.squadron_configs = []
for squadron in squadrons: for squadron in squadrons:
squadron_config = SquadronConfigurationBox(squadron) squadron_config = SquadronConfigurationBox(squadron, theater)
self.squadron_configs.append(squadron_config) self.squadron_configs.append(squadron_config)
self.addWidget(squadron_config) self.addWidget(squadron_config)
@ -182,12 +230,12 @@ class SquadronConfigurationLayout(QVBoxLayout):
class AircraftSquadronsPage(QWidget): class AircraftSquadronsPage(QWidget):
def __init__(self, squadrons: list[Squadron]) -> None: def __init__(self, squadrons: list[Squadron], theater: ConflictTheater) -> None:
super().__init__() super().__init__()
layout = QVBoxLayout() layout = QVBoxLayout()
self.setLayout(layout) self.setLayout(layout)
self.squadrons_config = SquadronConfigurationLayout(squadrons) self.squadrons_config = SquadronConfigurationLayout(squadrons, theater)
scrolling_widget = QWidget() scrolling_widget = QWidget()
scrolling_widget.setLayout(self.squadrons_config) scrolling_widget.setLayout(self.squadrons_config)
@ -205,12 +253,12 @@ class AircraftSquadronsPage(QWidget):
class AircraftSquadronsPanel(QStackedLayout): class AircraftSquadronsPanel(QStackedLayout):
def __init__(self, air_wing: AirWing) -> None: def __init__(self, air_wing: AirWing, theater: ConflictTheater) -> None:
super().__init__() super().__init__()
self.air_wing = air_wing self.air_wing = air_wing
self.squadrons_pages: dict[AircraftType, AircraftSquadronsPage] = {} self.squadrons_pages: dict[AircraftType, AircraftSquadronsPage] = {}
for aircraft, squadrons in self.air_wing.squadrons.items(): for aircraft, squadrons in self.air_wing.squadrons.items():
page = AircraftSquadronsPage(squadrons) page = AircraftSquadronsPage(squadrons, theater)
self.addWidget(page) self.addWidget(page)
self.squadrons_pages[aircraft] = page self.squadrons_pages[aircraft] = page
@ -262,7 +310,7 @@ class AircraftTypeList(QListView):
class AirWingConfigurationTab(QWidget): class AirWingConfigurationTab(QWidget):
def __init__(self, air_wing: AirWing) -> None: def __init__(self, air_wing: AirWing, theater: ConflictTheater) -> None:
super().__init__() super().__init__()
layout = QHBoxLayout() layout = QHBoxLayout()
@ -272,7 +320,7 @@ class AirWingConfigurationTab(QWidget):
type_list.page_index_changed.connect(self.on_aircraft_changed) type_list.page_index_changed.connect(self.on_aircraft_changed)
layout.addWidget(type_list) layout.addWidget(type_list)
self.squadrons_panel = AircraftSquadronsPanel(air_wing) self.squadrons_panel = AircraftSquadronsPanel(air_wing, theater)
layout.addLayout(self.squadrons_panel) layout.addLayout(self.squadrons_panel)
def apply(self) -> None: def apply(self) -> None:
@ -317,7 +365,7 @@ class AirWingConfigurationDialog(QDialog):
self.tabs = [] self.tabs = []
for coalition in game.coalitions: for coalition in game.coalitions:
coalition_tab = AirWingConfigurationTab(coalition.air_wing) coalition_tab = AirWingConfigurationTab(coalition.air_wing, game.theater)
name = "Blue" if coalition.player else "Red" name = "Blue" if coalition.player else "Red"
tab_widget.addTab(coalition_tab, name) tab_widget.addTab(coalition_tab, name)
self.tabs.append(coalition_tab) self.tabs.append(coalition_tab)