diff --git a/qt_ui/widgets/QConditionsWidget.py b/qt_ui/widgets/QConditionsWidget.py index 7ec2f9d5..80e27c9b 100644 --- a/qt_ui/widgets/QConditionsWidget.py +++ b/qt_ui/widgets/QConditionsWidget.py @@ -1,265 +1,270 @@ -from PySide2.QtCore import Qt -from PySide2.QtWidgets import QLabel, QHBoxLayout, QGroupBox, QVBoxLayout, QFrame, QGridLayout -from PySide2.QtGui import QPixmap - -from game.weather import Conditions, TimeOfDay, Weather -from game.utils import meter_to_nm, mps_to_knots -from dcs.weather import Weather as PydcsWeather - -from qt_ui.windows.weather.QWeatherInfoWindow import QWeatherInfoWindow -import qt_ui.uiconstants as CONST - -class QTimeTurnWidget(QGroupBox): - """ - UI Component to display current turn and time info - """ - - def __init__(self): - super(QTimeTurnWidget, self).__init__("Turn") - 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) - - 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.daytime_icon.setPixmap(self.icons[conditions.time_of_day]) - self.date_display.setText(conditions.start_time.strftime("%d %b %Y")) - self.time_display.setText( - conditions.start_time.strftime("%H:%M:%S Local")) - self.setTitle("Turn " + str(turn + 1)) - -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.updateForecast() - self.updateWinds() - - def updateWinds(self): - """Updates the UI with the current conditions wind info. - """ - windGlSpeed = mps_to_knots(self.conditions.weather.wind.at_0m.speed or 0) - windGlDir = self.conditions.weather.wind.at_0m.direction or 0 - self.windGLSpeedLabel.setText('{}kts'.format(windGlSpeed)) - self.windGLDirLabel.setText('{}º'.format(windGlDir)) - - windFL08Speed = mps_to_knots(self.conditions.weather.wind.at_2000m.speed or 0) - windFL08Dir = self.conditions.weather.wind.at_2000m.direction or 0 - self.windFL08SpeedLabel.setText('{}kts'.format(windFL08Speed)) - self.windFL08DirLabel.setText('{}º'.format(windFL08Dir)) - - windFL26Speed = mps_to_knots(self.conditions.weather.wind.at_8000m.speed or 0) - windFL26Dir = self.conditions.weather.wind.at_8000m.direction or 0 - self.windFL26SpeedLabel.setText('{}kts'.format(windFL26Speed)) - self.windFL26DirLabel.setText('{}º'.format(windFL26Dir)) - - def updateForecast(self): - """Updates the Forecast Text and icon with the current conditions wind info. - """ - icon = [] - cloudDensity = self.conditions.weather.clouds.density or 0 - precipitation = self.conditions.weather.clouds.precipitation or None - fog = self.conditions.weather.fog or None - is_night = self.conditions.time_of_day == TimeOfDay.Night - time = 'night' if is_night else 'day' - - if cloudDensity <= 0: - self.forecastClouds.setText('Sunny') - icon = [time, 'clear'] - - if cloudDensity > 0 and cloudDensity < 3: - self.forecastClouds.setText('Partly Cloudy') - icon = [time, 'partly-cloudy'] - - if cloudDensity >= 3 and cloudDensity < 5: - self.forecastClouds.setText('Mostly Cloudy') - icon = [time, 'partly-cloudy'] - - if cloudDensity >= 5: - self.forecastClouds.setText('Totally Cloudy') - icon = [time, 'partly-cloudy'] - - if precipitation == PydcsWeather.Preceptions.Rain: - self.forecastRain.setText('Rain') - icon = [time, 'rain'] - - elif precipitation == PydcsWeather.Preceptions.Thunderstorm: - self.forecastRain.setText('Thunderstorm') - icon = [time, 'thunderstorm'] - - else: - self.forecastRain.setText('No Rain') - - if not fog: - self.forecastFog.setText('No fog') - else: - visvibilityNm = round(meter_to_nm(fog.visibility), 1) - self.forecastFog.setText('Fog vis: {}nm'.format(visvibilityNm)) - icon = [time, ('cloudy' if cloudDensity > 1 else None), 'fog'] - - - icon_key = "Weather_{}".format('-'.join(filter(None.__ne__, icon))) - icon = CONST.ICONS.get(icon_key) or CONST.ICONS['Weather_night-partly-cloudy'] - self.weather_icon.setPixmap(icon) - - -class QConditionsWidget(QFrame): - """ - UI Component to display Turn Number, Day Time & Hour and weather combined. - """ - - def __init__(self): - super(QConditionsWidget, self).__init__() - self.setProperty('style', 'QConditionsWidget') - - self.layout = QGridLayout() - self.layout.setContentsMargins(0, 0, 0, 0) - self.layout.setHorizontalSpacing(0) - self.layout.setVerticalSpacing(0) - self.setLayout(self.layout) - - self.time_turn_widget = QTimeTurnWidget() - self.time_turn_widget.setStyleSheet('QGroupBox { margin-right: 0px; }') - self.layout.addWidget(self.time_turn_widget, 0, 0) - - self.weather_widget = QWeatherWidget() - self.weather_widget.setStyleSheet('QGroupBox { margin-top: 5px; margin-left: 0px; border-left: 0px; }') - self.weather_widget.hide() - self.layout.addWidget(self.weather_widget, 0, 1) - - 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.time_turn_widget.setCurrentTurn(turn, conditions) - self.weather_widget.setCurrentTurn(turn, conditions) - self.weather_widget.show() - +from PySide2.QtCore import Qt +from PySide2.QtWidgets import QLabel, QHBoxLayout, QGroupBox, QVBoxLayout, QFrame, QGridLayout +from PySide2.QtGui import QPixmap + +from game.weather import Conditions, TimeOfDay, Weather +from game.utils import meter_to_nm, mps_to_knots +from dcs.weather import Weather as PydcsWeather + +from qt_ui.windows.weather.QWeatherInfoWindow import QWeatherInfoWindow +import qt_ui.uiconstants as CONST + +class QTimeTurnWidget(QGroupBox): + """ + UI Component to display current turn and time info + """ + + def __init__(self): + super(QTimeTurnWidget, self).__init__("Turn") + 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) + + 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.daytime_icon.setPixmap(self.icons[conditions.time_of_day]) + self.date_display.setText(conditions.start_time.strftime("%d %b %Y")) + self.time_display.setText( + conditions.start_time.strftime("%H:%M:%S Local")) + self.setTitle("Turn " + str(turn + 1)) + +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.updateForecast() + self.updateWinds() + + def updateWinds(self): + """Updates the UI with the current conditions wind info. + """ + windGlSpeed = mps_to_knots(self.conditions.weather.wind.at_0m.speed or 0) + windGlDir = self.conditions.weather.wind.at_0m.direction or 0 + self.windGLSpeedLabel.setText('{}kts'.format(windGlSpeed)) + self.windGLDirLabel.setText('{}º'.format(windGlDir)) + + windFL08Speed = mps_to_knots(self.conditions.weather.wind.at_2000m.speed or 0) + windFL08Dir = self.conditions.weather.wind.at_2000m.direction or 0 + self.windFL08SpeedLabel.setText('{}kts'.format(windFL08Speed)) + self.windFL08DirLabel.setText('{}º'.format(windFL08Dir)) + + windFL26Speed = mps_to_knots(self.conditions.weather.wind.at_8000m.speed or 0) + windFL26Dir = self.conditions.weather.wind.at_8000m.direction or 0 + self.windFL26SpeedLabel.setText('{}kts'.format(windFL26Speed)) + self.windFL26DirLabel.setText('{}º'.format(windFL26Dir)) + + def updateForecast(self): + """Updates the Forecast Text and icon with the current conditions wind info. + """ + icon = [] + if self.conditions.weather.clouds is None: + cloudDensity = 0 + precipitation = None + else: + cloudDensity = self.conditions.weather.clouds.density + precipitation = self.conditions.weather.clouds.precipitation + + fog = self.conditions.weather.fog or None + is_night = self.conditions.time_of_day == TimeOfDay.Night + time = 'night' if is_night else 'day' + + if cloudDensity <= 0: + self.forecastClouds.setText('Sunny') + icon = [time, 'clear'] + + if cloudDensity > 0 and cloudDensity < 3: + self.forecastClouds.setText('Partly Cloudy') + icon = [time, 'partly-cloudy'] + + if cloudDensity >= 3 and cloudDensity < 5: + self.forecastClouds.setText('Mostly Cloudy') + icon = [time, 'partly-cloudy'] + + if cloudDensity >= 5: + self.forecastClouds.setText('Totally Cloudy') + icon = [time, 'partly-cloudy'] + + if precipitation == PydcsWeather.Preceptions.Rain: + self.forecastRain.setText('Rain') + icon = [time, 'rain'] + + elif precipitation == PydcsWeather.Preceptions.Thunderstorm: + self.forecastRain.setText('Thunderstorm') + icon = [time, 'thunderstorm'] + + else: + self.forecastRain.setText('No Rain') + + if not fog: + self.forecastFog.setText('No fog') + else: + visvibilityNm = round(meter_to_nm(fog.visibility), 1) + self.forecastFog.setText('Fog vis: {}nm'.format(visvibilityNm)) + icon = [time, ('cloudy' if cloudDensity > 1 else None), 'fog'] + + + icon_key = "Weather_{}".format('-'.join(filter(None.__ne__, icon))) + icon = CONST.ICONS.get(icon_key) or CONST.ICONS['Weather_night-partly-cloudy'] + self.weather_icon.setPixmap(icon) + + +class QConditionsWidget(QFrame): + """ + UI Component to display Turn Number, Day Time & Hour and weather combined. + """ + + def __init__(self): + super(QConditionsWidget, self).__init__() + self.setProperty('style', 'QConditionsWidget') + + self.layout = QGridLayout() + self.layout.setContentsMargins(0, 0, 0, 0) + self.layout.setHorizontalSpacing(0) + self.layout.setVerticalSpacing(0) + self.setLayout(self.layout) + + self.time_turn_widget = QTimeTurnWidget() + self.time_turn_widget.setStyleSheet('QGroupBox { margin-right: 0px; }') + self.layout.addWidget(self.time_turn_widget, 0, 0) + + self.weather_widget = QWeatherWidget() + self.weather_widget.setStyleSheet('QGroupBox { margin-top: 5px; margin-left: 0px; border-left: 0px; }') + self.weather_widget.hide() + self.layout.addWidget(self.weather_widget, 0, 1) + + 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.time_turn_widget.setCurrentTurn(turn, conditions) + self.weather_widget.setCurrentTurn(turn, conditions) + self.weather_widget.show() + diff --git a/qt_ui/windows/weather/QWeatherInfoWindow.py b/qt_ui/windows/weather/QWeatherInfoWindow.py index 4a3ed446..272b40ce 100644 --- a/qt_ui/windows/weather/QWeatherInfoWindow.py +++ b/qt_ui/windows/weather/QWeatherInfoWindow.py @@ -1,16 +1,16 @@ -from PySide2.QtWidgets import QDialog, QGridLayout, QLabel, QFrame, QSizePolicy - -from game.game import Game -from game.weather import Conditions, TimeOfDay, Weather - -import qt_ui.uiconstants as CONST - -class QWeatherInfoWindow(QDialog): - - def __init__(self, turn: int, conditions: Conditions): - super(QWeatherInfoWindow, self).__init__() - - self.setModal(True) - self.setWindowTitle("Weather Forecast Report") - self.setWindowIcon(CONST.ICONS["Money"]) +from PySide2.QtWidgets import QDialog, QGridLayout, QLabel, QFrame, QSizePolicy + +from game.game import Game +from game.weather import Conditions, TimeOfDay, Weather + +import qt_ui.uiconstants as CONST + +class QWeatherInfoWindow(QDialog): + + def __init__(self, turn: int, conditions: Conditions): + super(QWeatherInfoWindow, self).__init__() + + self.setModal(True) + self.setWindowTitle("Weather Forecast Report") + self.setWindowIcon(CONST.ICONS["Money"]) self.setMinimumSize(450, 200) \ No newline at end of file