mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-21 16:14:28 +08:00
0.2.5
课表组件、天气组件全面升级。
This commit is contained in:
@@ -39,6 +39,7 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
string Tint,
|
||||
string PrimaryText,
|
||||
string SecondaryText,
|
||||
string TertiaryText,
|
||||
string ParticleColor);
|
||||
|
||||
private readonly record struct WeatherMotionProfile(
|
||||
@@ -81,20 +82,6 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
Symbol Icon,
|
||||
string TemperatureText);
|
||||
|
||||
private static readonly IReadOnlyDictionary<WeatherVisualKind, string> WeatherBackgroundAssets =
|
||||
new Dictionary<WeatherVisualKind, string>
|
||||
{
|
||||
[WeatherVisualKind.ClearDay] = "avares://LanMontainDesktop/Assets/Weather/clear_day.jpg",
|
||||
[WeatherVisualKind.ClearNight] = "avares://LanMontainDesktop/Assets/Weather/clear_night.jpg",
|
||||
[WeatherVisualKind.CloudyDay] = "avares://LanMontainDesktop/Assets/Weather/cloudy_day.jpg",
|
||||
[WeatherVisualKind.CloudyNight] = "avares://LanMontainDesktop/Assets/Weather/cloudy_night.jpg",
|
||||
[WeatherVisualKind.RainLight] = "avares://LanMontainDesktop/Assets/Weather/rain_light.jpg",
|
||||
[WeatherVisualKind.RainHeavy] = "avares://LanMontainDesktop/Assets/Weather/rain_heavy.jpg",
|
||||
[WeatherVisualKind.Storm] = "avares://LanMontainDesktop/Assets/Weather/storm_dark.jpg",
|
||||
[WeatherVisualKind.Snow] = "avares://LanMontainDesktop/Assets/Weather/snow_soft.jpg",
|
||||
[WeatherVisualKind.Fog] = "avares://LanMontainDesktop/Assets/Weather/fog_haze.jpg"
|
||||
};
|
||||
|
||||
private static readonly IWeatherInfoService DefaultWeatherInfoService = new XiaomiWeatherService();
|
||||
|
||||
private readonly DispatcherTimer _refreshTimer = new()
|
||||
@@ -110,6 +97,7 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
private readonly AppSettingsService _settingsService = new();
|
||||
private readonly LocalizationService _localizationService = new();
|
||||
private readonly Dictionary<WeatherVisualKind, IBrush> _backgroundBrushCache = new();
|
||||
private readonly Dictionary<HyperOS3WeatherVisualKind, IBrush> _particleBrushCache = new();
|
||||
private readonly List<Border> _particleVisuals = new();
|
||||
private readonly List<ParticleState> _particleStates = new();
|
||||
private readonly Random _particleRandom = new();
|
||||
@@ -223,10 +211,11 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
public void ApplyCellSize(double cellSize)
|
||||
{
|
||||
_currentCellSize = Math.Max(1, cellSize);
|
||||
var metrics = HyperOS3WeatherTheme.ResolveMetrics(HyperOS3WeatherWidgetKind.Hourly4x2);
|
||||
var scale = ResolveScale();
|
||||
var hostWidth = Bounds.Width > 1 ? Bounds.Width : Math.Max(140, _currentCellSize * 4);
|
||||
var hostHeight = Bounds.Height > 1 ? Bounds.Height : Math.Max(78, _currentCellSize * 2);
|
||||
var cornerRadius = Math.Clamp(_currentCellSize * 0.45, 24, 44);
|
||||
var cornerRadius = Math.Clamp(_currentCellSize * metrics.CornerRadiusScale, 24, 44);
|
||||
|
||||
RootBorder.CornerRadius = new CornerRadius(cornerRadius);
|
||||
BackgroundImageLayer.CornerRadius = new CornerRadius(cornerRadius);
|
||||
@@ -235,8 +224,8 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
BackgroundLightLayer.CornerRadius = new CornerRadius(cornerRadius);
|
||||
BackgroundShadeLayer.CornerRadius = new CornerRadius(cornerRadius);
|
||||
ContentPaddingBorder.Padding = new Thickness(
|
||||
Math.Clamp(Math.Min(20 * scale, hostWidth * 0.028), 3, 18),
|
||||
Math.Clamp(Math.Min(14 * scale, hostHeight * 0.060), 2, 14));
|
||||
Math.Clamp(Math.Min((_currentCellSize * metrics.HorizontalPaddingScale) * scale, hostWidth * 0.028), 3, 18),
|
||||
Math.Clamp(Math.Min((_currentCellSize * metrics.VerticalPaddingScale) * scale, hostHeight * 0.060), 2, 14));
|
||||
ApplyAdaptiveTypography();
|
||||
ResetParticles();
|
||||
}
|
||||
@@ -319,26 +308,10 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
|
||||
private bool ResolveIsNight(WeatherSnapshot snapshot)
|
||||
{
|
||||
if (snapshot.ObservationTime.HasValue)
|
||||
{
|
||||
var observed = snapshot.ObservationTime.Value;
|
||||
try
|
||||
{
|
||||
if (_timeZoneService is not null)
|
||||
{
|
||||
var zoned = TimeZoneInfo.ConvertTime(observed, _timeZoneService.CurrentTimeZone);
|
||||
return zoned.Hour < 6 || zoned.Hour >= 18;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// fall through to local clock
|
||||
}
|
||||
|
||||
return observed.Hour < 6 || observed.Hour >= 18;
|
||||
}
|
||||
|
||||
return IsNightNow();
|
||||
return HyperOS3WeatherTheme.ResolveIsNightPreferred(
|
||||
snapshot,
|
||||
_timeZoneService?.CurrentTimeZone,
|
||||
_timeZoneService?.GetCurrentTime() ?? DateTime.Now);
|
||||
}
|
||||
|
||||
private bool IsNightNow()
|
||||
@@ -557,11 +530,11 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
BackgroundTintLayer.Background = CreateSolidBrush(palette.Tint);
|
||||
|
||||
var primary = CreateSolidBrush(palette.PrimaryText);
|
||||
var particleBrush = CreateSolidBrush(palette.ParticleColor);
|
||||
var particleBrush = ResolveParticleBrush(ToThemeKind(kind), palette.ParticleColor);
|
||||
var isNightVisual = kind is WeatherVisualKind.ClearNight or WeatherVisualKind.CloudyNight;
|
||||
var conditionSecondary = CreateSolidBrush(palette.SecondaryText, isNightVisual ? (byte)0xF0 : (byte)0xE6);
|
||||
var rangeSecondary = CreateSolidBrush(palette.SecondaryText, isNightVisual ? (byte)0xE8 : (byte)0xD6);
|
||||
var forecastTimeBrush = CreateSolidBrush(palette.SecondaryText, isNightVisual ? (byte)0xDA : (byte)0xC6);
|
||||
var forecastTimeBrush = CreateSolidBrush(palette.TertiaryText, isNightVisual ? (byte)0xDA : (byte)0xC6);
|
||||
var forecastTempBrush = CreateSolidBrush(palette.PrimaryText, isNightVisual ? (byte)0xF4 : (byte)0xEA);
|
||||
HourlyPanelBorder.Background = CreateSolidBrush(isNightVisual ? "#1BFFFFFF" : "#1EFFFFFF");
|
||||
LocationIcon.Foreground = primary;
|
||||
@@ -593,7 +566,8 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
return cached;
|
||||
}
|
||||
|
||||
if (WeatherBackgroundAssets.TryGetValue(kind, out var uriText))
|
||||
var uriText = HyperOS3WeatherTheme.ResolveBackgroundAsset(ToThemeKind(kind));
|
||||
if (!string.IsNullOrWhiteSpace(uriText))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -621,104 +595,89 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
return gradientBrush;
|
||||
}
|
||||
|
||||
private IBrush ResolveParticleBrush(HyperOS3WeatherVisualKind kind, string fallbackColor)
|
||||
{
|
||||
if (_particleBrushCache.TryGetValue(kind, out var cached))
|
||||
{
|
||||
return cached;
|
||||
}
|
||||
|
||||
var uriText = HyperOS3WeatherTheme.ResolveParticleAsset(kind);
|
||||
if (!string.IsNullOrWhiteSpace(uriText))
|
||||
{
|
||||
try
|
||||
{
|
||||
var uri = new Uri(uriText, UriKind.Absolute);
|
||||
using var stream = AssetLoader.Open(uri);
|
||||
var bitmap = new Bitmap(stream);
|
||||
var imageBrush = new ImageBrush
|
||||
{
|
||||
Source = bitmap,
|
||||
Stretch = Stretch.UniformToFill,
|
||||
AlignmentX = AlignmentX.Center,
|
||||
AlignmentY = AlignmentY.Center
|
||||
};
|
||||
_particleBrushCache[kind] = imageBrush;
|
||||
return imageBrush;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Fall through to solid particle color when the image cannot be loaded.
|
||||
}
|
||||
}
|
||||
|
||||
var solidBrush = CreateSolidBrush(fallbackColor);
|
||||
_particleBrushCache[kind] = solidBrush;
|
||||
return solidBrush;
|
||||
}
|
||||
|
||||
private static WeatherVisualKind ResolveVisualKind(int? weatherCode, bool isNight)
|
||||
{
|
||||
return weatherCode switch
|
||||
return HyperOS3WeatherTheme.ResolveVisualKind(weatherCode, isNight) switch
|
||||
{
|
||||
0 => isNight ? WeatherVisualKind.ClearNight : WeatherVisualKind.ClearDay,
|
||||
1 or 2 => isNight ? WeatherVisualKind.CloudyNight : WeatherVisualKind.CloudyDay,
|
||||
3 or 7 => WeatherVisualKind.RainLight,
|
||||
8 or 9 => WeatherVisualKind.RainHeavy,
|
||||
4 => WeatherVisualKind.Storm,
|
||||
13 or 14 or 15 or 16 => WeatherVisualKind.Snow,
|
||||
18 or 32 => WeatherVisualKind.Fog,
|
||||
_ => isNight ? WeatherVisualKind.CloudyNight : WeatherVisualKind.CloudyDay
|
||||
HyperOS3WeatherVisualKind.ClearDay => WeatherVisualKind.ClearDay,
|
||||
HyperOS3WeatherVisualKind.ClearNight => WeatherVisualKind.ClearNight,
|
||||
HyperOS3WeatherVisualKind.CloudyDay => WeatherVisualKind.CloudyDay,
|
||||
HyperOS3WeatherVisualKind.CloudyNight => WeatherVisualKind.CloudyNight,
|
||||
HyperOS3WeatherVisualKind.RainLight => WeatherVisualKind.RainLight,
|
||||
HyperOS3WeatherVisualKind.RainHeavy => WeatherVisualKind.RainHeavy,
|
||||
HyperOS3WeatherVisualKind.Storm => WeatherVisualKind.Storm,
|
||||
HyperOS3WeatherVisualKind.Snow => WeatherVisualKind.Snow,
|
||||
_ => WeatherVisualKind.Fog
|
||||
};
|
||||
}
|
||||
|
||||
private static WeatherVisualPalette ResolvePalette(WeatherVisualKind kind)
|
||||
{
|
||||
return kind switch
|
||||
{
|
||||
WeatherVisualKind.ClearDay => new WeatherVisualPalette(
|
||||
GradientFrom: "#4F92E8",
|
||||
GradientTo: "#83C5FF",
|
||||
Tint: "#234D87",
|
||||
PrimaryText: "#FFFFFFFF",
|
||||
SecondaryText: "#EEF5FF",
|
||||
ParticleColor: "#00FFFFFF"),
|
||||
WeatherVisualKind.ClearNight => new WeatherVisualPalette(
|
||||
GradientFrom: "#0E2B72",
|
||||
GradientTo: "#193A85",
|
||||
Tint: "#0A1E52",
|
||||
PrimaryText: "#FFFFFFFF",
|
||||
SecondaryText: "#CFE0FF",
|
||||
ParticleColor: "#00FFFFFF"),
|
||||
WeatherVisualKind.CloudyDay => new WeatherVisualPalette(
|
||||
GradientFrom: "#4A72B3",
|
||||
GradientTo: "#6A8EC2",
|
||||
Tint: "#2A487C",
|
||||
PrimaryText: "#FFFFFFFF",
|
||||
SecondaryText: "#EAF2FF",
|
||||
ParticleColor: "#16FFFFFF"),
|
||||
WeatherVisualKind.CloudyNight => new WeatherVisualPalette(
|
||||
GradientFrom: "#102A6B",
|
||||
GradientTo: "#193A80",
|
||||
Tint: "#0B1F51",
|
||||
PrimaryText: "#FFFFFFFF",
|
||||
SecondaryText: "#D5E4FF",
|
||||
ParticleColor: "#24FFFFFF"),
|
||||
WeatherVisualKind.RainLight => new WeatherVisualPalette(
|
||||
GradientFrom: "#32588A",
|
||||
GradientTo: "#4D74A8",
|
||||
Tint: "#1F3454",
|
||||
PrimaryText: "#FFFFFFFF",
|
||||
SecondaryText: "#E6F0FF",
|
||||
ParticleColor: "#88D7E8FF"),
|
||||
WeatherVisualKind.RainHeavy => new WeatherVisualPalette(
|
||||
GradientFrom: "#253F66",
|
||||
GradientTo: "#36567F",
|
||||
Tint: "#17263E",
|
||||
PrimaryText: "#FFFFFFFF",
|
||||
SecondaryText: "#DCE9FF",
|
||||
ParticleColor: "#A2CDE1FF"),
|
||||
WeatherVisualKind.Storm => new WeatherVisualPalette(
|
||||
GradientFrom: "#293A67",
|
||||
GradientTo: "#3A4F78",
|
||||
Tint: "#161E35",
|
||||
PrimaryText: "#FFFFFFFF",
|
||||
SecondaryText: "#DCE4F8",
|
||||
ParticleColor: "#A8C2D6F2"),
|
||||
WeatherVisualKind.Snow => new WeatherVisualPalette(
|
||||
GradientFrom: "#D1E8FF",
|
||||
GradientTo: "#A7D0F4",
|
||||
Tint: "#607C9D",
|
||||
PrimaryText: "#FF10253D",
|
||||
SecondaryText: "#FF2B435E",
|
||||
ParticleColor: "#CCFFFFFF"),
|
||||
_ => new WeatherVisualPalette(
|
||||
GradientFrom: "#445B7A",
|
||||
GradientTo: "#5B738F",
|
||||
Tint: "#2A3E56",
|
||||
PrimaryText: "#FFFFFFFF",
|
||||
SecondaryText: "#E7EDF6",
|
||||
ParticleColor: "#88E4EDF7")
|
||||
};
|
||||
var palette = HyperOS3WeatherTheme.ResolvePalette(ToThemeKind(kind));
|
||||
return new WeatherVisualPalette(
|
||||
palette.GradientFrom,
|
||||
palette.GradientTo,
|
||||
palette.Tint,
|
||||
palette.PrimaryText,
|
||||
palette.SecondaryText,
|
||||
palette.TertiaryText,
|
||||
palette.ParticleColor);
|
||||
}
|
||||
|
||||
private static Symbol ResolveWeatherSymbol(WeatherVisualKind kind)
|
||||
{
|
||||
return HyperOS3WeatherTheme.ResolveWeatherSymbol(ToThemeKind(kind));
|
||||
}
|
||||
|
||||
private static HyperOS3WeatherVisualKind ToThemeKind(WeatherVisualKind kind)
|
||||
{
|
||||
return kind switch
|
||||
{
|
||||
WeatherVisualKind.ClearDay => Symbol.WeatherSunny,
|
||||
WeatherVisualKind.ClearNight => Symbol.WeatherMoon,
|
||||
WeatherVisualKind.CloudyDay => Symbol.WeatherPartlyCloudyDay,
|
||||
WeatherVisualKind.CloudyNight => Symbol.WeatherPartlyCloudyNight,
|
||||
WeatherVisualKind.RainLight => Symbol.WeatherRainShowersDay,
|
||||
WeatherVisualKind.RainHeavy => Symbol.WeatherRain,
|
||||
WeatherVisualKind.Storm => Symbol.WeatherThunderstorm,
|
||||
WeatherVisualKind.Snow => Symbol.WeatherSnow,
|
||||
_ => Symbol.WeatherFog
|
||||
WeatherVisualKind.ClearDay => HyperOS3WeatherVisualKind.ClearDay,
|
||||
WeatherVisualKind.ClearNight => HyperOS3WeatherVisualKind.ClearNight,
|
||||
WeatherVisualKind.CloudyDay => HyperOS3WeatherVisualKind.CloudyDay,
|
||||
WeatherVisualKind.CloudyNight => HyperOS3WeatherVisualKind.CloudyNight,
|
||||
WeatherVisualKind.RainLight => HyperOS3WeatherVisualKind.RainLight,
|
||||
WeatherVisualKind.RainHeavy => HyperOS3WeatherVisualKind.RainHeavy,
|
||||
WeatherVisualKind.Storm => HyperOS3WeatherVisualKind.Storm,
|
||||
WeatherVisualKind.Snow => HyperOS3WeatherVisualKind.Snow,
|
||||
_ => HyperOS3WeatherVisualKind.Fog
|
||||
};
|
||||
}
|
||||
|
||||
@@ -994,18 +953,8 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
|
||||
private static string ResolveWeatherIconAccent(Symbol symbol, bool isNightVisual)
|
||||
{
|
||||
return symbol switch
|
||||
{
|
||||
Symbol.WeatherSunny => isNightVisual ? "#FFD978" : "#F7C40A",
|
||||
Symbol.WeatherMoon => "#F3D38C",
|
||||
Symbol.WeatherPartlyCloudyDay => "#75B0FF",
|
||||
Symbol.WeatherPartlyCloudyNight => "#8AB6FF",
|
||||
Symbol.WeatherRainShowersDay => "#9ECBFF",
|
||||
Symbol.WeatherRain => "#8DBDF5",
|
||||
Symbol.WeatherThunderstorm => "#F4D16E",
|
||||
Symbol.WeatherSnow => "#C7E6FF",
|
||||
_ => isNightVisual ? "#D5E2F4" : "#E2ECFA"
|
||||
};
|
||||
var kind = isNightVisual ? HyperOS3WeatherVisualKind.ClearNight : HyperOS3WeatherVisualKind.ClearDay;
|
||||
return HyperOS3WeatherTheme.ResolveIconAccent(kind, symbol);
|
||||
}
|
||||
|
||||
private static string ResolvePreciseDisplayLocation(string? rawName, string languageCode, string fallback)
|
||||
@@ -1154,6 +1103,7 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
private void ApplyAdaptiveTypography()
|
||||
{
|
||||
var (layoutWidth, layoutHeight) = ResolveLayoutViewport();
|
||||
var metrics = HyperOS3WeatherTheme.ResolveMetrics(HyperOS3WeatherWidgetKind.Hourly4x2);
|
||||
var scale = ResolveScale(layoutWidth, layoutHeight);
|
||||
var densityBoost = scale <= 0.55 ? 0.80 : scale <= 0.72 ? 0.88 : scale <= 0.92 ? 0.95 : scale >= 1.45 ? 1.06 : 1.0;
|
||||
var compactness = Math.Clamp((0.88 - scale) / 0.50, 0, 1);
|
||||
@@ -1162,9 +1112,9 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
var conditionLength = Math.Max(1, ConditionTextBlock.Text?.Length ?? 2);
|
||||
var conditionCompression = conditionLength >= 12 ? 0.72 : conditionLength >= 8 ? 0.85 : conditionLength >= 6 ? 0.92 : 1.0;
|
||||
|
||||
ContentGrid.RowSpacing = Math.Clamp(layoutHeight * Lerp(0.030, 0.018, compactness), 2, 14);
|
||||
TopRowGrid.ColumnSpacing = Math.Clamp(layoutWidth * 0.014, 3, 14);
|
||||
BottomInfoStack.Spacing = Math.Clamp(layoutHeight * 0.016, 2, 10);
|
||||
ContentGrid.RowSpacing = Math.Clamp(Math.Max(metrics.MainGap * scale, layoutHeight * Lerp(0.030, 0.018, compactness)), 2, 14);
|
||||
TopRowGrid.ColumnSpacing = Math.Clamp(Math.Max(metrics.MainGap * scale, layoutWidth * 0.014), 3, 14);
|
||||
BottomInfoStack.Spacing = Math.Clamp(Math.Max(metrics.SectionGap * scale, layoutHeight * 0.016), 2, 10);
|
||||
BottomInfoStack.Margin = new Thickness(0, 0, 0, Math.Clamp(layoutHeight * 0.018, 0, 10));
|
||||
ConditionRangeStack.Spacing = Math.Clamp(layoutWidth * 0.010, 3, 12);
|
||||
ConditionRangeStack.Margin = new Thickness(0, 0, 0, Math.Clamp(layoutHeight * 0.018, 0, 10));
|
||||
@@ -1179,12 +1129,12 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
var middleBandHeight = Math.Max(24, layoutHeight * 0.30);
|
||||
var bottomBandHeight = Math.Max(22, layoutHeight - topBandHeight - middleBandHeight - (ContentGrid.RowSpacing * 2));
|
||||
|
||||
LocationIcon.FontSize = Math.Min(Math.Clamp(24 * scale * densityBoost, 9, 30), topBandHeight * 0.58);
|
||||
CityTextBlock.FontSize = Math.Min(Math.Clamp(40 * scale * cityCompression * densityBoost, 12, 46), topBandHeight * 0.76);
|
||||
WeatherIconSymbol.FontSize = Math.Min(Math.Clamp(52 * scale * densityBoost, 12, 56), topBandHeight * 0.95);
|
||||
TemperatureTextBlock.FontSize = Math.Min(Math.Clamp(134 * scale * densityBoost, 26, 138), middleBandHeight * 0.92);
|
||||
ConditionTextBlock.FontSize = Math.Min(Math.Clamp(32 * scale * conditionCompression * densityBoost, 9, 40), middleBandHeight * 0.42);
|
||||
RangeTextBlock.FontSize = Math.Min(Math.Clamp(37 * scale * densityBoost, 10, 46), middleBandHeight * 0.50);
|
||||
LocationIcon.FontSize = Math.Min(Math.Clamp((metrics.IconFont * 0.6) * scale * densityBoost, 9, 30), topBandHeight * 0.58);
|
||||
CityTextBlock.FontSize = Math.Min(Math.Clamp((metrics.PrimaryTextFont * 1.42) * scale * cityCompression * densityBoost, 12, 46), topBandHeight * 0.76);
|
||||
WeatherIconSymbol.FontSize = Math.Min(Math.Clamp((metrics.IconFont * 1.02) * scale * densityBoost, 12, 56), topBandHeight * 0.95);
|
||||
TemperatureTextBlock.FontSize = Math.Min(Math.Clamp((metrics.PrimaryTemperatureFont * 1.40) * scale * densityBoost, 26, 138), middleBandHeight * 0.92);
|
||||
ConditionTextBlock.FontSize = Math.Min(Math.Clamp((metrics.PrimaryTextFont * 1.14) * scale * conditionCompression * densityBoost, 9, 40), middleBandHeight * 0.42);
|
||||
RangeTextBlock.FontSize = Math.Min(Math.Clamp((metrics.SecondaryTextFont * 1.54) * scale * densityBoost, 10, 46), middleBandHeight * 0.50);
|
||||
TemperatureTextBlock.Margin = new Thickness(0, Math.Clamp(layoutHeight * 0.008, 0, 6), 0, Math.Clamp(layoutHeight * 0.012, 0, 8));
|
||||
|
||||
var weightProgress = Math.Clamp((scale - 0.34) / 1.18, 0, 1);
|
||||
@@ -1219,13 +1169,13 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
var hourlyIconMaxByHeight = Math.Clamp(hourlyLineHeight * 1.05, 8, 30);
|
||||
|
||||
var hourlyTimeSize = Math.Min(
|
||||
Math.Clamp(24 * scale * densityBoost, 8, 30),
|
||||
Math.Clamp((metrics.CaptionFont * 1.20) * scale * densityBoost, 8, 30),
|
||||
Math.Min(hourlyTimeMaxByWidth, hourlyTimeMaxByHeight));
|
||||
var hourlyIconSize = Math.Min(
|
||||
Math.Clamp(30 * scale * densityBoost, 8, 34),
|
||||
Math.Clamp((metrics.IconFont * 0.64) * scale * densityBoost, 8, 34),
|
||||
Math.Min(hourlyIconMaxByWidth, hourlyIconMaxByHeight));
|
||||
var hourlyTempSize = Math.Min(
|
||||
Math.Clamp(32 * scale * densityBoost, 8, 34),
|
||||
Math.Clamp((metrics.SecondaryTextFont * 1.34) * scale * densityBoost, 8, 34),
|
||||
Math.Min(hourlyTempMaxByWidth, hourlyTempMaxByHeight));
|
||||
|
||||
for (var i = 0; i < _hourlyTimeBlocks.Length; i++)
|
||||
@@ -1256,81 +1206,25 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
|
||||
private WeatherMotionProfile ResolveMotionProfile(WeatherVisualKind kind)
|
||||
{
|
||||
return kind switch
|
||||
{
|
||||
WeatherVisualKind.ClearDay => new WeatherMotionProfile(
|
||||
DriftX: 8.0, DriftY: 4.0, ZoomBase: 1.055, ZoomAmplitude: 0.012,
|
||||
MotionOpacityBase: 0.22, MotionOpacityPulse: 0.05,
|
||||
LightOpacityBase: 0.68, LightOpacityPulse: 0.08,
|
||||
ShadeOpacityBase: 0.72, ShadeOpacityPulse: 0.03,
|
||||
PhaseStep: 0.015, ParticleCount: 0,
|
||||
ParticleSpeedMin: 0, ParticleSpeedMax: 0,
|
||||
ParticleLengthMin: 0, ParticleLengthMax: 0, ParticleDriftPerTick: 0),
|
||||
WeatherVisualKind.ClearNight => new WeatherMotionProfile(
|
||||
DriftX: 10.0, DriftY: 6.0, ZoomBase: 1.060, ZoomAmplitude: 0.014,
|
||||
MotionOpacityBase: 0.28, MotionOpacityPulse: 0.06,
|
||||
LightOpacityBase: 0.58, LightOpacityPulse: 0.07,
|
||||
ShadeOpacityBase: 0.82, ShadeOpacityPulse: 0.04,
|
||||
PhaseStep: 0.018, ParticleCount: 0,
|
||||
ParticleSpeedMin: 0, ParticleSpeedMax: 0,
|
||||
ParticleLengthMin: 0, ParticleLengthMax: 0, ParticleDriftPerTick: 0),
|
||||
WeatherVisualKind.CloudyDay => new WeatherMotionProfile(
|
||||
DriftX: 12.0, DriftY: 7.0, ZoomBase: 1.060, ZoomAmplitude: 0.013,
|
||||
MotionOpacityBase: 0.32, MotionOpacityPulse: 0.06,
|
||||
LightOpacityBase: 0.62, LightOpacityPulse: 0.07,
|
||||
ShadeOpacityBase: 0.80, ShadeOpacityPulse: 0.03,
|
||||
PhaseStep: 0.020, ParticleCount: 6,
|
||||
ParticleSpeedMin: 0.30, ParticleSpeedMax: 0.70,
|
||||
ParticleLengthMin: 14, ParticleLengthMax: 28, ParticleDriftPerTick: 0.10),
|
||||
WeatherVisualKind.CloudyNight => new WeatherMotionProfile(
|
||||
DriftX: 14.0, DriftY: 8.0, ZoomBase: 1.065, ZoomAmplitude: 0.013,
|
||||
MotionOpacityBase: 0.34, MotionOpacityPulse: 0.07,
|
||||
LightOpacityBase: 0.54, LightOpacityPulse: 0.06,
|
||||
ShadeOpacityBase: 0.85, ShadeOpacityPulse: 0.03,
|
||||
PhaseStep: 0.021, ParticleCount: 8,
|
||||
ParticleSpeedMin: 0.35, ParticleSpeedMax: 0.80,
|
||||
ParticleLengthMin: 16, ParticleLengthMax: 30, ParticleDriftPerTick: 0.12),
|
||||
WeatherVisualKind.RainLight => new WeatherMotionProfile(
|
||||
DriftX: 6.0, DriftY: 10.0, ZoomBase: 1.050, ZoomAmplitude: 0.010,
|
||||
MotionOpacityBase: 0.30, MotionOpacityPulse: 0.08,
|
||||
LightOpacityBase: 0.50, LightOpacityPulse: 0.04,
|
||||
ShadeOpacityBase: 0.84, ShadeOpacityPulse: 0.04,
|
||||
PhaseStep: 0.030, ParticleCount: 18,
|
||||
ParticleSpeedMin: 1.80, ParticleSpeedMax: 3.20,
|
||||
ParticleLengthMin: 14, ParticleLengthMax: 26, ParticleDriftPerTick: 0.70),
|
||||
WeatherVisualKind.RainHeavy => new WeatherMotionProfile(
|
||||
DriftX: 5.0, DriftY: 11.0, ZoomBase: 1.045, ZoomAmplitude: 0.010,
|
||||
MotionOpacityBase: 0.34, MotionOpacityPulse: 0.10,
|
||||
LightOpacityBase: 0.42, LightOpacityPulse: 0.03,
|
||||
ShadeOpacityBase: 0.88, ShadeOpacityPulse: 0.05,
|
||||
PhaseStep: 0.036, ParticleCount: 30,
|
||||
ParticleSpeedMin: 2.80, ParticleSpeedMax: 4.80,
|
||||
ParticleLengthMin: 18, ParticleLengthMax: 34, ParticleDriftPerTick: 0.92),
|
||||
WeatherVisualKind.Storm => new WeatherMotionProfile(
|
||||
DriftX: 4.0, DriftY: 12.0, ZoomBase: 1.042, ZoomAmplitude: 0.012,
|
||||
MotionOpacityBase: 0.38, MotionOpacityPulse: 0.12,
|
||||
LightOpacityBase: 0.36, LightOpacityPulse: 0.02,
|
||||
ShadeOpacityBase: 0.91, ShadeOpacityPulse: 0.04,
|
||||
PhaseStep: 0.042, ParticleCount: 34,
|
||||
ParticleSpeedMin: 3.60, ParticleSpeedMax: 5.80,
|
||||
ParticleLengthMin: 20, ParticleLengthMax: 36, ParticleDriftPerTick: 1.08),
|
||||
WeatherVisualKind.Snow => new WeatherMotionProfile(
|
||||
DriftX: 9.0, DriftY: 7.0, ZoomBase: 1.055, ZoomAmplitude: 0.012,
|
||||
MotionOpacityBase: 0.28, MotionOpacityPulse: 0.06,
|
||||
LightOpacityBase: 0.74, LightOpacityPulse: 0.08,
|
||||
ShadeOpacityBase: 0.68, ShadeOpacityPulse: 0.03,
|
||||
PhaseStep: 0.020, ParticleCount: 24,
|
||||
ParticleSpeedMin: 0.60, ParticleSpeedMax: 1.60,
|
||||
ParticleLengthMin: 3.0, ParticleLengthMax: 8.5, ParticleDriftPerTick: 0.24),
|
||||
_ => new WeatherMotionProfile(
|
||||
DriftX: 7.0, DriftY: 5.0, ZoomBase: 1.050, ZoomAmplitude: 0.011,
|
||||
MotionOpacityBase: 0.30, MotionOpacityPulse: 0.05,
|
||||
LightOpacityBase: 0.58, LightOpacityPulse: 0.05,
|
||||
ShadeOpacityBase: 0.86, ShadeOpacityPulse: 0.03,
|
||||
PhaseStep: 0.018, ParticleCount: 10,
|
||||
ParticleSpeedMin: 0.25, ParticleSpeedMax: 0.70,
|
||||
ParticleLengthMin: 16, ParticleLengthMax: 34, ParticleDriftPerTick: 0.12)
|
||||
};
|
||||
var motion = HyperOS3WeatherTheme.ResolveMotion(ToThemeKind(kind));
|
||||
return new WeatherMotionProfile(
|
||||
motion.DriftX,
|
||||
motion.DriftY,
|
||||
motion.ZoomBase,
|
||||
motion.ZoomAmplitude,
|
||||
motion.MotionOpacityBase,
|
||||
motion.MotionOpacityPulse,
|
||||
motion.LightOpacityBase,
|
||||
motion.LightOpacityPulse,
|
||||
motion.ShadeOpacityBase,
|
||||
motion.ShadeOpacityPulse,
|
||||
motion.PhaseStep,
|
||||
motion.ParticleCount,
|
||||
motion.ParticleSpeedMin,
|
||||
motion.ParticleSpeedMax,
|
||||
motion.ParticleLengthMin,
|
||||
motion.ParticleLengthMax,
|
||||
motion.ParticleDriftPerTick);
|
||||
}
|
||||
|
||||
private void ResetAnimationState()
|
||||
|
||||
Reference in New Issue
Block a user