mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Add per-aircraft tabs to air wing configuration.
This commit is contained in:
parent
c2951e5e41
commit
270f87f193
@ -1,21 +1,20 @@
|
|||||||
import itertools
|
from typing import Optional, Callable
|
||||||
import logging
|
|
||||||
from collections import defaultdict
|
|
||||||
from typing import Optional, Callable, Iterator
|
|
||||||
|
|
||||||
from PySide2.QtCore import (
|
from PySide2.QtCore import (
|
||||||
QItemSelectionModel,
|
QItemSelectionModel,
|
||||||
QModelIndex,
|
QModelIndex,
|
||||||
QSize,
|
QSize,
|
||||||
Qt,
|
Qt,
|
||||||
|
QItemSelection,
|
||||||
|
Signal,
|
||||||
)
|
)
|
||||||
|
from PySide2.QtGui import QStandardItemModel, QStandardItem, QIcon
|
||||||
from PySide2.QtWidgets import (
|
from PySide2.QtWidgets import (
|
||||||
QAbstractItemView,
|
QAbstractItemView,
|
||||||
QDialog,
|
QDialog,
|
||||||
QListView,
|
QListView,
|
||||||
QVBoxLayout,
|
QVBoxLayout,
|
||||||
QGroupBox,
|
QGroupBox,
|
||||||
QGridLayout,
|
|
||||||
QLabel,
|
QLabel,
|
||||||
QWidget,
|
QWidget,
|
||||||
QScrollArea,
|
QScrollArea,
|
||||||
@ -23,12 +22,15 @@ from PySide2.QtWidgets import (
|
|||||||
QTextEdit,
|
QTextEdit,
|
||||||
QCheckBox,
|
QCheckBox,
|
||||||
QHBoxLayout,
|
QHBoxLayout,
|
||||||
|
QStackedLayout,
|
||||||
)
|
)
|
||||||
|
|
||||||
from game import Game
|
from game import Game
|
||||||
|
from game.dcs.aircrafttype import AircraftType
|
||||||
from game.squadrons import Squadron, AirWing, Pilot
|
from game.squadrons import Squadron, AirWing, Pilot
|
||||||
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.windows.AirWingDialog import SquadronDelegate
|
from qt_ui.windows.AirWingDialog import SquadronDelegate
|
||||||
from qt_ui.windows.SquadronDialog import SquadronDialog
|
from qt_ui.windows.SquadronDialog import SquadronDialog
|
||||||
|
|
||||||
@ -151,60 +153,33 @@ class SquadronConfigurationBox(QGroupBox):
|
|||||||
return self.squadron
|
return self.squadron
|
||||||
|
|
||||||
|
|
||||||
class AirWingConfigurationLayout(QVBoxLayout):
|
class SquadronConfigurationLayout(QVBoxLayout):
|
||||||
def __init__(self, air_wing: AirWing) -> None:
|
def __init__(self, squadrons: list[Squadron]) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.air_wing = air_wing
|
|
||||||
self.squadron_configs = []
|
self.squadron_configs = []
|
||||||
|
for squadron in squadrons:
|
||||||
doc_url = (
|
|
||||||
"https://github.com/dcs-liberation/dcs_liberation/wiki/Squadrons-and-pilots"
|
|
||||||
)
|
|
||||||
doc_label = QLabel(
|
|
||||||
"Use this opportunity to customize the squadrons available to your "
|
|
||||||
"coalition. <strong>This is your<br />"
|
|
||||||
"only opportunity to make changes.</strong><br />"
|
|
||||||
"<br />"
|
|
||||||
"To accept your changes and continue, close this window.<br />"
|
|
||||||
"<br />"
|
|
||||||
"To remove a squadron from the game, uncheck the box in the title. New "
|
|
||||||
"squadrons cannot<br />"
|
|
||||||
"be added via the UI at this time. To add a custom squadron, see "
|
|
||||||
f'<a style="color:#ffffff" href="{doc_url}">the wiki</a>.'
|
|
||||||
)
|
|
||||||
|
|
||||||
doc_label.setOpenExternalLinks(True)
|
|
||||||
self.addWidget(doc_label)
|
|
||||||
for squadron in self.air_wing.iter_squadrons():
|
|
||||||
squadron_config = SquadronConfigurationBox(squadron)
|
squadron_config = SquadronConfigurationBox(squadron)
|
||||||
self.squadron_configs.append(squadron_config)
|
self.squadron_configs.append(squadron_config)
|
||||||
self.addWidget(squadron_config)
|
self.addWidget(squadron_config)
|
||||||
|
|
||||||
def apply(self) -> None:
|
def apply(self) -> list[Squadron]:
|
||||||
keep_squadrons = defaultdict(list)
|
keep_squadrons = []
|
||||||
for squadron_config in self.squadron_configs:
|
for squadron_config in self.squadron_configs:
|
||||||
if squadron_config.isChecked():
|
if squadron_config.isChecked():
|
||||||
squadron = squadron_config.apply()
|
keep_squadrons.append(squadron_config.apply())
|
||||||
keep_squadrons[squadron.aircraft].append(squadron)
|
return keep_squadrons
|
||||||
self.air_wing.squadrons = keep_squadrons
|
|
||||||
|
|
||||||
|
|
||||||
class AirWingConfigurationDialog(QDialog):
|
class AircraftSquadronsPage(QWidget):
|
||||||
"""Dialog window for air wing configuration."""
|
def __init__(self, squadrons: list[Squadron]) -> None:
|
||||||
|
super().__init__()
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
def __init__(self, game: Game, parent) -> None:
|
self.squadrons_config = SquadronConfigurationLayout(squadrons)
|
||||||
super().__init__(parent)
|
|
||||||
self.air_wing = game.blue.air_wing
|
|
||||||
|
|
||||||
self.setMinimumSize(500, 800)
|
|
||||||
self.setWindowTitle(f"Air Wing Configuration")
|
|
||||||
# TODO: self.setWindowIcon()
|
|
||||||
|
|
||||||
self.air_wing_config = AirWingConfigurationLayout(self.air_wing)
|
|
||||||
|
|
||||||
scrolling_layout = QVBoxLayout()
|
|
||||||
scrolling_widget = QWidget()
|
scrolling_widget = QWidget()
|
||||||
scrolling_widget.setLayout(self.air_wing_config)
|
scrolling_widget.setLayout(self.squadrons_config)
|
||||||
|
|
||||||
scrolling_area = QScrollArea()
|
scrolling_area = QScrollArea()
|
||||||
scrolling_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
scrolling_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
@ -212,9 +187,112 @@ class AirWingConfigurationDialog(QDialog):
|
|||||||
scrolling_area.setWidgetResizable(True)
|
scrolling_area.setWidgetResizable(True)
|
||||||
scrolling_area.setWidget(scrolling_widget)
|
scrolling_area.setWidget(scrolling_widget)
|
||||||
|
|
||||||
scrolling_layout.addWidget(scrolling_area)
|
layout.addWidget(scrolling_area)
|
||||||
self.setLayout(scrolling_layout)
|
|
||||||
|
def apply(self) -> list[Squadron]:
|
||||||
|
return self.squadrons_config.apply()
|
||||||
|
|
||||||
|
|
||||||
|
class AircraftSquadronsPanel(QStackedLayout):
|
||||||
|
def __init__(self, air_wing: AirWing) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.air_wing = air_wing
|
||||||
|
self.squadrons_pages: dict[AircraftType, AircraftSquadronsPage] = {}
|
||||||
|
for aircraft, squadrons in self.air_wing.squadrons.items():
|
||||||
|
page = AircraftSquadronsPage(squadrons)
|
||||||
|
self.addWidget(page)
|
||||||
|
self.squadrons_pages[aircraft] = page
|
||||||
|
|
||||||
|
def apply(self) -> None:
|
||||||
|
for aircraft, page in self.squadrons_pages.items():
|
||||||
|
self.air_wing.squadrons[aircraft] = page.apply()
|
||||||
|
|
||||||
|
|
||||||
|
class AircraftTypeList(QListView):
|
||||||
|
page_index_changed = Signal(int)
|
||||||
|
|
||||||
|
def __init__(self, air_wing: AirWing) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.setIconSize(QSize(91, 24))
|
||||||
|
self.setMinimumWidth(300)
|
||||||
|
|
||||||
|
model = QStandardItemModel(self)
|
||||||
|
self.setModel(model)
|
||||||
|
|
||||||
|
self.selectionModel().setCurrentIndex(
|
||||||
|
model.index(0, 0), QItemSelectionModel.Select
|
||||||
|
)
|
||||||
|
self.selectionModel().selectionChanged.connect(self.on_selection_changed)
|
||||||
|
for aircraft in air_wing.squadrons:
|
||||||
|
aircraft_item = QStandardItem(aircraft.name)
|
||||||
|
icon = self.icon_for(aircraft)
|
||||||
|
if icon is not None:
|
||||||
|
aircraft_item.setIcon(icon)
|
||||||
|
aircraft_item.setEditable(False)
|
||||||
|
aircraft_item.setSelectable(True)
|
||||||
|
model.appendRow(aircraft_item)
|
||||||
|
|
||||||
|
def on_selection_changed(
|
||||||
|
self, selected: QItemSelection, _deselected: QItemSelection
|
||||||
|
) -> None:
|
||||||
|
indexes = selected.indexes()
|
||||||
|
if len(indexes) > 1:
|
||||||
|
raise RuntimeError("Aircraft list should not allow multi-selection")
|
||||||
|
if not indexes:
|
||||||
|
return
|
||||||
|
self.page_index_changed.emit(indexes[0].row())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def icon_for(aircraft: AircraftType) -> Optional[QIcon]:
|
||||||
|
name = aircraft.dcs_id
|
||||||
|
if name in AIRCRAFT_ICONS:
|
||||||
|
return QIcon(AIRCRAFT_ICONS[name])
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class AirWingConfigurationDialog(QDialog):
|
||||||
|
"""Dialog window for air wing configuration."""
|
||||||
|
|
||||||
|
def __init__(self, game: Game, parent) -> None:
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setMinimumSize(500, 800)
|
||||||
|
self.setWindowTitle(f"Air Wing Configuration")
|
||||||
|
# TODO: self.setWindowIcon()
|
||||||
|
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
doc_url = (
|
||||||
|
"https://github.com/dcs-liberation/dcs_liberation/wiki/Squadrons-and-pilots"
|
||||||
|
)
|
||||||
|
doc_label = QLabel(
|
||||||
|
"Use this opportunity to customize the squadrons available to your "
|
||||||
|
"coalition. <strong>This is your only opportunity to make changes.</strong>"
|
||||||
|
"<br /><br />"
|
||||||
|
"To accept your changes and continue, close this window.<br />"
|
||||||
|
"<br />"
|
||||||
|
"To remove a squadron from the game, uncheck the box in the title. New "
|
||||||
|
"squadrons cannot be added via the UI at this time. To add a custom "
|
||||||
|
"squadron,<br />"
|
||||||
|
f'see <a style="color:#ffffff" href="{doc_url}">the wiki</a>.'
|
||||||
|
)
|
||||||
|
|
||||||
|
doc_label.setOpenExternalLinks(True)
|
||||||
|
layout.addWidget(doc_label)
|
||||||
|
|
||||||
|
columns = QHBoxLayout()
|
||||||
|
layout.addLayout(columns)
|
||||||
|
|
||||||
|
type_list = AircraftTypeList(game.blue.air_wing)
|
||||||
|
type_list.page_index_changed.connect(self.on_aircraft_changed)
|
||||||
|
columns.addWidget(type_list)
|
||||||
|
|
||||||
|
self.squadrons_panel = AircraftSquadronsPanel(game.blue.air_wing)
|
||||||
|
columns.addLayout(self.squadrons_panel)
|
||||||
|
|
||||||
def reject(self) -> None:
|
def reject(self) -> None:
|
||||||
self.air_wing_config.apply()
|
self.squadrons_panel.apply()
|
||||||
super().reject()
|
super().reject()
|
||||||
|
|
||||||
|
def on_aircraft_changed(self, index: QModelIndex) -> None:
|
||||||
|
self.squadrons_panel.setCurrentIndex(index)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user