diff --git a/changelog.md b/changelog.md index f9677e31..a3d1ea9b 100644 --- a/changelog.md +++ b/changelog.md @@ -19,6 +19,7 @@ * **[UI]** Zoom level retained when switching campaigns * **[UX]** Allow changing squadrons in flight's edit dialog * **[Cheats]** Sink/Resurrect carriers instead of showing an error during cheat-capture (use AWCD-cheat to add squadrons upon resurrection) +* **[UI/UX]** Allow changing conditions such as Time, Date & Weather ## Fixes * **[UI/UX]** A-10A flights can be edited again diff --git a/qt_ui/widgets/QConditionsDialog.py b/qt_ui/widgets/QConditionsDialog.py new file mode 100644 index 00000000..959574a1 --- /dev/null +++ b/qt_ui/widgets/QConditionsDialog.py @@ -0,0 +1,85 @@ +from copy import deepcopy +from datetime import datetime, timedelta + +from PySide6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QPushButton + +from game.sim import GameUpdateEvents +from game.weather.clouds import Clouds +from qt_ui.widgets.conditions.QTimeAdjustmentWidget import QTimeAdjustmentWidget +from qt_ui.widgets.conditions.QTimeTurnWidget import QTimeTurnWidget +from qt_ui.widgets.conditions.QWeatherAdjustmentWidget import QWeatherAdjustmentWidget +from qt_ui.widgets.conditions.QWeatherWidget import QWeatherWidget + + +class QConditionsDialog(QDialog): + def __init__(self, time_turn: QTimeTurnWidget, weather: QWeatherWidget): + super().__init__() + self.time_turn = time_turn + self.weather = weather + self.init_ui() + + def init_ui(self): + self.setWindowTitle("Time & Weather Conditions") + self.setMinimumSize(360, 380) + + vbox = QVBoxLayout() + + self.time_adjuster = QTimeAdjustmentWidget(self.time_turn) + vbox.addWidget(self.time_adjuster, 1) + self.weather_adjuster = QWeatherAdjustmentWidget(self.weather) + vbox.addWidget(self.weather_adjuster, 8) + + hbox = QHBoxLayout() + reject_btn = QPushButton("REJECT") + reject_btn.setProperty("style", "btn-danger") + reject_btn.clicked.connect(self.close) + hbox.addWidget(reject_btn) + accept_btn = QPushButton("ACCEPT") + accept_btn.setProperty("style", "btn-success") + accept_btn.clicked.connect(self.apply_conditions) + hbox.addWidget(accept_btn) + vbox.addLayout(hbox, 1) + + self.setLayout(vbox) + + def apply_conditions(self) -> None: + qdt: datetime = self.time_adjuster.datetime_edit.dateTime().toPython() + + sim = self.time_turn.sim_controller + current_time = sim.current_time_in_sim_if_game_loaded + if current_time: + current_time = deepcopy(current_time) + sim.game_loop.sim.time = qdt + + game = sim.game_loop.game + game.date = qdt.date() - timedelta(days=game.turn // 4) + game.conditions.start_time = qdt + self.time_turn.set_current_turn(game.turn, game.conditions) + + # TODO: create new weather object + + new_weather_type = self.weather_adjuster.type_selector.currentData() + new_weather = new_weather_type( + seasonal_conditions=game.theater.seasonal_conditions, + day=qdt.date(), + time_of_day=game.current_turn_time_of_day, + ) + + # self.weather.conditions.weather = WeatherType() + preset = self.weather_adjuster.preset_selector.currentData() + new_weather.clouds = Clouds( + base=self.weather_adjuster.cloud_base.base.value(), + density=self.weather_adjuster.cloud_density.density.value(), + thickness=self.weather_adjuster.cloud_thickness.thickness.value(), + precipitation=self.weather_adjuster.precipitation.selector.currentData(), + preset=preset, + ) + + self.weather.conditions.weather = new_weather + + self.weather.update_forecast() + if game.turn > 0 and current_time != qdt: + events = GameUpdateEvents() + game.initialize_turn(events, for_blue=True, for_red=True) + sim.sim_update.emit(events) + self.accept() diff --git a/qt_ui/widgets/QConditionsWidget.py b/qt_ui/widgets/QConditionsWidget.py index 37c26d65..69762377 100644 --- a/qt_ui/widgets/QConditionsWidget.py +++ b/qt_ui/widgets/QConditionsWidget.py @@ -1,282 +1,15 @@ -from datetime import datetime - -from PySide6.QtGui import QPixmap +from PySide6 import QtCore, QtGui +from PySide6.QtGui import QCursor from PySide6.QtWidgets import ( QFrame, QGridLayout, - QGroupBox, - QHBoxLayout, - QLabel, - QVBoxLayout, ) -from dcs.weather import CloudPreset, Weather as PydcsWeather -import qt_ui.uiconstants as CONST -from game.sim.gameupdateevents import GameUpdateEvents -from game.timeofday import TimeOfDay -from game.utils import mps from game.weather.conditions import Conditions from qt_ui.simcontroller import SimController - - -class QTimeTurnWidget(QGroupBox): - """ - UI Component to display current turn and time info - """ - - 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" - ) - - self.icons = { - TimeOfDay.Dawn: CONST.ICONS["Dawn"], - TimeOfDay.Day: CONST.ICONS["Day"], - TimeOfDay.Dusk: CONST.ICONS["Dusk"], - TimeOfDay.Night: CONST.ICONS["Night"], - } - - # self.setProperty('style', 'conditions__widget--turn') - self.layout = QHBoxLayout() - self.setLayout(self.layout) - - self.daytime_icon = QLabel() - self.daytime_icon.setPixmap(self.icons[TimeOfDay.Dawn]) - self.layout.addWidget(self.daytime_icon) - - self.time_column = QVBoxLayout() - self.layout.addLayout(self.time_column) - - self.date_display = QLabel() - self.time_column.addWidget(self.date_display) - - self.time_display = QLabel() - self.time_column.addWidget(self.time_display) - - sim_controller.sim_update.connect(self.on_sim_update) - - def on_sim_update(self, _events: GameUpdateEvents) -> None: - time = self.sim_controller.current_time_in_sim_if_game_loaded - 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.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): - """ - UI Component to display current weather forecast - """ - - turn = None - conditions = None - - def __init__(self): - super(QWeatherWidget, self).__init__("") - self.setProperty("style", "QWeatherWidget") - - self.icons = { - TimeOfDay.Dawn: CONST.ICONS["Dawn"], - TimeOfDay.Day: CONST.ICONS["Day"], - TimeOfDay.Dusk: CONST.ICONS["Dusk"], - TimeOfDay.Night: CONST.ICONS["Night"], - } - - self.layout = QHBoxLayout() - self.setLayout(self.layout) - - self.makeWeatherIcon() - self.makeCloudRainFogWidget() - self.makeWindsWidget() - - def makeWeatherIcon(self): - """Makes the Weather Icon Widget""" - self.weather_icon = QLabel() - self.weather_icon.setPixmap(self.icons[TimeOfDay.Dawn]) - self.layout.addWidget(self.weather_icon) - - def makeCloudRainFogWidget(self): - """Makes the Cloud, Rain, Fog Widget""" - self.textLayout = QVBoxLayout() - self.layout.addLayout(self.textLayout) - - self.forecastClouds = self.makeLabel() - self.textLayout.addWidget(self.forecastClouds) - - self.forecastRain = self.makeLabel() - self.textLayout.addWidget(self.forecastRain) - - self.forecastFog = self.makeLabel() - self.textLayout.addWidget(self.forecastFog) - - def makeWindsWidget(self): - """Factory for the winds widget.""" - windsLayout = QGridLayout() - self.layout.addLayout(windsLayout) - - windsLayout.addWidget(self.makeIcon(CONST.ICONS["Weather_winds"]), 0, 0, 3, 1) - - windsLayout.addWidget(self.makeLabel("At GL"), 0, 1) - windsLayout.addWidget(self.makeLabel("At FL08"), 1, 1) - windsLayout.addWidget(self.makeLabel("At FL26"), 2, 1) - - self.windGLSpeedLabel = self.makeLabel("0kts") - self.windGLDirLabel = self.makeLabel("0º") - windsLayout.addWidget(self.windGLSpeedLabel, 0, 2) - windsLayout.addWidget(self.windGLDirLabel, 0, 3) - - self.windFL08SpeedLabel = self.makeLabel("0kts") - self.windFL08DirLabel = self.makeLabel("0º") - windsLayout.addWidget(self.windFL08SpeedLabel, 1, 2) - windsLayout.addWidget(self.windFL08DirLabel, 1, 3) - - self.windFL26SpeedLabel = self.makeLabel("0kts") - self.windFL26DirLabel = self.makeLabel("0º") - windsLayout.addWidget(self.windFL26SpeedLabel, 2, 2) - windsLayout.addWidget(self.windFL26DirLabel, 2, 3) - - def makeLabel(self, text: str = "") -> QLabel: - """Shorthand to generate a QLabel with widget standard style - - :arg pixmap QPixmap for the icon. - """ - label = QLabel(text) - label.setProperty("style", "text-sm") - - return label - - def makeIcon(self, pixmap: QPixmap) -> QLabel: - """Shorthand to generate a QIcon with pixmap. - - :arg pixmap QPixmap for the icon. - """ - icon = QLabel() - icon.setPixmap(pixmap) - - return icon - - def setCurrentTurn(self, turn: int, conditions: Conditions) -> None: - """Sets the turn information display. - - :arg turn Current turn number. - :arg conditions Current time and weather conditions. - """ - self.turn = turn - self.conditions = conditions - - self.update_forecast() - self.updateWinds() - - def updateWinds(self): - """Updates the UI with the current conditions wind info.""" - windGlSpeed = mps(self.conditions.weather.wind.at_0m.speed or 0) - windGlDir = str(self.conditions.weather.wind.at_0m.direction or 0).rjust(3, "0") - self.windGLSpeedLabel.setText(f"{int(windGlSpeed.knots)}kts") - self.windGLDirLabel.setText(f"{windGlDir}º") - - windFL08Speed = mps(self.conditions.weather.wind.at_2000m.speed or 0) - windFL08Dir = str(self.conditions.weather.wind.at_2000m.direction or 0).rjust( - 3, "0" - ) - self.windFL08SpeedLabel.setText(f"{int(windFL08Speed.knots)}kts") - self.windFL08DirLabel.setText(f"{windFL08Dir}º") - - windFL26Speed = mps(self.conditions.weather.wind.at_8000m.speed or 0) - windFL26Dir = str(self.conditions.weather.wind.at_8000m.direction or 0).rjust( - 3, "0" - ) - self.windFL26SpeedLabel.setText(f"{int(windFL26Speed.knots)}kts") - self.windFL26DirLabel.setText(f"{windFL26Dir}º") - - def update_forecast_from_preset(self, preset: CloudPreset) -> None: - self.forecastFog.setText("No fog") - if "Rain" in preset.name: - self.forecastRain.setText("Rain") - self.update_forecast_icons("rain") - else: - self.forecastRain.setText("No rain") - self.update_forecast_icons("partly-cloudy") - - # We get a description like the following for the cloud preset. - # - # 09 ##Two Layer Broken/Scattered \nMETAR:BKN 7.5/10 SCT 20/22 FEW41 - # - # The second line is probably interesting but doesn't fit into the widget - # currently, so for now just extract the first line. - self.forecastClouds.setText(preset.description.splitlines()[0].split("##")[1]) - - def update_forecast(self): - """Updates the Forecast Text and icon with the current conditions wind info.""" - if ( - self.conditions.weather.clouds - and self.conditions.weather.clouds.preset is not None - ): - self.update_forecast_from_preset(self.conditions.weather.clouds.preset) - return - - if self.conditions.weather.clouds is None: - cloud_density = 0 - precipitation = None - else: - cloud_density = self.conditions.weather.clouds.density - precipitation = self.conditions.weather.clouds.precipitation - - if not cloud_density: - self.forecastClouds.setText("Clear") - weather_type = "clear" - elif cloud_density < 3: - self.forecastClouds.setText("Partly Cloudy") - weather_type = "partly-cloudy" - elif cloud_density < 5: - self.forecastClouds.setText("Mostly Cloudy") - weather_type = "partly-cloudy" - else: - self.forecastClouds.setText("Totally Cloudy") - weather_type = "partly-cloudy" - - if precipitation == PydcsWeather.Preceptions.Rain: - self.forecastRain.setText("Rain") - weather_type = "rain" - elif precipitation == PydcsWeather.Preceptions.Thunderstorm: - self.forecastRain.setText("Thunderstorm") - weather_type = "thunderstorm" - else: - self.forecastRain.setText("No rain") - - if not self.conditions.weather.fog is not None: - self.forecastFog.setText("No fog") - else: - visibility = round(self.conditions.weather.fog.visibility.nautical_miles, 1) - self.forecastFog.setText(f"Fog vis: {visibility}nm") - if cloud_density > 1: - weather_type = "cloudy-fog" - else: - weather_type = "fog" - - self.update_forecast_icons(weather_type) - - def update_forecast_icons(self, weather_type: str) -> None: - time = "night" if self.conditions.time_of_day == TimeOfDay.Night else "day" - icon_key = f"Weather_{time}-{weather_type}" - icon = CONST.ICONS.get(icon_key) or CONST.ICONS["Weather_night-partly-cloudy"] - self.weather_icon.setPixmap(icon) +from qt_ui.widgets.QConditionsDialog import QConditionsDialog +from qt_ui.widgets.conditions.QTimeTurnWidget import QTimeTurnWidget +from qt_ui.widgets.conditions.QWeatherWidget import QWeatherWidget class QConditionsWidget(QFrame): @@ -287,6 +20,7 @@ class QConditionsWidget(QFrame): def __init__(self, sim_controller: SimController) -> None: super(QConditionsWidget, self).__init__() self.setProperty("style", "QConditionsWidget") + self.setCursor(QCursor(QtCore.Qt.CursorShape.PointingHandCursor)) self.layout = QGridLayout() self.layout.setContentsMargins(0, 0, 0, 0) @@ -305,6 +39,9 @@ class QConditionsWidget(QFrame): self.weather_widget.hide() self.layout.addWidget(self.weather_widget, 0, 1) + def mouseDoubleClickEvent(self, event: QtGui.QMouseEvent) -> None: + QConditionsDialog(self.time_turn_widget, self.weather_widget).exec() + def setCurrentTurn(self, turn: int, conditions: Conditions) -> None: """Sets the turn information display. diff --git a/qt_ui/widgets/conditions/DcsCloudBaseSelector.py b/qt_ui/widgets/conditions/DcsCloudBaseSelector.py new file mode 100644 index 00000000..3c734afa --- /dev/null +++ b/qt_ui/widgets/conditions/DcsCloudBaseSelector.py @@ -0,0 +1,89 @@ +from typing import Optional + +from PySide6.QtCore import Qt +from PySide6.QtWidgets import QHBoxLayout, QLabel, QSlider, QSpinBox, QComboBox +from dcs.weather import CloudPreset + + +class DcsCloudBaseSelector(QHBoxLayout): + M2FT_FACTOR = 3.2808399 + + def __init__(self, preset: Optional[CloudPreset]) -> None: + super().__init__() + self.preset = preset + self.unit_changing = False + + self.label = QLabel("Cloud Base: ") + self.addWidget(self.label) + + self.base = QSlider(Qt.Orientation.Horizontal) + self.base.setValue(round(self.max_base - (self.max_base - self.min_base) / 2)) + self.base.valueChanged.connect(self.on_slider_change) + self.addWidget(self.base, 1) + + self.base_spinner = QSpinBox() + self.base_spinner.setValue(self.base.value()) + self.base_spinner.setFixedWidth(75) + self.base_spinner.setSingleStep(100) + self.base_spinner.valueChanged.connect(self.update_slider) + self.addWidget(self.base_spinner, 1) + + self.unit = QComboBox() + self.unit.insertItems(0, ["m", "ft"]) + self.unit.currentIndexChanged.connect(self.on_unit_change) + self.unit.setCurrentIndex(1) + self.addWidget(self.unit) + + self.update_bounds() + + @property + def min_base(self) -> int: + return self.preset.min_base if self.preset else 300 + + @property + def max_base(self) -> int: + return self.preset.max_base if self.preset else 5000 + + def update_bounds(self) -> None: + self.base.setRange(self.min_base, self.max_base) + index = self.unit.currentIndex() + if index == 0: + self.base_spinner.setRange(self.min_base, self.max_base) + elif index == 1: + self.base_spinner.setRange( + self.m2ft(self.min_base), self.m2ft(self.max_base) + ) + + def on_slider_change(self, value: int) -> None: + if self.unit.currentIndex() == 0: + self.base_spinner.setValue(value) + elif self.unit.currentIndex() == 1 and not self.unit_changing: + self.base_spinner.setValue(self.m2ft(value)) + + def update_slider(self, value: int) -> None: + if self.unit_changing: + return + if self.unit.currentIndex() == 0: + self.base.setValue(value) + elif self.unit.currentIndex() == 1: + self.unit_changing = True + self.base.setValue(self.ft2m(value)) + self.unit_changing = False + + def on_unit_change(self, index: int) -> None: + self.unit_changing = True + if index == 0: + self.base_spinner.setRange(self.min_base, self.max_base) + self.base_spinner.setValue(self.base.value()) + elif index == 1: + self.base_spinner.setRange( + self.m2ft(self.min_base), self.m2ft(self.max_base) + ) + self.base_spinner.setValue(self.m2ft(self.base.value())) + self.unit_changing = False + + def m2ft(self, value: int) -> int: + return round(value * self.M2FT_FACTOR) + + def ft2m(self, value: int) -> int: + return round(value / self.M2FT_FACTOR) diff --git a/qt_ui/widgets/conditions/DcsCloudDensitySelector.py b/qt_ui/widgets/conditions/DcsCloudDensitySelector.py new file mode 100644 index 00000000..a86cf848 --- /dev/null +++ b/qt_ui/widgets/conditions/DcsCloudDensitySelector.py @@ -0,0 +1,42 @@ +from typing import Optional + +from PySide6.QtCore import Qt +from PySide6.QtWidgets import QHBoxLayout, QLabel, QSlider, QSpinBox +from dcs.weather import CloudPreset + +from game.weather.clouds import Clouds + + +class DcsCloudDensitySelector(QHBoxLayout): + def __init__(self, clouds: Clouds) -> None: + super().__init__() + self.unit_changing = False + + self.label = QLabel("Density : ") + self.addWidget(self.label) + + self.density = QSlider(Qt.Orientation.Horizontal) + self.density.setRange(0, 10) + self.density.setValue(clouds.density) + self.density.valueChanged.connect(self.on_slider_change) + self.addWidget(self.density, 1) + + self.density_spinner = QSpinBox() + self.density_spinner.setValue(self.density.value()) + self.density_spinner.setFixedWidth(75) + self.density_spinner.valueChanged.connect(self.update_slider) + self.addWidget(self.density_spinner, 1) + + def on_slider_change(self, value: int) -> None: + self.density_spinner.setValue(value) + + def update_slider(self, value: int) -> None: + self.density.setValue(value) + + def update_ui(self, preset: Optional[CloudPreset]) -> None: + self.label.setVisible(preset is None) + self.density.setVisible(preset is None) + self.density_spinner.setVisible(preset is None) + + if preset: + self.density.setValue(0) diff --git a/qt_ui/widgets/conditions/DcsCloudThicknessSelector.py b/qt_ui/widgets/conditions/DcsCloudThicknessSelector.py new file mode 100644 index 00000000..2838f856 --- /dev/null +++ b/qt_ui/widgets/conditions/DcsCloudThicknessSelector.py @@ -0,0 +1,87 @@ +from typing import Optional + +from PySide6.QtCore import Qt +from PySide6.QtWidgets import QHBoxLayout, QLabel, QSlider, QSpinBox, QComboBox +from dcs.weather import CloudPreset + +from game.weather.clouds import Clouds + + +class DcsCloudThicknessSelector(QHBoxLayout): + M2FT_FACTOR = 3.2808399 + + def __init__(self, clouds: Clouds) -> None: + super().__init__() + self.unit_changing = False + + self.label = QLabel("Thickness : ") + self.addWidget(self.label) + + self.thickness = QSlider(Qt.Orientation.Horizontal) + self.thickness.setRange(200, 2000) + self.thickness.setValue(clouds.thickness) + self.thickness.valueChanged.connect(self.on_slider_change) + self.addWidget(self.thickness, 1) + + self.thickness_spinner = QSpinBox() + self.thickness_spinner.setValue(self.thickness.value()) + self.thickness_spinner.setFixedWidth(75) + self.thickness_spinner.setSingleStep(100) + self.thickness_spinner.valueChanged.connect(self.update_slider) + self.addWidget(self.thickness_spinner, 1) + + self.unit = QComboBox() + self.unit.insertItems(0, ["m", "ft"]) + self.unit.currentIndexChanged.connect(self.on_unit_change) + self.unit.setCurrentIndex(1) + self.addWidget(self.unit) + + def update_ui(self, preset: Optional[CloudPreset]) -> None: + self.label.setVisible(preset is None) + self.thickness.setVisible(preset is None) + self.thickness_spinner.setVisible(preset is None) + self.unit.setVisible(preset is None) + + if preset: + self.thickness.setValue(0) + + def on_slider_change(self, value: int) -> None: + if self.unit.currentIndex() == 0: + self.thickness_spinner.setValue(value) + elif self.unit.currentIndex() == 1 and not self.unit_changing: + self.thickness_spinner.setValue(self.m2ft(value)) + + def update_slider(self, value: int) -> None: + if self.unit_changing: + return + if self.unit.currentIndex() == 0: + self.thickness.setValue(value) + elif self.unit.currentIndex() == 1: + self.unit_changing = True + self.thickness.setValue(self.ft2m(value)) + self.unit_changing = False + + def on_unit_change(self, index: int) -> None: + self.unit_changing = True + mini = ( + self.thickness.minimum() + if index == 0 + else self.m2ft(self.thickness.minimum()) + ) + maxi = ( + self.thickness.maximum() + if index == 0 + else self.m2ft(self.thickness.maximum()) + ) + value = ( + self.thickness.value() if index == 0 else self.m2ft(self.thickness.value()) + ) + self.thickness_spinner.setRange(mini, maxi) + self.thickness_spinner.setValue(value) + self.unit_changing = False + + def m2ft(self, value: int) -> int: + return round(value * self.M2FT_FACTOR) + + def ft2m(self, value: int) -> int: + return round(value / self.M2FT_FACTOR) diff --git a/qt_ui/widgets/conditions/DcsPrecipitationSelector.py b/qt_ui/widgets/conditions/DcsPrecipitationSelector.py new file mode 100644 index 00000000..f8b93d8e --- /dev/null +++ b/qt_ui/widgets/conditions/DcsPrecipitationSelector.py @@ -0,0 +1,28 @@ +from typing import Optional + +from PySide6.QtWidgets import QHBoxLayout, QLabel, QComboBox +from dcs.weather import Weather as PydcsWeather, CloudPreset + +from game.weather.clouds import Clouds + + +class DcsPrecipitationSelector(QHBoxLayout): + def __init__(self, clouds: Clouds) -> None: + super().__init__() + self.unit_changing = False + + self.label = QLabel("Precipitation : ") + self.addWidget(self.label) + + self.selector = QComboBox() + for p in PydcsWeather.Preceptions: + self.selector.addItem(p.name.replace("_", ""), p) + + self.selector.setCurrentText(clouds.precipitation.name.replace("_", "")) + self.addWidget(self.selector, 1) + + def update_ui(self, preset: Optional[CloudPreset]) -> None: + self.selector.setEnabled(preset is None) + + if preset: + self.selector.setCurrentText("None") diff --git a/qt_ui/widgets/conditions/QTimeAdjustmentWidget.py b/qt_ui/widgets/conditions/QTimeAdjustmentWidget.py new file mode 100644 index 00000000..8c116d0e --- /dev/null +++ b/qt_ui/widgets/conditions/QTimeAdjustmentWidget.py @@ -0,0 +1,38 @@ +from typing import Optional + +from PySide6.QtCore import QDateTime +from PySide6.QtWidgets import QVBoxLayout, QWidget, QLabel, QHBoxLayout, QDateTimeEdit + +from qt_ui.widgets.conditions.QTimeTurnWidget import QTimeTurnWidget + + +class QTimeAdjustmentWidget(QWidget): + def __init__( + self, time_turn: QTimeTurnWidget, parent: Optional[QWidget] = None + ) -> None: + super().__init__(parent) + self.current_datetime = time_turn.sim_controller.current_time_in_sim + self.init_ui() + + def init_ui(self) -> None: + vbox = QVBoxLayout() + + vbox.addWidget(QLabel("