diff --git a/changelog.md b/changelog.md index 734b0ef8..e205e389 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,7 @@ Saves from 7.x are not compatible with 8.0. * **[Engine]** Support for DCS 2.8.6.41066, including the new Sinai map. * **[UI]** Limited size of overfull airbase display and added scrollbar. +* **[UI]** Waypoint altitudes can be edited in Waypoints tab of Edit Flight window. * **[UI]** Moved air wing and transfer menus to the toolbar to improve UI fit on low resolution displays. * **[UI]** Added basic game over dialog. diff --git a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py index 880d9b36..91fd6ca4 100644 --- a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py +++ b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py @@ -1,14 +1,35 @@ -from PySide6.QtCore import QItemSelectionModel, QPoint +from PySide6.QtCore import QItemSelectionModel, QPoint, QModelIndex from PySide6.QtGui import QStandardItem, QStandardItemModel -from PySide6.QtWidgets import QHeaderView, QTableView +from PySide6.QtWidgets import ( + QHeaderView, + QTableView, + QStyledItemDelegate, + QDoubleSpinBox, + QWidget, + QStyleOptionViewItem, +) from game.ato.flight import Flight from game.ato.flightwaypoint import FlightWaypoint from game.ato.flightwaypointtype import FlightWaypointType from game.ato.package import Package +from game.utils import Distance from qt_ui.windows.mission.flight.waypoints.QFlightWaypointItem import QWaypointItem +HEADER_LABELS = ["Name", "Alt (ft)", "Alt Type", "TOT/DEPART"] + + +class AltitudeEditorDelegate(QStyledItemDelegate): + def createEditor( + self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex + ) -> QDoubleSpinBox: + editor = QDoubleSpinBox(parent) + editor.setMinimum(0) + editor.setMaximum(40000) + return editor + + class QFlightWaypointList(QTableView): def __init__(self, package: Package, flight: Flight): super().__init__() @@ -16,8 +37,9 @@ class QFlightWaypointList(QTableView): self.flight = flight self.model = QStandardItemModel(self) + self.model.itemChanged.connect(self.on_changed) self.setModel(self.model) - self.model.setHorizontalHeaderLabels(["Name", "Alt", "TOT/DEPART"]) + self.model.setHorizontalHeaderLabels(HEADER_LABELS) header = self.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.ResizeToContents) @@ -27,27 +49,36 @@ class QFlightWaypointList(QTableView): self.indexAt(QPoint(1, 1)), QItemSelectionModel.Select ) - def update_list(self): - # We need to keep just the row and rebuild the index later because the - # QModelIndex will not be valid after the model is cleared. - current_index = self.currentIndex().row() - self.model.clear() + self.altitude_editor_delegate = AltitudeEditorDelegate(self) + self.setItemDelegateForColumn(1, self.altitude_editor_delegate) - self.model.setHorizontalHeaderLabels(["Name", "Alt", "TOT/DEPART"]) + def update_list(self) -> None: + # ignore signals when updating list so on_changed does not fire + self.model.blockSignals(True) + try: + # We need to keep just the row and rebuild the index later because the + # QModelIndex will not be valid after the model is cleared. + current_index = self.currentIndex().row() + self.model.clear() - waypoints = self.flight.flight_plan.waypoints - for row, waypoint in enumerate(waypoints): - self.add_waypoint_row(row, self.flight, waypoint) - self.selectionModel().setCurrentIndex( - self.model.index(current_index, 0), QItemSelectionModel.Select - ) - self.resizeColumnsToContents() - total_column_width = self.verticalHeader().width() + self.lineWidth() - for i in range(0, self.model.columnCount()): - total_column_width += self.columnWidth(i) + self.lineWidth() - self.setFixedWidth(total_column_width) + self.model.setHorizontalHeaderLabels(HEADER_LABELS) - def add_waypoint_row( + waypoints = self.flight.flight_plan.waypoints + for row, waypoint in enumerate(waypoints): + self._add_waypoint_row(row, self.flight, waypoint) + self.selectionModel().setCurrentIndex( + self.model.index(current_index, 0), QItemSelectionModel.Select + ) + self.resizeColumnsToContents() + total_column_width = self.verticalHeader().width() + self.lineWidth() + for i in range(0, self.model.columnCount()): + total_column_width += self.columnWidth(i) + self.lineWidth() + self.setFixedWidth(total_column_width) + finally: + # stop ignoring signals + self.model.blockSignals(False) + + def _add_waypoint_row( self, row: int, flight: Flight, waypoint: FlightWaypoint ) -> None: self.model.insertRow(self.model.rowCount()) @@ -55,15 +86,25 @@ class QFlightWaypointList(QTableView): self.model.setItem(row, 0, QWaypointItem(waypoint, row)) altitude = int(waypoint.alt.feet) - altitude_type = "AGL" if waypoint.alt_type == "RADIO" else "MSL" - altitude_item = QStandardItem(f"{altitude} ft {altitude_type}") - altitude_item.setEditable(False) + altitude_item = QStandardItem(f"{altitude}") + altitude_item.setEditable(True) self.model.setItem(row, 1, altitude_item) + altitude_type = "AGL" if waypoint.alt_type == "RADIO" else "MSL" + altitude_type_item = QStandardItem(f"{altitude_type}") + altitude_type_item.setEditable(False) + self.model.setItem(row, 2, altitude_type_item) + tot = self.tot_text(flight, waypoint) tot_item = QStandardItem(tot) tot_item.setEditable(False) - self.model.setItem(row, 2, tot_item) + self.model.setItem(row, 3, tot_item) + + def on_changed(self) -> None: + for i in range(self.model.rowCount()): + altitude = self.model.item(i, 1).text() + altitude_feet = float(altitude) + self.flight.flight_plan.waypoints[i].alt = Distance.from_feet(altitude_feet) def tot_text(self, flight: Flight, waypoint: FlightWaypoint) -> str: if waypoint.waypoint_type == FlightWaypointType.TAKEOFF: