Rework the speed controls for 1080p friendliness.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2396.
This commit is contained in:
Dan Albert 2023-02-19 11:59:45 -08:00
parent 088b69a6ef
commit 67dae80b76
2 changed files with 60 additions and 20 deletions

View File

@ -22,7 +22,7 @@ if TYPE_CHECKING:
class SimController(QObject): class SimController(QObject):
sim_update = Signal(GameUpdateEvents) sim_update = Signal(GameUpdateEvents)
sim_speed_reset = Signal(SimSpeedSetting) sim_speed_changed = Signal(SimSpeedSetting)
simulation_complete = Signal() simulation_complete = Signal()
def __init__(self, game: Optional[Game]) -> None: def __init__(self, game: Optional[Game]) -> None:
@ -55,8 +55,8 @@ class SimController(QObject):
return self.game_loop.elapsed_time return self.game_loop.elapsed_time
def set_game(self, game: Optional[Game]) -> None: def set_game(self, game: Optional[Game]) -> None:
self.sim_speed_changed.emit(SimSpeedSetting.PAUSED)
self.recreate_game_loop(game) self.recreate_game_loop(game)
self.sim_speed_reset.emit(SimSpeedSetting.PAUSED)
def recreate_game_loop(self, game: Optional[Game]) -> None: def recreate_game_loop(self, game: Optional[Game]) -> None:
if self.game_loop is not None: if self.game_loop is not None:
@ -76,6 +76,7 @@ class SimController(QObject):
if not self.started and simulation_speed is not SimSpeedSetting.PAUSED: if not self.started and simulation_speed is not SimSpeedSetting.PAUSED:
self.game_loop.start() self.game_loop.start()
self.started = True self.started = True
self.sim_speed_changed.emit(simulation_speed)
self.game_loop.set_simulation_speed(simulation_speed) self.game_loop.set_simulation_speed(simulation_speed)
@contextmanager @contextmanager
@ -106,4 +107,5 @@ class SimController(QObject):
def on_simulation_complete(self) -> None: def on_simulation_complete(self) -> None:
logging.debug("Simulation complete") logging.debug("Simulation complete")
self.sim_speed_changed.emit(SimSpeedSetting.PAUSED)
self.simulation_complete.emit() self.simulation_complete.emit()

View File

@ -2,34 +2,72 @@ from __future__ import annotations
from typing import Optional from typing import Optional
from PySide6.QtWidgets import QButtonGroup, QHBoxLayout, QPushButton, QWidget from PySide6.QtCore import QSize
from PySide6.QtWidgets import QHBoxLayout, QPushButton, QSpinBox, QWidget
from game.sim.simspeedsetting import SimSpeedSetting from game.sim.simspeedsetting import SimSpeedSetting
from qt_ui.simcontroller import SimController from qt_ui.simcontroller import SimController
class SimSpeedSpinner(QSpinBox):
def __init__(self, sim_controller: SimController, parent: QWidget | None) -> None:
super().__init__(parent)
self.sim_controller = sim_controller
# Disable text editing, which wouldn't work in the first place, but also
# obnoxiously selects the text on change (highlighting it) and leaves a flashing
# cursor in the middle of the element when clicked.
self.lineEdit().setEnabled(False)
# The value stored by the spinner is the index of the speed setting in the enum.
# SimSpeedSetting is ordered, so the minimum value is paused, and increasing the
# value will speed up the game by one speed).
self.setMinimum(0)
self.setMaximum(len(SimSpeedSetting) - 1)
self.setValue(0)
self.valueChanged.connect(self.on_change)
self.sim_controller.sim_speed_changed.connect(self.on_sim_speed_reset)
@staticmethod
def speed_for_value(value: int) -> SimSpeedSetting:
return list(SimSpeedSetting)[value]
def sizeHint(self) -> QSize:
# The default size hinting fails to deal with label width, and will truncate
# "Paused".
size = super().sizeHint()
size.setWidth(86)
return size
def textFromValue(self, value: int) -> str:
return self.speed_for_value(value).text
def valueFromText(self, text: str) -> int:
for idx, speed in enumerate(SimSpeedSetting):
if speed.text == text:
return idx
raise ValueError(f"Unknown SimSpeedSetting: {text}")
def on_change(self, value: int) -> None:
self.sim_controller.set_simulation_speed(self.speed_for_value(value))
def on_sim_speed_reset(self, speed_setting: SimSpeedSetting) -> None:
self.setValue(list(SimSpeedSetting).index(speed_setting))
class SimSpeedControls(QHBoxLayout): class SimSpeedControls(QHBoxLayout):
def __init__( def __init__(
self, sim_controller: SimController, parent: Optional[QWidget] = None self, sim_controller: SimController, parent: Optional[QWidget] = None
) -> None: ) -> None:
super().__init__(parent) super().__init__(parent)
self.sim_controller = sim_controller self.sim_controller = sim_controller
self.button_group = QButtonGroup(self)
self.buttons: dict[SimSpeedSetting, QPushButton] = {}
for speed_setting in SimSpeedSetting: self.pause_button = QPushButton(text="Pause")
button = QPushButton(speed_setting.text) self.pause_button.clicked.connect(
button.setCheckable(True) # TODO: CSS lambda: self.sim_controller.set_simulation_speed(SimSpeedSetting.PAUSED)
self.button_group.addButton(button, id=speed_setting.speed_factor) )
self.addWidget(button) self.addWidget(self.pause_button)
self.buttons[speed_setting] = button
self.button_group.idPressed.connect(self.speed_changed) self.speed_spinner = SimSpeedSpinner(sim_controller, parent)
self.sim_controller.sim_speed_reset.connect(self.on_sim_speed_reset) self.addWidget(self.speed_spinner)
def speed_changed(self, speed_factor: int) -> None:
setting = SimSpeedSetting.from_factor(speed_factor)
self.sim_controller.set_simulation_speed(setting)
def on_sim_speed_reset(self, speed_setting: SimSpeedSetting) -> None:
self.buttons[speed_setting].setChecked(True)