动画优化
This commit is contained in:
lincube
2026-03-05 14:03:35 +08:00
parent 2e49602bff
commit d182925b58
8 changed files with 375 additions and 85 deletions

View File

@@ -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
)

View File

@@ -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);

View File

@@ -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()

View File

@@ -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()

View File

@@ -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;

View File

@@ -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)

View File

@@ -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()

View File

@@ -1906,7 +1906,7 @@ public partial class MainWindow
}
SettingsPage.IsVisible = false;
}, TimeSpan.FromMilliseconds(200));
}, TimeSpan.FromMilliseconds(SettingsTransitionDurationMs));
}
private void InitializeSettingsIcons()