mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-22 17:24:27 +08:00
0.4.1
修天气,时钟,每日图片....
This commit is contained in:
@@ -18,7 +18,8 @@
|
|||||||
<Border x:Name="ArtworkPanel"
|
<Border x:Name="ArtworkPanel"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
ClipToBounds="True"
|
ClipToBounds="True"
|
||||||
Background="#B8AE9A">
|
Background="#B8AE9A"
|
||||||
|
PointerPressed="OnArtworkPanelPointerPressed">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image x:Name="ArtworkImage"
|
<Image x:Name="ArtworkImage"
|
||||||
Stretch="UniformToFill" />
|
Stretch="UniformToFill" />
|
||||||
@@ -34,12 +35,14 @@
|
|||||||
FontSize="44"
|
FontSize="44"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
FontFeatures="tnum"
|
FontFeatures="tnum"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
LineHeight="46" />
|
LineHeight="46" />
|
||||||
<TextBlock x:Name="WeekdayTextBlock"
|
<TextBlock x:Name="WeekdayTextBlock"
|
||||||
Text="星期二"
|
Text="星期二"
|
||||||
Foreground="#F9F9F9"
|
Foreground="#F9F9F9"
|
||||||
FontSize="44"
|
FontSize="44"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
LineHeight="46" />
|
LineHeight="46" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -48,7 +51,8 @@
|
|||||||
<Border Grid.Column="1"
|
<Border Grid.Column="1"
|
||||||
x:Name="InfoPanel"
|
x:Name="InfoPanel"
|
||||||
Background="#111418"
|
Background="#111418"
|
||||||
Padding="18,14,18,14">
|
Padding="18,14,18,14"
|
||||||
|
PointerPressed="OnInfoPanelPointerPressed">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Canvas x:Name="BrickPatternCanvas"
|
<Canvas x:Name="BrickPatternCanvas"
|
||||||
IsHitTestVisible="False"
|
IsHitTestVisible="False"
|
||||||
@@ -76,6 +80,7 @@
|
|||||||
FontSize="44"
|
FontSize="44"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
MaxLines="2"
|
MaxLines="2"
|
||||||
Margin="0,0,0,8" />
|
Margin="0,0,0,8" />
|
||||||
|
|
||||||
@@ -96,6 +101,7 @@
|
|||||||
FontSize="26"
|
FontSize="26"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
MaxLines="2" />
|
MaxLines="2" />
|
||||||
<TextBlock x:Name="YearTextBlock"
|
<TextBlock x:Name="YearTextBlock"
|
||||||
Text="1754"
|
Text="1754"
|
||||||
@@ -104,6 +110,7 @@
|
|||||||
FontWeight="Medium"
|
FontWeight="Medium"
|
||||||
FontFeatures="tnum"
|
FontFeatures="tnum"
|
||||||
TextWrapping="NoWrap"
|
TextWrapping="NoWrap"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
MaxLines="1" />
|
MaxLines="1" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
@@ -8,6 +9,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
@@ -62,6 +64,8 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
private double _currentCellSize = BaseCellSize;
|
private double _currentCellSize = BaseCellSize;
|
||||||
private bool _isAttached;
|
private bool _isAttached;
|
||||||
private bool _isRefreshing;
|
private bool _isRefreshing;
|
||||||
|
private string? _currentArtworkSourceUrl;
|
||||||
|
private string? _currentArtworkImageUrl;
|
||||||
|
|
||||||
public DailyArtworkWidget()
|
public DailyArtworkWidget()
|
||||||
{
|
{
|
||||||
@@ -102,7 +106,7 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
Math.Clamp(16 * scale, 8, 26));
|
Math.Clamp(16 * scale, 8, 26));
|
||||||
DateInfoStack.Spacing = Math.Clamp(2 * scale, 1, 6);
|
DateInfoStack.Spacing = Math.Clamp(4 * scale, 2, 10);
|
||||||
|
|
||||||
StatusTextBlock.FontSize = Math.Clamp(16 * scale, 10, 24);
|
StatusTextBlock.FontSize = Math.Clamp(16 * scale, 10, 24);
|
||||||
|
|
||||||
@@ -154,6 +158,28 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
await RefreshArtworkAsync(forceRefresh: false);
|
await RefreshArtworkAsync(forceRefresh: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnArtworkPanelPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = RefreshArtworkAsync(forceRefresh: true);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInfoPanelPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TryOpenArtworkSourceUrl();
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task RefreshArtworkAsync(bool forceRefresh)
|
private async Task RefreshArtworkAsync(bool forceRefresh)
|
||||||
{
|
{
|
||||||
if (!_isAttached || _isRefreshing)
|
if (!_isAttached || _isRefreshing)
|
||||||
@@ -222,6 +248,8 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
ArtistTextBlock.Text = NormalizeCompactText(artist);
|
ArtistTextBlock.Text = NormalizeCompactText(artist);
|
||||||
|
|
||||||
YearTextBlock.Text = ResolveYearText(snapshot);
|
YearTextBlock.Text = ResolveYearText(snapshot);
|
||||||
|
_currentArtworkSourceUrl = snapshot.ArtworkUrl;
|
||||||
|
_currentArtworkImageUrl = snapshot.ImageUrl;
|
||||||
StatusTextBlock.IsVisible = false;
|
StatusTextBlock.IsVisible = false;
|
||||||
|
|
||||||
UpdateAdaptiveLayout();
|
UpdateAdaptiveLayout();
|
||||||
@@ -352,6 +380,8 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
|
|
||||||
private void ApplyLoadingState()
|
private void ApplyLoadingState()
|
||||||
{
|
{
|
||||||
|
_currentArtworkSourceUrl = null;
|
||||||
|
_currentArtworkImageUrl = null;
|
||||||
StatusTextBlock.IsVisible = true;
|
StatusTextBlock.IsVisible = true;
|
||||||
StatusTextBlock.Text = L("artwork.widget.loading", "Loading...");
|
StatusTextBlock.Text = L("artwork.widget.loading", "Loading...");
|
||||||
PaintingTitleTextBlock.Text = BuildQuotedTitle(L("artwork.widget.loading_title", "Daily Artwork"));
|
PaintingTitleTextBlock.Text = BuildQuotedTitle(L("artwork.widget.loading_title", "Daily Artwork"));
|
||||||
@@ -362,6 +392,8 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
|
|
||||||
private void ApplyFailedState()
|
private void ApplyFailedState()
|
||||||
{
|
{
|
||||||
|
_currentArtworkSourceUrl = null;
|
||||||
|
_currentArtworkImageUrl = null;
|
||||||
StatusTextBlock.IsVisible = true;
|
StatusTextBlock.IsVisible = true;
|
||||||
StatusTextBlock.Text = L("artwork.widget.fetch_failed", "Artwork fetch failed");
|
StatusTextBlock.Text = L("artwork.widget.fetch_failed", "Artwork fetch failed");
|
||||||
PaintingTitleTextBlock.Text = BuildQuotedTitle(L("artwork.widget.fallback_title", "Daily Artwork"));
|
PaintingTitleTextBlock.Text = BuildQuotedTitle(L("artwork.widget.fallback_title", "Daily Artwork"));
|
||||||
@@ -384,71 +416,94 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
var rightContentWidth = Math.Max(58, rightPanelWidth - InfoPanel.Padding.Left - InfoPanel.Padding.Right);
|
var rightContentWidth = Math.Max(58, rightPanelWidth - InfoPanel.Padding.Left - InfoPanel.Padding.Right);
|
||||||
var leftPanelWidth = Math.Max(84, totalWidth - rightPanelWidth);
|
var leftPanelWidth = Math.Max(84, totalWidth - rightPanelWidth);
|
||||||
var leftContentWidth = Math.Max(52, leftPanelWidth - DateInfoStack.Margin.Left - 10);
|
var leftContentWidth = Math.Max(52, leftPanelWidth - DateInfoStack.Margin.Left - 10);
|
||||||
|
var leftContentHeight = Math.Max(30, totalHeight - DateInfoStack.Margin.Bottom - 10);
|
||||||
|
|
||||||
|
var dateStackSpacing = Math.Clamp(4 * scale, 2, 10);
|
||||||
|
DateInfoStack.Spacing = dateStackSpacing;
|
||||||
|
DateInfoStack.MaxWidth = leftContentWidth;
|
||||||
|
var leftSingleLineHeight = Math.Max(12, (leftContentHeight - dateStackSpacing) / 2d);
|
||||||
|
|
||||||
var dateBase = Math.Clamp(44 * scale, 16, 62);
|
var dateBase = Math.Clamp(44 * scale, 16, 62);
|
||||||
DateTextBlock.FontSize = FitFontSize(
|
DateTextBlock.FontSize = FitFontSize(
|
||||||
DateTextBlock.Text,
|
DateTextBlock.Text,
|
||||||
leftContentWidth,
|
leftContentWidth,
|
||||||
Math.Max(18, totalHeight * 0.20),
|
leftSingleLineHeight,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
minFontSize: Math.Max(12, dateBase * 0.68),
|
minFontSize: Math.Max(12, dateBase * 0.68),
|
||||||
maxFontSize: dateBase,
|
maxFontSize: dateBase,
|
||||||
weight: FontWeight.Bold,
|
weight: FontWeight.Bold,
|
||||||
lineHeightFactor: 1.00);
|
lineHeightFactor: 1.10);
|
||||||
DateTextBlock.LineHeight = DateTextBlock.FontSize * 1.00;
|
DateTextBlock.LineHeight = DateTextBlock.FontSize * 1.10;
|
||||||
|
|
||||||
WeekdayTextBlock.FontSize = FitFontSize(
|
WeekdayTextBlock.FontSize = FitFontSize(
|
||||||
WeekdayTextBlock.Text,
|
WeekdayTextBlock.Text,
|
||||||
leftContentWidth,
|
leftContentWidth,
|
||||||
Math.Max(18, totalHeight * 0.21),
|
leftSingleLineHeight,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
minFontSize: Math.Max(12, dateBase * 0.68),
|
minFontSize: Math.Max(12, dateBase * 0.68),
|
||||||
maxFontSize: dateBase,
|
maxFontSize: dateBase,
|
||||||
weight: FontWeight.Bold,
|
weight: FontWeight.Bold,
|
||||||
lineHeightFactor: 1.00);
|
lineHeightFactor: 1.10);
|
||||||
WeekdayTextBlock.LineHeight = WeekdayTextBlock.FontSize * 1.00;
|
WeekdayTextBlock.LineHeight = WeekdayTextBlock.FontSize * 1.10;
|
||||||
|
|
||||||
|
var rightContentHeight = Math.Max(42, totalHeight - InfoPanel.Padding.Top - InfoPanel.Padding.Bottom);
|
||||||
|
var titleBottomMargin = Math.Clamp(8 * scale, 4, 14);
|
||||||
|
var separatorBottomMargin = Math.Clamp(10 * scale, 4, 14);
|
||||||
|
var bottomStackSpacing = Math.Clamp(3 * scale, 2, 8);
|
||||||
|
var reservedHeight = titleBottomMargin + separatorBottomMargin + bottomStackSpacing + 3;
|
||||||
|
var textHeightBudget = Math.Max(24, rightContentHeight - reservedHeight);
|
||||||
|
var titleHeightBudget = Math.Max(16, textHeightBudget * 0.54);
|
||||||
|
var bottomTextBudget = Math.Max(10, textHeightBudget - titleHeightBudget);
|
||||||
|
var artistHeightBudget = Math.Max(8, bottomTextBudget * 0.66);
|
||||||
|
var yearHeightBudget = Math.Max(8, bottomTextBudget - artistHeightBudget);
|
||||||
|
|
||||||
var titleBase = Math.Clamp(44 * scale, 16, 58);
|
var titleBase = Math.Clamp(44 * scale, 16, 58);
|
||||||
PaintingTitleTextBlock.MaxWidth = rightContentWidth;
|
PaintingTitleTextBlock.MaxWidth = rightContentWidth;
|
||||||
|
PaintingTitleTextBlock.Margin = new Thickness(0, 0, 0, titleBottomMargin);
|
||||||
PaintingTitleTextBlock.FontSize = FitFontSize(
|
PaintingTitleTextBlock.FontSize = FitFontSize(
|
||||||
PaintingTitleTextBlock.Text,
|
PaintingTitleTextBlock.Text,
|
||||||
rightContentWidth,
|
rightContentWidth,
|
||||||
Math.Max(20, totalHeight * 0.34),
|
titleHeightBudget,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
minFontSize: Math.Max(12, titleBase * 0.62),
|
minFontSize: Math.Max(12, titleBase * 0.62),
|
||||||
maxFontSize: titleBase,
|
maxFontSize: titleBase,
|
||||||
weight: FontWeight.Bold,
|
weight: FontWeight.Bold,
|
||||||
lineHeightFactor: 1.08);
|
lineHeightFactor: 1.12);
|
||||||
PaintingTitleTextBlock.LineHeight = PaintingTitleTextBlock.FontSize * 1.08;
|
PaintingTitleTextBlock.LineHeight = PaintingTitleTextBlock.FontSize * 1.12;
|
||||||
|
|
||||||
var artistBase = Math.Clamp(26 * scale, 11, 34);
|
var artistBase = Math.Clamp(26 * scale, 11, 34);
|
||||||
|
if (ArtistTextBlock.Parent is StackPanel artistInfoStack)
|
||||||
|
{
|
||||||
|
artistInfoStack.Spacing = bottomStackSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
ArtistTextBlock.MaxWidth = rightContentWidth;
|
ArtistTextBlock.MaxWidth = rightContentWidth;
|
||||||
ArtistTextBlock.FontSize = FitFontSize(
|
ArtistTextBlock.FontSize = FitFontSize(
|
||||||
ArtistTextBlock.Text,
|
ArtistTextBlock.Text,
|
||||||
rightContentWidth,
|
rightContentWidth,
|
||||||
Math.Max(18, totalHeight * 0.24),
|
artistHeightBudget,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
minFontSize: Math.Max(10, artistBase * 0.72),
|
minFontSize: Math.Max(10, artistBase * 0.72),
|
||||||
maxFontSize: artistBase,
|
maxFontSize: artistBase,
|
||||||
weight: FontWeight.SemiBold,
|
weight: FontWeight.SemiBold,
|
||||||
lineHeightFactor: 1.12);
|
lineHeightFactor: 1.14);
|
||||||
ArtistTextBlock.LineHeight = ArtistTextBlock.FontSize * 1.12;
|
ArtistTextBlock.LineHeight = ArtistTextBlock.FontSize * 1.14;
|
||||||
|
|
||||||
var yearBase = Math.Clamp(22 * scale, 10, 30);
|
var yearBase = Math.Clamp(22 * scale, 10, 30);
|
||||||
YearTextBlock.MaxWidth = rightContentWidth;
|
YearTextBlock.MaxWidth = rightContentWidth;
|
||||||
YearTextBlock.FontSize = FitFontSize(
|
YearTextBlock.FontSize = FitFontSize(
|
||||||
YearTextBlock.Text,
|
YearTextBlock.Text,
|
||||||
rightContentWidth,
|
rightContentWidth,
|
||||||
Math.Max(14, totalHeight * 0.12),
|
yearHeightBudget,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
minFontSize: Math.Max(9.5, yearBase * 0.78),
|
minFontSize: Math.Max(9.5, yearBase * 0.78),
|
||||||
maxFontSize: yearBase,
|
maxFontSize: yearBase,
|
||||||
weight: FontWeight.Medium,
|
weight: FontWeight.Medium,
|
||||||
lineHeightFactor: 1.04);
|
lineHeightFactor: 1.08);
|
||||||
YearTextBlock.LineHeight = YearTextBlock.FontSize * 1.04;
|
YearTextBlock.LineHeight = YearTextBlock.FontSize * 1.08;
|
||||||
|
|
||||||
RightPanelSeparator.Width = Math.Clamp(rightContentWidth * 0.58, 42, 136);
|
RightPanelSeparator.Width = Math.Clamp(rightContentWidth * 0.58, 42, 136);
|
||||||
RightPanelSeparator.Margin = new Thickness(0, 0, 0, Math.Clamp(10 * scale, 4, 14));
|
RightPanelSeparator.Margin = new Thickness(0, 0, 0, separatorBottomMargin);
|
||||||
|
|
||||||
BrickPatternCanvas.Opacity = totalWidth < _currentCellSize * 4.2
|
BrickPatternCanvas.Opacity = totalWidth < _currentCellSize * 4.2
|
||||||
? 0.34
|
? 0.34
|
||||||
@@ -478,6 +533,54 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
_currentArtworkBitmap = null;
|
_currentArtworkBitmap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TryOpenArtworkSourceUrl()
|
||||||
|
{
|
||||||
|
var candidate = _currentArtworkSourceUrl;
|
||||||
|
if (!TryNormalizeHttpUrl(candidate, out var normalizedUrl) &&
|
||||||
|
!TryNormalizeHttpUrl(_currentArtworkImageUrl, out normalizedUrl))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var startInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = normalizedUrl,
|
||||||
|
UseShellExecute = true
|
||||||
|
};
|
||||||
|
Process.Start(startInfo);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore malformed URLs or shell launch failures.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryNormalizeHttpUrl(string? rawUrl, out string normalizedUrl)
|
||||||
|
{
|
||||||
|
normalizedUrl = string.Empty;
|
||||||
|
if (string.IsNullOrWhiteSpace(rawUrl))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var candidate = rawUrl.Trim();
|
||||||
|
if (!Uri.TryCreate(candidate, UriKind.Absolute, out var uri))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.Equals(uri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
!string.Equals(uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
normalizedUrl = uri.ToString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateLanguageCode()
|
private void UpdateLanguageCode()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
private readonly TextBlock[] _dailyHighBlocks;
|
private readonly TextBlock[] _dailyHighBlocks;
|
||||||
private readonly TextBlock[] _dailyLowBlocks;
|
private readonly TextBlock[] _dailyLowBlocks;
|
||||||
private readonly Image[] _dailyIconBlocks;
|
private readonly Image[] _dailyIconBlocks;
|
||||||
|
private readonly HyperOS3WeatherVisualKind[] _dailyIconKinds;
|
||||||
|
|
||||||
public ExtendedWeatherWidget()
|
public ExtendedWeatherWidget()
|
||||||
{
|
{
|
||||||
@@ -76,6 +77,7 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
[
|
[
|
||||||
DailyIcon0, DailyIcon1, DailyIcon2, DailyIcon3, DailyIcon4
|
DailyIcon0, DailyIcon1, DailyIcon2, DailyIcon3, DailyIcon4
|
||||||
];
|
];
|
||||||
|
_dailyIconKinds = Enumerable.Repeat(HyperOS3WeatherVisualKind.CloudyDay, _dailyIconBlocks.Length).ToArray();
|
||||||
ConfigureTextOverflowGuards();
|
ConfigureTextOverflowGuards();
|
||||||
_refreshTimer.Tick += OnRefreshTimerTick;
|
_refreshTimer.Tick += OnRefreshTimerTick;
|
||||||
_animationTimer.Tick += OnAnimationTick;
|
_animationTimer.Tick += OnAnimationTick;
|
||||||
@@ -344,6 +346,7 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
_dailyLabelBlocks[i].Text = $"{ResolveDayLabel(date, i + 1)}·{dayText}";
|
_dailyLabelBlocks[i].Text = $"{ResolveDayLabel(date, i + 1)}·{dayText}";
|
||||||
_dailyHighBlocks[i].Text = FormatTemperatureValue(daily?.HighTemperatureC);
|
_dailyHighBlocks[i].Text = FormatTemperatureValue(daily?.HighTemperatureC);
|
||||||
_dailyLowBlocks[i].Text = FormatTemperatureValue(daily?.LowTemperatureC);
|
_dailyLowBlocks[i].Text = FormatTemperatureValue(daily?.LowTemperatureC);
|
||||||
|
_dailyIconKinds[i] = dayKind;
|
||||||
_dailyIconBlocks[i].Source = HyperOS3WeatherAssetLoader.LoadImage(HyperOS3WeatherTheme.ResolveMiniIconAsset(dayKind));
|
_dailyIconBlocks[i].Source = HyperOS3WeatherAssetLoader.LoadImage(HyperOS3WeatherTheme.ResolveMiniIconAsset(dayKind));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,6 +374,7 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
_dailyLabelBlocks[i].Text = $"{ResolveDayLabel(DateOnly.FromDateTime(DateTime.Now).AddDays(i + 1), i + 1)}·{L("weather.widget.condition_cloudy", "Cloudy")}";
|
_dailyLabelBlocks[i].Text = $"{ResolveDayLabel(DateOnly.FromDateTime(DateTime.Now).AddDays(i + 1), i + 1)}·{L("weather.widget.condition_cloudy", "Cloudy")}";
|
||||||
_dailyHighBlocks[i].Text = "--";
|
_dailyHighBlocks[i].Text = "--";
|
||||||
_dailyLowBlocks[i].Text = "--";
|
_dailyLowBlocks[i].Text = "--";
|
||||||
|
_dailyIconKinds[i] = HyperOS3WeatherVisualKind.CloudyDay;
|
||||||
_dailyIconBlocks[i].Source = HyperOS3WeatherAssetLoader.LoadImage(HyperOS3WeatherTheme.ResolveMiniIconAsset(HyperOS3WeatherVisualKind.CloudyDay));
|
_dailyIconBlocks[i].Source = HyperOS3WeatherAssetLoader.LoadImage(HyperOS3WeatherTheme.ResolveMiniIconAsset(HyperOS3WeatherVisualKind.CloudyDay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -523,7 +527,9 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
3.80);
|
3.80);
|
||||||
var hourlyTempSize = Math.Clamp(19 * hourlyCellScale, 6, 72);
|
var hourlyTempSize = Math.Clamp(19 * hourlyCellScale, 6, 72);
|
||||||
var hourlyTimeSize = Math.Clamp(14 * hourlyCellScale, 6, 52);
|
var hourlyTimeSize = Math.Clamp(14 * hourlyCellScale, 6, 52);
|
||||||
var hourlyIconSize = Math.Clamp(34 * hourlyCellScale, 8, 114);
|
var hourlyIconSize = Math.Clamp(42 * hourlyCellScale, 9, 140);
|
||||||
|
hourlyIconSize = Math.Min(hourlyIconSize, Math.Max(10, hourlyCellWidth * 0.86));
|
||||||
|
hourlyIconSize = Math.Min(hourlyIconSize, Math.Max(10, hourlyHeight * 0.56));
|
||||||
var hourlyStackSpacing = Math.Clamp(2 * hourlyCellScale, 0.2, 10);
|
var hourlyStackSpacing = Math.Clamp(2 * hourlyCellScale, 0.2, 10);
|
||||||
for (var i = 0; i < _hourlyTempBlocks.Length; i++)
|
for (var i = 0; i < _hourlyTempBlocks.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -548,7 +554,9 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
|
|
||||||
var dailyLabelSize = Math.Clamp(18.5 * dailyRowScale, 6, 70);
|
var dailyLabelSize = Math.Clamp(18.5 * dailyRowScale, 6, 70);
|
||||||
var dailyTempSize = Math.Clamp(19 * dailyRowScale, 6, 72);
|
var dailyTempSize = Math.Clamp(19 * dailyRowScale, 6, 72);
|
||||||
var dailyIconSize = Math.Clamp(30 * dailyRowScale, 8, 102);
|
var dailyIconSize = Math.Clamp(43 * dailyRowScale, 9, 132);
|
||||||
|
dailyIconSize = Math.Min(dailyIconSize, Math.Max(10, dailyRowHeight * 0.92));
|
||||||
|
dailyIconSize = Math.Min(dailyIconSize, Math.Max(10, innerWidth * 0.14));
|
||||||
var dailyLabelMaxWidth = Math.Clamp(innerWidth * 0.52, 28, 460);
|
var dailyLabelMaxWidth = Math.Clamp(innerWidth * 0.52, 28, 460);
|
||||||
var dailyHighWidth = Math.Clamp(innerWidth * 0.14, 14, 140);
|
var dailyHighWidth = Math.Clamp(innerWidth * 0.14, 14, 140);
|
||||||
var dailyLowWidth = Math.Clamp(innerWidth * 0.11, 12, 120);
|
var dailyLowWidth = Math.Clamp(innerWidth * 0.11, 12, 120);
|
||||||
@@ -570,8 +578,21 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
_dailyLowBlocks[i].HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right;
|
_dailyLowBlocks[i].HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right;
|
||||||
_dailyHighBlocks[i].TextAlignment = TextAlignment.Right;
|
_dailyHighBlocks[i].TextAlignment = TextAlignment.Right;
|
||||||
_dailyLowBlocks[i].TextAlignment = TextAlignment.Right;
|
_dailyLowBlocks[i].TextAlignment = TextAlignment.Right;
|
||||||
_dailyIconBlocks[i].Width = dailyIconSize;
|
if (_dailyIconBlocks[i].Parent is Grid dailyRowGrid)
|
||||||
_dailyIconBlocks[i].Height = dailyIconSize;
|
{
|
||||||
|
dailyRowGrid.ColumnSpacing = Math.Clamp(9 * dailyRowScale, 4, 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dailyKind = i < _dailyIconKinds.Length
|
||||||
|
? _dailyIconKinds[i]
|
||||||
|
: HyperOS3WeatherVisualKind.CloudyDay;
|
||||||
|
var dailyIconVisualSize = Math.Clamp(
|
||||||
|
dailyIconSize * ResolveDailyMiniIconScaleBoost(dailyKind),
|
||||||
|
8,
|
||||||
|
148);
|
||||||
|
dailyIconVisualSize = Math.Min(dailyIconVisualSize, Math.Max(10, dailyRowHeight * 0.94));
|
||||||
|
_dailyIconBlocks[i].Width = dailyIconVisualSize;
|
||||||
|
_dailyIconBlocks[i].Height = dailyIconVisualSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,6 +926,21 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
HyperOS3WeatherVisualKind.ClearNight or HyperOS3WeatherVisualKind.CloudyNight => 1.08,
|
HyperOS3WeatherVisualKind.ClearNight or HyperOS3WeatherVisualKind.CloudyNight => 1.08,
|
||||||
_ => 1.0
|
_ => 1.0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static double ResolveDailyMiniIconScaleBoost(HyperOS3WeatherVisualKind kind) =>
|
||||||
|
kind switch
|
||||||
|
{
|
||||||
|
HyperOS3WeatherVisualKind.CloudyDay => 1.30,
|
||||||
|
HyperOS3WeatherVisualKind.CloudyNight => 1.28,
|
||||||
|
HyperOS3WeatherVisualKind.ClearDay => 1.26,
|
||||||
|
HyperOS3WeatherVisualKind.ClearNight => 1.24,
|
||||||
|
HyperOS3WeatherVisualKind.Fog => 1.18,
|
||||||
|
HyperOS3WeatherVisualKind.RainLight => 1.14,
|
||||||
|
HyperOS3WeatherVisualKind.RainHeavy => 1.12,
|
||||||
|
HyperOS3WeatherVisualKind.Snow => 1.12,
|
||||||
|
HyperOS3WeatherVisualKind.Storm => 1.08,
|
||||||
|
_ => 1.18
|
||||||
|
};
|
||||||
private static FontWeight ToVariableWeight(double weight) => (FontWeight)(int)Math.Clamp(Math.Round(weight), 1, 1000);
|
private static FontWeight ToVariableWeight(double weight) => (FontWeight)(int)Math.Clamp(Math.Round(weight), 1, 1000);
|
||||||
private static IBrush CreateSolidBrush(string colorHex) => new SolidColorBrush(Color.Parse(colorHex));
|
private static IBrush CreateSolidBrush(string colorHex) => new SolidColorBrush(Color.Parse(colorHex));
|
||||||
private static IBrush CreateSolidBrush(string colorHex, byte alpha) { var c = Color.Parse(colorHex); return new SolidColorBrush(Color.FromArgb(alpha, c.R, c.G, c.B)); }
|
private static IBrush CreateSolidBrush(string colorHex, byte alpha) { var c = Color.Parse(colorHex); return new SolidColorBrush(Color.FromArgb(alpha, c.R, c.G, c.B)); }
|
||||||
|
|||||||
@@ -1264,7 +1264,9 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
|||||||
var stackSpacing = Math.Clamp(2 * hourlyCellScale, 0.2, 10);
|
var stackSpacing = Math.Clamp(2 * hourlyCellScale, 0.2, 10);
|
||||||
var hourlyTempSize = Math.Clamp(19.5 * hourlyCellScale, 6, 72);
|
var hourlyTempSize = Math.Clamp(19.5 * hourlyCellScale, 6, 72);
|
||||||
var hourlyTimeSize = Math.Clamp(14.5 * hourlyCellScale, 6, 50);
|
var hourlyTimeSize = Math.Clamp(14.5 * hourlyCellScale, 6, 50);
|
||||||
var hourlyIconSize = Math.Clamp(34 * hourlyCellScale, 8, 108);
|
var hourlyIconSize = Math.Clamp(42 * hourlyCellScale, 9, 136);
|
||||||
|
hourlyIconSize = Math.Min(hourlyIconSize, Math.Max(10, hourlyCellWidth * 0.86));
|
||||||
|
hourlyIconSize = Math.Min(hourlyIconSize, Math.Max(10, bottomZoneHeight * 0.52));
|
||||||
|
|
||||||
for (var i = 0; i < _hourlyTimeBlocks.Length; i++)
|
for (var i = 0; i < _hourlyTimeBlocks.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1112,7 +1112,9 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
var stackSpacing = Math.Clamp(2 * hourlyCellScale, 0.2, 10);
|
var stackSpacing = Math.Clamp(2 * hourlyCellScale, 0.2, 10);
|
||||||
var forecastRangeSize = Math.Clamp(18.0 * hourlyCellScale, 6, 62);
|
var forecastRangeSize = Math.Clamp(18.0 * hourlyCellScale, 6, 62);
|
||||||
var forecastLabelSize = Math.Clamp(13.8 * hourlyCellScale, 6, 48);
|
var forecastLabelSize = Math.Clamp(13.8 * hourlyCellScale, 6, 48);
|
||||||
var forecastIconSize = Math.Clamp(32 * hourlyCellScale, 8, 100);
|
var forecastIconSize = Math.Clamp(40 * hourlyCellScale, 9, 124);
|
||||||
|
forecastIconSize = Math.Min(forecastIconSize, Math.Max(10, hourlyCellWidth * 0.88));
|
||||||
|
forecastIconSize = Math.Min(forecastIconSize, Math.Max(10, bottomZoneHeight * 0.50));
|
||||||
|
|
||||||
for (var i = 0; i < _hourlyTimeBlocks.Length; i++)
|
for (var i = 0; i < _hourlyTimeBlocks.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user