mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
0.3.13
动画优化
This commit is contained in:
41
.github/workflows/release.yml
vendored
41
.github/workflows/release.yml
vendored
@@ -55,6 +55,7 @@ jobs:
|
||||
needs: prepare
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch: [x64, x86]
|
||||
name: Build_Windows_${{ matrix.arch }}
|
||||
@@ -136,14 +137,36 @@ jobs:
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Find Inno Setup compiler
|
||||
$isccPath = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
|
||||
if (-not (Test-Path -Path $isccPath)) {
|
||||
$isccPath = "C:\Program Files\Inno Setup 6\ISCC.exe"
|
||||
# Find Inno Setup compiler (choco may install a shim in PATH)
|
||||
$isccPath = $null
|
||||
$isccCommand = Get-Command ISCC.exe -ErrorAction SilentlyContinue
|
||||
if ($isccCommand) {
|
||||
$isccPath = $isccCommand.Source
|
||||
}
|
||||
|
||||
if (-not (Test-Path -Path $isccPath)) {
|
||||
Write-Error "Inno Setup compiler not found at: $isccPath"
|
||||
|
||||
$candidatePaths = @(
|
||||
"C:\Program Files (x86)\Inno Setup 6\ISCC.exe",
|
||||
"C:\Program Files\Inno Setup 6\ISCC.exe",
|
||||
"$env:ChocolateyInstall\bin\ISCC.exe",
|
||||
"$env:ChocolateyInstall\lib\innosetup\tools\ISCC.exe"
|
||||
)
|
||||
|
||||
if (-not $isccPath) {
|
||||
foreach ($candidate in $candidatePaths) {
|
||||
if ($candidate -and (Test-Path -Path $candidate)) {
|
||||
$isccPath = $candidate
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $isccPath) {
|
||||
Write-Host "ISCC.exe was not found in PATH or known locations."
|
||||
Write-Host "Checked locations:"
|
||||
$candidatePaths | ForEach-Object { Write-Host " - $_" }
|
||||
Write-Host "Chocolatey bin listing (if exists):"
|
||||
Get-ChildItem "$env:ChocolateyInstall\bin" -Filter "*iscc*" -ErrorAction SilentlyContinue | Select-Object FullName
|
||||
Write-Error "Inno Setup compiler not found."
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -158,8 +181,8 @@ jobs:
|
||||
|
||||
$compileArgs = @(
|
||||
"/DMyAppVersion=$version",
|
||||
"/DPublishDir=$publishDir",
|
||||
"/DMyOutputDir=$outputDir",
|
||||
"/DPublishDir=`"$publishDir`"",
|
||||
"/DMyOutputDir=`"$outputDir`"",
|
||||
"/DMyAppArch=$arch",
|
||||
$installerScript
|
||||
)
|
||||
|
||||
@@ -14,12 +14,14 @@ using LanMountainDesktop.Services;
|
||||
|
||||
namespace LanMountainDesktop.Views.Components;
|
||||
|
||||
public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
|
||||
public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
|
||||
{
|
||||
private static readonly IWeatherInfoService DefaultWeatherInfoService = new XiaomiWeatherService();
|
||||
|
||||
private readonly DispatcherTimer _refreshTimer = new() { Interval = TimeSpan.FromMinutes(12) };
|
||||
private readonly DispatcherTimer _animationTimer = new() { Interval = TimeSpan.FromMilliseconds(48) };
|
||||
private readonly ScaleTransform _backgroundMotionScaleTransform = new(1, 1);
|
||||
private readonly TranslateTransform _backgroundMotionTranslateTransform = new();
|
||||
private readonly AppSettingsService _settingsService = new();
|
||||
private readonly LocalizationService _localizationService = new();
|
||||
|
||||
@@ -29,6 +31,7 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
private double _currentCellSize = 48;
|
||||
private double _phase;
|
||||
private bool _isAttached;
|
||||
private bool _isOnActivePage = true;
|
||||
private bool _isRefreshing;
|
||||
private string _languageCode = "zh-CN";
|
||||
private HyperOS3WeatherVisualKind _activeVisualKind = HyperOS3WeatherVisualKind.ClearDay;
|
||||
@@ -43,6 +46,7 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
public ExtendedWeatherWidget()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeMotionTransform();
|
||||
_hourlyTempBlocks =
|
||||
[
|
||||
HourlyTemp0, HourlyTemp1, HourlyTemp2, HourlyTemp3, HourlyTemp4, HourlyTemp5
|
||||
@@ -74,21 +78,9 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
ConfigureTextOverflowGuards();
|
||||
_refreshTimer.Tick += OnRefreshTimerTick;
|
||||
_animationTimer.Tick += OnAnimationTick;
|
||||
AttachedToVisualTree += (_, _) =>
|
||||
{
|
||||
_isAttached = true;
|
||||
_refreshTimer.Start();
|
||||
_animationTimer.Start();
|
||||
_ = RefreshWeatherAsync(false);
|
||||
};
|
||||
DetachedFromVisualTree += (_, _) =>
|
||||
{
|
||||
_isAttached = false;
|
||||
_refreshTimer.Stop();
|
||||
_animationTimer.Stop();
|
||||
CancelRefresh();
|
||||
};
|
||||
SizeChanged += (_, _) => ApplyCellSize(_currentCellSize);
|
||||
AttachedToVisualTree += OnAttachedToVisualTree;
|
||||
DetachedFromVisualTree += OnDetachedFromVisualTree;
|
||||
SizeChanged += OnSizeChanged;
|
||||
ApplyCellSize(_currentCellSize);
|
||||
ApplyVisualTheme(_activeVisualKind);
|
||||
ApplyFallback();
|
||||
@@ -159,7 +151,20 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
|
||||
{
|
||||
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;
|
||||
if (_isAttached)
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDesktopPageContext(bool isOnActivePage, bool isEditMode)
|
||||
{
|
||||
_ = isEditMode;
|
||||
var wasOnActivePage = _isOnActivePage;
|
||||
_isOnActivePage = isOnActivePage;
|
||||
UpdateTimerState();
|
||||
|
||||
if (!wasOnActivePage && _isOnActivePage && _isAttached)
|
||||
{
|
||||
_ = RefreshWeatherAsync(false);
|
||||
}
|
||||
@@ -167,12 +172,34 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
|
||||
private void OnTimeZoneChanged(object? sender, EventArgs e)
|
||||
{
|
||||
if (_isAttached)
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = true;
|
||||
UpdateTimerState();
|
||||
if (_isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = false;
|
||||
UpdateTimerState();
|
||||
CancelRefresh();
|
||||
}
|
||||
|
||||
private void OnSizeChanged(object? sender, SizeChangedEventArgs e)
|
||||
{
|
||||
ApplyCellSize(_currentCellSize);
|
||||
}
|
||||
|
||||
private async void OnRefreshTimerTick(object? sender, EventArgs e)
|
||||
{
|
||||
await RefreshWeatherAsync(false);
|
||||
@@ -180,18 +207,16 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
|
||||
private void OnAnimationTick(object? sender, EventArgs e)
|
||||
{
|
||||
if (!_isAttached || !_isOnActivePage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_phase += 0.018;
|
||||
if (_phase > Math.PI * 2) _phase -= Math.PI * 2;
|
||||
var sin = Math.Sin(_phase);
|
||||
var cos = Math.Cos(_phase * 0.83);
|
||||
BackgroundMotionLayer.RenderTransform = new TransformGroup
|
||||
{
|
||||
Children = new Transforms
|
||||
{
|
||||
new ScaleTransform(1.05 + (sin * 0.01), 1.05 + (sin * 0.01)),
|
||||
new TranslateTransform(sin * 7.0, cos * 5.0)
|
||||
}
|
||||
};
|
||||
SetMotionTransform(sin * 7.0, cos * 5.0, 1.05 + (sin * 0.01));
|
||||
BackgroundMotionLayer.Opacity = Math.Clamp(0.27 + (cos * 0.05), 0.10, 0.90);
|
||||
BackgroundLightLayer.Opacity = Math.Clamp(0.62 + (sin * 0.06), 0.20, 0.95);
|
||||
BackgroundShadeLayer.Opacity = Math.Clamp(0.80 + (cos * 0.03), 0.45, 0.95);
|
||||
@@ -199,7 +224,7 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
|
||||
private async Task RefreshWeatherAsync(bool forceRefresh)
|
||||
{
|
||||
if (!_isAttached || _isRefreshing)
|
||||
if (!_isAttached || !_isOnActivePage || _isRefreshing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -821,6 +846,48 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
|
||||
private string L(string key, string fallback) => _localizationService.GetString(_languageCode, key, fallback);
|
||||
|
||||
private void InitializeMotionTransform()
|
||||
{
|
||||
BackgroundMotionLayer.RenderTransform = new TransformGroup
|
||||
{
|
||||
Children = new Transforms
|
||||
{
|
||||
_backgroundMotionScaleTransform,
|
||||
_backgroundMotionTranslateTransform
|
||||
}
|
||||
};
|
||||
SetMotionTransform(0, 0, 1.05);
|
||||
}
|
||||
|
||||
private void SetMotionTransform(double translateX, double translateY, double scale)
|
||||
{
|
||||
_backgroundMotionScaleTransform.ScaleX = scale;
|
||||
_backgroundMotionScaleTransform.ScaleY = scale;
|
||||
_backgroundMotionTranslateTransform.X = translateX;
|
||||
_backgroundMotionTranslateTransform.Y = translateY;
|
||||
}
|
||||
|
||||
private void UpdateTimerState()
|
||||
{
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
if (!_refreshTimer.IsEnabled)
|
||||
{
|
||||
_refreshTimer.Start();
|
||||
}
|
||||
|
||||
if (!_animationTimer.IsEnabled)
|
||||
{
|
||||
_animationTimer.Start();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_refreshTimer.Stop();
|
||||
_animationTimer.Stop();
|
||||
}
|
||||
|
||||
private void CancelRefresh()
|
||||
{
|
||||
var cts = Interlocked.Exchange(ref _refreshCts, null);
|
||||
|
||||
@@ -16,7 +16,7 @@ using LanMountainDesktop.Services;
|
||||
|
||||
namespace LanMountainDesktop.Views.Components;
|
||||
|
||||
public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
|
||||
public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
|
||||
{
|
||||
private enum WeatherVisualKind
|
||||
{
|
||||
@@ -99,6 +99,8 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
private readonly List<Border> _particleVisuals = new();
|
||||
private readonly List<ParticleState> _particleStates = new();
|
||||
private readonly Random _particleRandom = new();
|
||||
private readonly ScaleTransform _backgroundMotionScaleTransform = new(1, 1);
|
||||
private readonly TranslateTransform _backgroundMotionTranslateTransform = new();
|
||||
|
||||
private IWeatherInfoService _weatherInfoService = DefaultWeatherInfoService;
|
||||
private TimeZoneService? _timeZoneService;
|
||||
@@ -110,6 +112,7 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
private double _animationPhase;
|
||||
private int _activeParticleCount;
|
||||
private bool _isAttached;
|
||||
private bool _isOnActivePage = true;
|
||||
private bool _isRefreshing;
|
||||
private readonly TextBlock[] _hourlyTimeBlocks;
|
||||
private readonly Image[] _hourlyIconBlocks;
|
||||
@@ -118,6 +121,7 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
public HourlyWeatherWidget()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeMotionTransform();
|
||||
_hourlyTimeBlocks =
|
||||
[
|
||||
HourlyTime0, HourlyTime1, HourlyTime2, HourlyTime3, HourlyTime4, HourlyTime5
|
||||
@@ -200,7 +204,20 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
|
||||
{
|
||||
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;
|
||||
if (_isAttached)
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDesktopPageContext(bool isOnActivePage, bool isEditMode)
|
||||
{
|
||||
_ = isEditMode;
|
||||
var wasOnActivePage = _isOnActivePage;
|
||||
_isOnActivePage = isOnActivePage;
|
||||
UpdateTimerState();
|
||||
|
||||
if (!wasOnActivePage && _isOnActivePage && _isAttached)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
@@ -231,16 +248,17 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = true;
|
||||
_refreshTimer.Start();
|
||||
_backgroundAnimationTimer.Start();
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
UpdateTimerState();
|
||||
if (_isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = false;
|
||||
_refreshTimer.Stop();
|
||||
_backgroundAnimationTimer.Stop();
|
||||
UpdateTimerState();
|
||||
CancelRefreshRequest();
|
||||
}
|
||||
|
||||
@@ -257,7 +275,7 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
|
||||
private void OnBackgroundAnimationTick(object? sender, EventArgs e)
|
||||
{
|
||||
if (!_isAttached)
|
||||
if (!_isAttached || !_isOnActivePage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -320,7 +338,7 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
|
||||
private async Task RefreshWeatherAsync(bool forceRefresh)
|
||||
{
|
||||
if (!_isAttached || _isRefreshing)
|
||||
if (!_isAttached || !_isOnActivePage || _isRefreshing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1339,15 +1357,43 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
||||
|
||||
private void SetMotionTransform(double translateX, double translateY, double scale)
|
||||
{
|
||||
var group = new TransformGroup
|
||||
_backgroundMotionScaleTransform.ScaleX = scale;
|
||||
_backgroundMotionScaleTransform.ScaleY = scale;
|
||||
_backgroundMotionTranslateTransform.X = translateX;
|
||||
_backgroundMotionTranslateTransform.Y = translateY;
|
||||
}
|
||||
|
||||
private void InitializeMotionTransform()
|
||||
{
|
||||
BackgroundMotionLayer.RenderTransform = new TransformGroup
|
||||
{
|
||||
Children = new Transforms
|
||||
{
|
||||
new ScaleTransform(scale, scale),
|
||||
new TranslateTransform(translateX, translateY)
|
||||
_backgroundMotionScaleTransform,
|
||||
_backgroundMotionTranslateTransform
|
||||
}
|
||||
};
|
||||
BackgroundMotionLayer.RenderTransform = group;
|
||||
}
|
||||
|
||||
private void UpdateTimerState()
|
||||
{
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
if (!_refreshTimer.IsEnabled)
|
||||
{
|
||||
_refreshTimer.Start();
|
||||
}
|
||||
|
||||
if (!_backgroundAnimationTimer.IsEnabled)
|
||||
{
|
||||
_backgroundAnimationTimer.Start();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_refreshTimer.Stop();
|
||||
_backgroundAnimationTimer.Stop();
|
||||
}
|
||||
|
||||
private void InitializeParticleVisuals()
|
||||
|
||||
@@ -14,7 +14,7 @@ using LanMountainDesktop.Services;
|
||||
|
||||
namespace LanMountainDesktop.Views.Components;
|
||||
|
||||
public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
|
||||
public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
|
||||
{
|
||||
private enum WeatherVisualKind
|
||||
{
|
||||
@@ -97,6 +97,8 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
private readonly List<Border> _particleVisuals = new();
|
||||
private readonly List<ParticleState> _particleStates = new();
|
||||
private readonly Random _particleRandom = new();
|
||||
private readonly ScaleTransform _backgroundMotionScaleTransform = new(1, 1);
|
||||
private readonly TranslateTransform _backgroundMotionTranslateTransform = new();
|
||||
|
||||
private IWeatherInfoService _weatherInfoService = DefaultWeatherInfoService;
|
||||
private TimeZoneService? _timeZoneService;
|
||||
@@ -108,6 +110,7 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
private double _animationPhase;
|
||||
private int _activeParticleCount;
|
||||
private bool _isAttached;
|
||||
private bool _isOnActivePage = true;
|
||||
private bool _isRefreshing;
|
||||
private readonly TextBlock[] _hourlyTimeBlocks;
|
||||
private readonly Image[] _hourlyIconBlocks;
|
||||
@@ -116,6 +119,7 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
public MultiDayWeatherWidget()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeMotionTransform();
|
||||
_hourlyTimeBlocks =
|
||||
[
|
||||
HourlyTime0, HourlyTime1, HourlyTime2, HourlyTime3, HourlyTime4
|
||||
@@ -198,7 +202,20 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
|
||||
{
|
||||
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;
|
||||
if (_isAttached)
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDesktopPageContext(bool isOnActivePage, bool isEditMode)
|
||||
{
|
||||
_ = isEditMode;
|
||||
var wasOnActivePage = _isOnActivePage;
|
||||
_isOnActivePage = isOnActivePage;
|
||||
UpdateTimerState();
|
||||
|
||||
if (!wasOnActivePage && _isOnActivePage && _isAttached)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
@@ -229,16 +246,17 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = true;
|
||||
_refreshTimer.Start();
|
||||
_backgroundAnimationTimer.Start();
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
UpdateTimerState();
|
||||
if (_isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = false;
|
||||
_refreshTimer.Stop();
|
||||
_backgroundAnimationTimer.Stop();
|
||||
UpdateTimerState();
|
||||
CancelRefreshRequest();
|
||||
}
|
||||
|
||||
@@ -255,7 +273,7 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
|
||||
private void OnBackgroundAnimationTick(object? sender, EventArgs e)
|
||||
{
|
||||
if (!_isAttached)
|
||||
if (!_isAttached || !_isOnActivePage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -318,7 +336,7 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
|
||||
private async Task RefreshWeatherAsync(bool forceRefresh)
|
||||
{
|
||||
if (!_isAttached || _isRefreshing)
|
||||
if (!_isAttached || !_isOnActivePage || _isRefreshing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1189,15 +1207,43 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
||||
|
||||
private void SetMotionTransform(double translateX, double translateY, double scale)
|
||||
{
|
||||
var group = new TransformGroup
|
||||
_backgroundMotionScaleTransform.ScaleX = scale;
|
||||
_backgroundMotionScaleTransform.ScaleY = scale;
|
||||
_backgroundMotionTranslateTransform.X = translateX;
|
||||
_backgroundMotionTranslateTransform.Y = translateY;
|
||||
}
|
||||
|
||||
private void InitializeMotionTransform()
|
||||
{
|
||||
BackgroundMotionLayer.RenderTransform = new TransformGroup
|
||||
{
|
||||
Children = new Transforms
|
||||
{
|
||||
new ScaleTransform(scale, scale),
|
||||
new TranslateTransform(translateX, translateY)
|
||||
_backgroundMotionScaleTransform,
|
||||
_backgroundMotionTranslateTransform
|
||||
}
|
||||
};
|
||||
BackgroundMotionLayer.RenderTransform = group;
|
||||
}
|
||||
|
||||
private void UpdateTimerState()
|
||||
{
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
if (!_refreshTimer.IsEnabled)
|
||||
{
|
||||
_refreshTimer.Start();
|
||||
}
|
||||
|
||||
if (!_backgroundAnimationTimer.IsEnabled)
|
||||
{
|
||||
_backgroundAnimationTimer.Start();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_refreshTimer.Stop();
|
||||
_backgroundAnimationTimer.Stop();
|
||||
}
|
||||
|
||||
private void InitializeParticleVisuals()
|
||||
|
||||
@@ -17,7 +17,7 @@ using LanMountainDesktop.Theme;
|
||||
|
||||
namespace LanMountainDesktop.Views.Components;
|
||||
|
||||
public partial class MusicControlWidget : UserControl, IDesktopComponentWidget
|
||||
public partial class MusicControlWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget
|
||||
{
|
||||
private const Symbol PlaySymbol = Symbol.Play;
|
||||
private const Symbol PauseSymbol = Symbol.Pause;
|
||||
@@ -38,6 +38,7 @@ public partial class MusicControlWidget : UserControl, IDesktopComponentWidget
|
||||
private string _languageCode = "zh-CN";
|
||||
private double _currentCellSize = 48;
|
||||
private bool _isAttached;
|
||||
private bool _isOnActivePage = true;
|
||||
private bool _isRefreshing;
|
||||
private bool _isExecutingCommand;
|
||||
private double _progressRatio;
|
||||
@@ -126,17 +127,33 @@ public partial class MusicControlWidget : UserControl, IDesktopComponentWidget
|
||||
UpdateProgressVisual(_progressRatio, _isProgressIndeterminate);
|
||||
}
|
||||
|
||||
public void SetDesktopPageContext(bool isOnActivePage, bool isEditMode)
|
||||
{
|
||||
_ = isEditMode;
|
||||
var wasOnActivePage = _isOnActivePage;
|
||||
_isOnActivePage = isOnActivePage;
|
||||
UpdateRefreshTimerState();
|
||||
|
||||
if (!wasOnActivePage && _isOnActivePage && _isAttached)
|
||||
{
|
||||
_ = RefreshStateAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = true;
|
||||
_refreshTimer.Start();
|
||||
_ = RefreshStateAsync();
|
||||
UpdateRefreshTimerState();
|
||||
if (_isOnActivePage)
|
||||
{
|
||||
_ = RefreshStateAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = false;
|
||||
_refreshTimer.Stop();
|
||||
UpdateRefreshTimerState();
|
||||
CancelRefreshRequest();
|
||||
DisposeCoverBitmap();
|
||||
}
|
||||
@@ -211,7 +228,7 @@ public partial class MusicControlWidget : UserControl, IDesktopComponentWidget
|
||||
|
||||
private async Task RefreshStateAsync()
|
||||
{
|
||||
if (!_isAttached || _isRefreshing)
|
||||
if (!_isAttached || !_isOnActivePage || _isRefreshing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -257,6 +274,21 @@ public partial class MusicControlWidget : UserControl, IDesktopComponentWidget
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRefreshTimerState()
|
||||
{
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
if (!_refreshTimer.IsEnabled)
|
||||
{
|
||||
_refreshTimer.Start();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_refreshTimer.Stop();
|
||||
}
|
||||
|
||||
private void ApplyState(MusicPlaybackState state)
|
||||
{
|
||||
var hasMediaSession = state.IsSupported && state.HasSession;
|
||||
|
||||
@@ -14,7 +14,7 @@ using LanMountainDesktop.Services;
|
||||
|
||||
namespace LanMountainDesktop.Views.Components;
|
||||
|
||||
public partial class RecordingWidget : UserControl, IDesktopComponentWidget
|
||||
public partial class RecordingWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget
|
||||
{
|
||||
private const int WaveBarCount = 22;
|
||||
|
||||
@@ -34,6 +34,7 @@ public partial class RecordingWidget : UserControl, IDesktopComponentWidget
|
||||
private string _lastSavedFilePath = string.Empty;
|
||||
private double _currentCellSize = 48;
|
||||
private bool _isAttached;
|
||||
private bool _isOnActivePage = true;
|
||||
private bool _pausedStudyMonitoringForRecording;
|
||||
|
||||
public RecordingWidget()
|
||||
@@ -106,10 +107,24 @@ public partial class RecordingWidget : UserControl, IDesktopComponentWidget
|
||||
UpdateWaveformVisual();
|
||||
}
|
||||
|
||||
public void SetDesktopPageContext(bool isOnActivePage, bool isEditMode)
|
||||
{
|
||||
_ = isEditMode;
|
||||
var wasOnActivePage = _isOnActivePage;
|
||||
_isOnActivePage = isOnActivePage;
|
||||
UpdateUiTimerState();
|
||||
|
||||
if (!wasOnActivePage && _isOnActivePage && _isAttached)
|
||||
{
|
||||
ReloadLanguageCode();
|
||||
RefreshVisual();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = true;
|
||||
_uiTimer.Start();
|
||||
UpdateUiTimerState();
|
||||
ReloadLanguageCode();
|
||||
RefreshVisual();
|
||||
}
|
||||
@@ -117,7 +132,7 @@ public partial class RecordingWidget : UserControl, IDesktopComponentWidget
|
||||
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = false;
|
||||
_uiTimer.Stop();
|
||||
UpdateUiTimerState();
|
||||
|
||||
var snapshot = _audioRecorderService.GetSnapshot();
|
||||
if (snapshot.State is not AudioRecorderRuntimeState.Recording and not AudioRecorderRuntimeState.Paused)
|
||||
@@ -133,7 +148,7 @@ public partial class RecordingWidget : UserControl, IDesktopComponentWidget
|
||||
|
||||
private void OnUiTick(object? sender, EventArgs e)
|
||||
{
|
||||
if (!_isAttached)
|
||||
if (!_isAttached || !_isOnActivePage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -141,6 +156,21 @@ public partial class RecordingWidget : UserControl, IDesktopComponentWidget
|
||||
RefreshVisual();
|
||||
}
|
||||
|
||||
private void UpdateUiTimerState()
|
||||
{
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
if (!_uiTimer.IsEnabled)
|
||||
{
|
||||
_uiTimer.Start();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_uiTimer.Stop();
|
||||
}
|
||||
|
||||
private void OnDiscardButtonPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
|
||||
|
||||
@@ -16,7 +16,7 @@ using LanMountainDesktop.Services;
|
||||
|
||||
namespace LanMountainDesktop.Views.Components;
|
||||
|
||||
public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
|
||||
public partial class WeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget
|
||||
{
|
||||
private enum WeatherVisualKind
|
||||
{
|
||||
@@ -93,6 +93,8 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
|
||||
private readonly List<Border> _particleVisuals = new();
|
||||
private readonly List<ParticleState> _particleStates = new();
|
||||
private readonly Random _particleRandom = new();
|
||||
private readonly ScaleTransform _backgroundMotionScaleTransform = new(1, 1);
|
||||
private readonly TranslateTransform _backgroundMotionTranslateTransform = new();
|
||||
|
||||
private IWeatherInfoService _weatherInfoService = DefaultWeatherInfoService;
|
||||
private TimeZoneService? _timeZoneService;
|
||||
@@ -104,11 +106,13 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
|
||||
private double _animationPhase;
|
||||
private int _activeParticleCount;
|
||||
private bool _isAttached;
|
||||
private bool _isOnActivePage = true;
|
||||
private bool _isRefreshing;
|
||||
|
||||
public WeatherWidget()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeMotionTransform();
|
||||
|
||||
_refreshTimer.Tick += OnRefreshTimerTick;
|
||||
_backgroundAnimationTimer.Tick += OnBackgroundAnimationTick;
|
||||
@@ -143,7 +147,20 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
|
||||
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
|
||||
{
|
||||
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;
|
||||
if (_isAttached)
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDesktopPageContext(bool isOnActivePage, bool isEditMode)
|
||||
{
|
||||
_ = isEditMode;
|
||||
var wasOnActivePage = _isOnActivePage;
|
||||
_isOnActivePage = isOnActivePage;
|
||||
UpdateTimerState();
|
||||
|
||||
if (!wasOnActivePage && _isOnActivePage && _isAttached)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
@@ -176,16 +193,17 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
|
||||
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = true;
|
||||
_refreshTimer.Start();
|
||||
_backgroundAnimationTimer.Start();
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
UpdateTimerState();
|
||||
if (_isOnActivePage)
|
||||
{
|
||||
_ = RefreshWeatherAsync(forceRefresh: false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
_isAttached = false;
|
||||
_refreshTimer.Stop();
|
||||
_backgroundAnimationTimer.Stop();
|
||||
UpdateTimerState();
|
||||
CancelRefreshRequest();
|
||||
}
|
||||
|
||||
@@ -202,7 +220,7 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
|
||||
|
||||
private void OnBackgroundAnimationTick(object? sender, EventArgs e)
|
||||
{
|
||||
if (!_isAttached)
|
||||
if (!_isAttached || !_isOnActivePage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -265,7 +283,7 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
|
||||
|
||||
private async Task RefreshWeatherAsync(bool forceRefresh)
|
||||
{
|
||||
if (!_isAttached || _isRefreshing)
|
||||
if (!_isAttached || !_isOnActivePage || _isRefreshing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -980,15 +998,43 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
|
||||
|
||||
private void SetMotionTransform(double translateX, double translateY, double scale)
|
||||
{
|
||||
var group = new TransformGroup
|
||||
_backgroundMotionScaleTransform.ScaleX = scale;
|
||||
_backgroundMotionScaleTransform.ScaleY = scale;
|
||||
_backgroundMotionTranslateTransform.X = translateX;
|
||||
_backgroundMotionTranslateTransform.Y = translateY;
|
||||
}
|
||||
|
||||
private void InitializeMotionTransform()
|
||||
{
|
||||
BackgroundMotionLayer.RenderTransform = new TransformGroup
|
||||
{
|
||||
Children = new Transforms
|
||||
{
|
||||
new ScaleTransform(scale, scale),
|
||||
new TranslateTransform(translateX, translateY)
|
||||
_backgroundMotionScaleTransform,
|
||||
_backgroundMotionTranslateTransform
|
||||
}
|
||||
};
|
||||
BackgroundMotionLayer.RenderTransform = group;
|
||||
}
|
||||
|
||||
private void UpdateTimerState()
|
||||
{
|
||||
if (_isAttached && _isOnActivePage)
|
||||
{
|
||||
if (!_refreshTimer.IsEnabled)
|
||||
{
|
||||
_refreshTimer.Start();
|
||||
}
|
||||
|
||||
if (!_backgroundAnimationTimer.IsEnabled)
|
||||
{
|
||||
_backgroundAnimationTimer.Start();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_refreshTimer.Stop();
|
||||
_backgroundAnimationTimer.Stop();
|
||||
}
|
||||
|
||||
private void InitializeParticleVisuals()
|
||||
|
||||
@@ -1906,7 +1906,7 @@ public partial class MainWindow
|
||||
}
|
||||
|
||||
SettingsPage.IsVisible = false;
|
||||
}, TimeSpan.FromMilliseconds(200));
|
||||
}, TimeSpan.FromMilliseconds(SettingsTransitionDurationMs));
|
||||
}
|
||||
|
||||
private void InitializeSettingsIcons()
|
||||
|
||||
Reference in New Issue
Block a user