Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/accessiweather/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,7 @@ def _initialize_taskbar_updater(self) -> None:
format_string=getattr(settings, "taskbar_icon_text_format", "{temp} {condition}"),
temperature_unit=getattr(settings, "temperature_unit", "both"),
verbosity_level=getattr(settings, "verbosity_level", "standard"),
round_values=getattr(settings, "round_values", False),
)
logger.debug("Taskbar icon updater initialized")
except Exception as e:
Expand Down
21 changes: 11 additions & 10 deletions src/accessiweather/display/presentation/current_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,19 @@ def _build_basic_metrics(
if current.humidity is not None:
metrics.append(Metric("Humidity", f"{current.humidity:.0f}%"))

wind_value = format_wind(current, unit_pref)
wind_value = format_wind(current, unit_pref, precision=precision)
if wind_value:
metrics.append(Metric("Wind", wind_value))

dewpoint_value = format_dewpoint(current, unit_pref, precision)
if show_dewpoint and dewpoint_value:
metrics.append(Metric("Dewpoint", dewpoint_value))

pressure_value = format_pressure_value(current, unit_pref)
pressure_value = format_pressure_value(current, unit_pref, precision=precision)
if pressure_value:
metrics.append(Metric("Pressure", pressure_value))

visibility_value = format_visibility_value(current, unit_pref)
visibility_value = format_visibility_value(current, unit_pref, precision=precision)
if show_visibility and visibility_value:
metrics.append(Metric("Visibility", visibility_value))

Expand All @@ -93,13 +93,13 @@ def _build_basic_metrics(
if current.precipitation_in is not None and current.precipitation_in > 0:
if unit_pref == TemperatureUnit.CELSIUS:
precip_mm = current.precipitation_mm or current.precipitation_in * 25.4
metrics.append(Metric("Precipitation", f"{precip_mm:.1f} mm"))
metrics.append(Metric("Precipitation", f"{precip_mm:.{precision}f} mm"))
elif unit_pref == TemperatureUnit.FAHRENHEIT:
metrics.append(Metric("Precipitation", f"{current.precipitation_in:.2f} in"))
metrics.append(Metric("Precipitation", f"{current.precipitation_in:.{precision}f} in"))
else:
precip_mm = current.precipitation_mm or current.precipitation_in * 25.4
metrics.append(
Metric("Precipitation", f"{current.precipitation_in:.2f} in ({precip_mm:.1f} mm)")
Metric("Precipitation", f"{current.precipitation_in:.{precision}f} in ({precip_mm:.{precision}f} mm)")
)

return metrics
Expand Down Expand Up @@ -243,13 +243,13 @@ def _build_seasonal_metrics(
if current.snow_depth_in is not None and current.snow_depth_in > 0:
if unit_pref == TemperatureUnit.CELSIUS:
snow_depth_cm = current.snow_depth_cm or current.snow_depth_in * 2.54
metrics.append(Metric("Snow on ground", f"{snow_depth_cm:.1f} cm"))
metrics.append(Metric("Snow on ground", f"{snow_depth_cm:.{precision}f} cm"))
elif unit_pref == TemperatureUnit.FAHRENHEIT:
metrics.append(Metric("Snow on ground", f"{current.snow_depth_in:.1f} in"))
metrics.append(Metric("Snow on ground", f"{current.snow_depth_in:.{precision}f} in"))
else:
snow_depth_cm = current.snow_depth_cm or current.snow_depth_in * 2.54
metrics.append(
Metric("Snow on ground", f"{current.snow_depth_in:.1f} in ({snow_depth_cm:.1f} cm)")
Metric("Snow on ground", f"{current.snow_depth_in:.{precision}f} in ({snow_depth_cm:.{precision}f} cm)")
)

if current.wind_chill_f is not None:
Expand Down Expand Up @@ -428,7 +428,8 @@ def build_current_conditions(
"""Create a structured presentation for the current weather using helper functions."""
title = f"Current conditions for {location.name}"
description = current.condition or "Unknown"
precision = get_temperature_precision(unit_pref)
round_values = getattr(settings, "round_values", False) if settings else False
precision = 0 if round_values else get_temperature_precision(unit_pref)

# Extract settings preferences
show_dewpoint = getattr(settings, "show_dewpoint", True) if settings else True
Expand Down
14 changes: 8 additions & 6 deletions src/accessiweather/display/presentation/forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ def build_forecast(
) -> ForecastPresentation:
"""Create a structured forecast including optional hourly highlights."""
title = f"Forecast for {location.name}"
precision = get_temperature_precision(unit_pref)
round_values = getattr(settings, "round_values", False) if settings else False
precision = 0 if round_values else get_temperature_precision(unit_pref)

periods: list[ForecastPeriodPresentation] = []
fallback_lines = [f"Forecast for {location.name}:\n"]
Expand Down Expand Up @@ -161,7 +162,7 @@ def build_forecast(
else None
)
snowfall_val = (
f"{period.snowfall:.1f} in"
f"{period.snowfall:.{precision}f} in"
if include_snowfall and period.snowfall is not None and period.snowfall > 0
else None
)
Expand All @@ -177,7 +178,7 @@ def build_forecast(
)
gust_val = period.wind_gust if include_wind_gust and period.wind_gust else None
precip_amt = (
f"{period.precipitation_amount:.2f} in"
f"{period.precipitation_amount:.{precision}f} in"
if include_precipitation
and period.precipitation_amount is not None
and period.precipitation_amount > 0
Expand Down Expand Up @@ -261,7 +262,8 @@ def build_hourly_summary(
settings: AppSettings | None = None,
) -> list[HourlyPeriodPresentation]:
"""Generate the next six hours of simplified forecast data."""
precision = get_temperature_precision(unit_pref)
round_values = getattr(settings, "round_values", False) if settings else False
precision = 0 if round_values else get_temperature_precision(unit_pref)
summary: list[HourlyPeriodPresentation] = []

# Extract time display preferences and verbosity from settings
Expand Down Expand Up @@ -314,7 +316,7 @@ def build_hourly_summary(
else None
)
snowfall_val = (
f"{period.snowfall:.1f} in"
f"{period.snowfall:.{precision}f} in"
if include_snowfall and period.snowfall is not None and period.snowfall > 0
else None
)
Expand All @@ -334,7 +336,7 @@ def build_hourly_summary(
else None
)
precip_amt = (
f"{period.precipitation_amount:.2f} in"
f"{period.precipitation_amount:.{precision}f} in"
if include_precipitation
and period.precipitation_amount is not None
and period.precipitation_amount > 0
Expand Down
12 changes: 8 additions & 4 deletions src/accessiweather/display/presentation/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ def format_temperature_pair(
return format_temperature(temp_f, unit_pref, temperature_c=temp_c, precision=precision)


def format_wind(current: CurrentConditions, unit_pref: TemperatureUnit) -> str | None:
def format_wind(
current: CurrentConditions, unit_pref: TemperatureUnit, precision: int = 1
) -> str | None:
"""Describe wind direction and speed or return calm when wind is negligible."""
if (
current.wind_speed_mph is None
Expand All @@ -56,7 +58,7 @@ def format_wind(current: CurrentConditions, unit_pref: TemperatureUnit) -> str |
current.wind_speed_mph,
unit_pref,
wind_speed_kph=current.wind_speed_kph,
precision=1,
precision=precision,
)
if direction and speed:
return f"{direction} at {speed}"
Expand Down Expand Up @@ -97,6 +99,7 @@ def format_dewpoint(
def format_pressure_value(
current: CurrentConditions,
unit_pref: TemperatureUnit,
precision: int = 1,
) -> str | None:
"""Format station pressure in the preferred unit, if available."""
if current.pressure_in is None and current.pressure_mb is None:
Expand All @@ -105,12 +108,13 @@ def format_pressure_value(
pressure_mb = current.pressure_mb
if pressure_in is None and pressure_mb is not None:
pressure_in = pressure_mb / 33.8639
return format_pressure(pressure_in, unit_pref, pressure_mb=pressure_mb, precision=1)
return format_pressure(pressure_in, unit_pref, pressure_mb=pressure_mb, precision=precision)


def format_visibility_value(
current: CurrentConditions,
unit_pref: TemperatureUnit,
precision: int = 1,
) -> str | None:
"""Format horizontal visibility taking unit preference into account."""
if current.visibility_miles is None and current.visibility_km is None:
Expand All @@ -119,7 +123,7 @@ def format_visibility_value(
current.visibility_miles,
unit_pref,
visibility_km=current.visibility_km,
precision=1,
precision=precision,
)


Expand Down
5 changes: 5 additions & 0 deletions src/accessiweather/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
# API key settings (loaded lazily via keyring)
"visual_crossing_api_key",
# Display preferences
"round_values",
"show_detailed_forecast",
"enable_alerts",
"minimize_to_tray",
Expand Down Expand Up @@ -187,6 +188,8 @@ class AppSettings:
# Startup UX guidance flags
onboarding_wizard_shown: bool = False
portable_missing_api_keys_hint_shown: bool = False
# Display precision
round_values: bool = False

@staticmethod
def _as_bool(value, default: bool) -> bool:
Expand Down Expand Up @@ -448,6 +451,7 @@ def to_dict(self) -> dict:
"severe_weather_override": self.severe_weather_override,
"onboarding_wizard_shown": self.onboarding_wizard_shown,
"portable_missing_api_keys_hint_shown": self.portable_missing_api_keys_hint_shown,
"round_values": self.round_values,
}

@classmethod
Expand Down Expand Up @@ -542,6 +546,7 @@ def from_dict(cls, data: dict) -> AppSettings:
portable_missing_api_keys_hint_shown=cls._as_bool(
data.get("portable_missing_api_keys_hint_shown"), False
),
round_values=cls._as_bool(data.get("round_values"), False),
)

def to_alert_settings(self):
Expand Down
19 changes: 15 additions & 4 deletions src/accessiweather/taskbar_icon_updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def __init__(
format_string: str = DEFAULT_TOOLTIP_FORMAT,
temperature_unit: str = "both",
verbosity_level: str = "standard",
round_values: bool = False,
):
"""
Initialize the TaskbarIconUpdater.
Expand All @@ -63,13 +64,15 @@ def __init__(
format_string: The format string to use for the tooltip
temperature_unit: Temperature unit preference (fahrenheit, celsius, both)
verbosity_level: Information verbosity level (minimal, standard, detailed)
round_values: Whether to round numeric values to whole numbers

"""
self.text_enabled = text_enabled
self.dynamic_enabled = dynamic_enabled
self.format_string = format_string
self.temperature_unit = temperature_unit
self.verbosity_level = verbosity_level
self.round_values = round_values
self.parser = FormatStringParser()
self._last_format_error: str | None = None

Expand All @@ -80,6 +83,7 @@ def update_settings(
format_string: str | None = None,
temperature_unit: str | None = None,
verbosity_level: str | None = None,
round_values: bool | None = None,
) -> None:
"""
Update taskbar icon settings.
Expand All @@ -90,6 +94,7 @@ def update_settings(
format_string: The format string to use for the tooltip
temperature_unit: Temperature unit preference
verbosity_level: Information verbosity level (minimal, standard, detailed)
round_values: Whether to round numeric values to whole numbers

"""
if text_enabled is not None:
Expand All @@ -102,6 +107,8 @@ def update_settings(
self.temperature_unit = temperature_unit
if verbosity_level is not None:
self.verbosity_level = verbosity_level
if round_values is not None:
self.round_values = round_values

def format_tooltip(
self,
Expand Down Expand Up @@ -313,29 +320,32 @@ def _format_wind(self, current: Any) -> str:

def _format_wind_speed(self, current: Any) -> str:
"""Format wind speed using the selected unit preference."""
precision = 0 if self.round_values else 1
return format_wind_speed(
getattr(current, "wind_speed_mph", None),
unit=self._normalize_temperature_unit(),
wind_speed_kph=getattr(current, "wind_speed_kph", None),
precision=1,
precision=precision,
)

def _format_pressure(self, current: Any) -> str:
"""Format pressure using the selected unit preference."""
precision = 0 if self.round_values else 2
return format_pressure(
getattr(current, "pressure_in", None),
unit=self._normalize_temperature_unit(),
pressure_mb=getattr(current, "pressure_mb", None),
precision=2,
precision=precision,
)

def _format_visibility(self, current: Any) -> str:
"""Format visibility using the selected unit preference."""
precision = 0 if self.round_values else 1
return format_visibility(
getattr(current, "visibility_miles", None),
unit=self._normalize_temperature_unit(),
visibility_km=getattr(current, "visibility_km", None),
precision=1,
precision=precision,
)

def _format_precipitation(self, current: Any) -> str:
Expand All @@ -346,11 +356,12 @@ def _format_precipitation(self, current: Any) -> str:
if precip_in is None:
precip_in = getattr(current, "precipitation", None)

precision = 0 if self.round_values else 2
return format_precipitation(
precip_in,
unit=self._normalize_temperature_unit(),
precipitation_mm=getattr(current, "precipitation_mm", None),
precision=2,
precision=precision,
)

def _format_forecast_temperatures(
Expand Down
9 changes: 9 additions & 0 deletions src/accessiweather/ui/dialogs/settings_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ def _create_display_tab(self):
self._controls["show_pressure_trend"] = wx.CheckBox(panel, label="Show pressure trend")
sizer.Add(self._controls["show_pressure_trend"], 0, wx.LEFT, 10)

self._controls["round_values"] = wx.CheckBox(
panel, label="Show values as whole numbers (no decimals)"
)
sizer.Add(self._controls["round_values"], 0, wx.LEFT | wx.TOP, 10)

self._controls["detailed_forecast"] = wx.CheckBox(
panel, label="Show detailed forecast information"
)
Expand Down Expand Up @@ -1266,6 +1271,9 @@ def _load_settings(self):
self._controls["show_pressure_trend"].SetValue(
getattr(settings, "show_pressure_trend", True)
)
self._controls["round_values"].SetValue(
getattr(settings, "round_values", False)
)
self._controls["detailed_forecast"].SetValue(
getattr(settings, "show_detailed_forecast", True)
)
Expand Down Expand Up @@ -1520,6 +1528,7 @@ def _save_settings(self) -> bool:
"show_visibility": self._controls["show_visibility"].GetValue(),
"show_uv_index": self._controls["show_uv_index"].GetValue(),
"show_pressure_trend": self._controls["show_pressure_trend"].GetValue(),
"round_values": self._controls["round_values"].GetValue(),
"show_detailed_forecast": self._controls["detailed_forecast"].GetValue(),
"forecast_duration_days": forecast_duration_values[
self._controls["forecast_duration_days"].GetSelection()
Expand Down
Loading
Loading