From 15e589aedd5b67b6a4b6bc6f3c839fee4fac61be Mon Sep 17 00:00:00 2001 From: lincube Date: Tue, 17 Mar 2026 18:36:10 +0800 Subject: [PATCH] 0.6.5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 流畅性优化测试 --- .../Views/MainWindow.ComponentSystem.cs | 83 ++++++++++++- .../Views/MainWindow.DesktopPaging.cs | 110 ++++++++++++++++++ .../SettingsPages/UpdateSettingsPage.axaml | 13 ++- 3 files changed, 201 insertions(+), 5 deletions(-) diff --git a/LanMountainDesktop/Views/MainWindow.ComponentSystem.cs b/LanMountainDesktop/Views/MainWindow.ComponentSystem.cs index 2118bb4..95c3fbe 100644 --- a/LanMountainDesktop/Views/MainWindow.ComponentSystem.cs +++ b/LanMountainDesktop/Views/MainWindow.ComponentSystem.cs @@ -964,6 +964,7 @@ public partial class MainWindow DisposeComponentIfNeeded(host); contentHost.Child = component; ApplyDesktopEditStateToHost(host, _isComponentLibraryOpen); + InvalidateDesktopPageAwareComponentContextCache(); UpdateDesktopPageAwareComponentContext(); if (_selectedDesktopComponentHost == host) { @@ -1102,6 +1103,7 @@ public partial class MainWindow ClearTimeZoneServiceBindings(pageGrid.Children.OfType().ToList()); pageGrid.Children.Clear(); + InvalidateDesktopPageAwareComponentContextCache(); var maxColumns = pageGrid.ColumnDefinitions.Count; var maxRows = pageGrid.RowDefinitions.Count; @@ -1204,6 +1206,7 @@ public partial class MainWindow pageGrid.Children.Add(host); _desktopComponentPlacements.Add(placement); + InvalidateDesktopPageAwareComponentContextCache(); UpdateDesktopPageAwareComponentContext(); PersistSettings(); @@ -1577,14 +1580,86 @@ public partial class MainWindow } } + private void InvalidateDesktopPageAwareComponentContextCache() + { + _desktopPageContextInitialized = false; + _desktopPageContextActiveMask = 0; + } + + private int BuildDesktopPageAwareComponentActiveMask() + { + if (_isSettingsOpen) + { + return 0; + } + + var activeMask = 0; + if (_desktopSurfacePageWidth > 1 && + _desktopPagesHostTransform is not null && + (_isDesktopSwipeActive || + _desktopPageContextSettlingSourceIndex is not null || + _desktopPageContextSettlingTargetIndex is not null)) + { + var viewportLeft = -_desktopPagesHostTransform.X; + var viewportRight = viewportLeft + _desktopSurfacePageWidth; + for (var pageIndex = 0; pageIndex < _desktopPageCount; pageIndex++) + { + var pageLeft = pageIndex * _desktopSurfacePageWidth; + var pageRight = pageLeft + _desktopSurfacePageWidth; + if (pageRight > viewportLeft + 0.5d && pageLeft < viewportRight - 0.5d) + { + activeMask |= 1 << pageIndex; + } + } + } + + if (_currentDesktopSurfaceIndex >= 0 && _currentDesktopSurfaceIndex < _desktopPageCount) + { + activeMask |= 1 << _currentDesktopSurfaceIndex; + } + + if (_desktopPageContextSettlingSourceIndex is int sourceIndex && + sourceIndex >= 0 && + sourceIndex < _desktopPageCount) + { + activeMask |= 1 << sourceIndex; + } + + if (_desktopPageContextSettlingTargetIndex is int targetIndex && + targetIndex >= 0 && + targetIndex < _desktopPageCount) + { + activeMask |= 1 << targetIndex; + } + + return activeMask; + } + private void UpdateDesktopPageAwareComponentContext() { - var activeDesktopPageIndex = _isSettingsOpen ? -1 : _currentDesktopSurfaceIndex; var isEditMode = _isComponentLibraryOpen || _isSettingsOpen; + var activeMask = BuildDesktopPageAwareComponentActiveMask(); + var pageUpdateMask = !_desktopPageContextInitialized || isEditMode != _desktopPageContextEditMode + ? _desktopPageComponentGrids.Keys.Aggregate(0, (mask, pageIndex) => mask | (1 << pageIndex)) + : activeMask ^ _desktopPageContextActiveMask; + + if (_desktopPageContextInitialized && + pageUpdateMask == 0 && + isEditMode == _desktopPageContextEditMode && + activeMask == _desktopPageContextActiveMask) + { + return; + } foreach (var pair in _desktopPageComponentGrids) { - var isOnActivePage = pair.Key == activeDesktopPageIndex; + var pageBit = 1 << pair.Key; + if ((pageUpdateMask & pageBit) == 0) + { + continue; + } + + var isOnActivePage = (activeMask & pageBit) != 0; foreach (var host in pair.Value.Children.OfType()) { if (!host.Classes.Contains(DesktopComponentHostClass)) @@ -1598,6 +1673,10 @@ public partial class MainWindow } } } + + _desktopPageContextInitialized = true; + _desktopPageContextEditMode = isEditMode; + _desktopPageContextActiveMask = activeMask; } private static void ApplyDesktopPageContext(Control root, bool isOnActivePage, bool isEditMode) diff --git a/LanMountainDesktop/Views/MainWindow.DesktopPaging.cs b/LanMountainDesktop/Views/MainWindow.DesktopPaging.cs index 8f59c3e..4ff3f0c 100644 --- a/LanMountainDesktop/Views/MainWindow.DesktopPaging.cs +++ b/LanMountainDesktop/Views/MainWindow.DesktopPaging.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using Avalonia; +using Avalonia.Animation; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; @@ -16,6 +17,7 @@ using Avalonia.VisualTree; using FluentAvalonia.UI.Controls; using LanMountainDesktop.Models; using LanMountainDesktop.Services; +using LanMountainDesktop.Theme; namespace LanMountainDesktop.Views; @@ -54,6 +56,8 @@ public partial class MainWindow private int _currentDesktopSurfaceIndex; private double _desktopSurfacePageWidth; private TranslateTransform? _desktopPagesHostTransform; + private Transitions? _desktopPagesHostSnapTransitions; + private bool _desktopPagesHostTransitionsSuspended; private bool _isDesktopSwipeActive; private bool _isDesktopSwipeDirectionLocked; private Point _desktopSwipeStartPoint; @@ -62,6 +66,12 @@ public partial class MainWindow private long _desktopSwipeLastTimestamp; private double _desktopSwipeVelocityX; private double _desktopSwipeBaseOffset; + private bool _desktopPageContextInitialized; + private bool _desktopPageContextEditMode; + private int _desktopPageContextActiveMask; + private int? _desktopPageContextSettlingSourceIndex; + private int? _desktopPageContextSettlingTargetIndex; + private int _desktopPageContextSettleRevision; private int LauncherSurfaceIndex => Math.Max(MinDesktopPageCount, _desktopPageCount); @@ -164,6 +174,15 @@ public partial class MainWindow DesktopPagesHost.RenderTransform = _desktopPagesHostTransform; } + if (_desktopPagesHostTransitionsSuspended) + { + _desktopPagesHostTransform.Transitions = null; + } + else + { + _desktopPagesHostSnapTransitions ??= _desktopPagesHostTransform.Transitions; + } + var viewportRow = gridMetrics.RowCount > 2 ? 1 : 0; var viewportRowSpan = gridMetrics.RowCount > 2 ? gridMetrics.RowCount - 2 : 1; var pageWidth = Math.Max(1, gridMetrics.GridWidthPx); @@ -200,6 +219,7 @@ public partial class MainWindow DesktopPagesContainer.Width = pageWidth * _desktopPageCount; DesktopPagesContainer.Height = pageHeight; _desktopPageComponentGrids.Clear(); + InvalidateDesktopPageAwareComponentContextCache(); for (var index = 0; index < _desktopPageCount; index++) { DesktopPagesContainer.ColumnDefinitions.Add(new ColumnDefinition(new GridLength(pageWidth, GridUnitType.Pixel))); @@ -354,6 +374,88 @@ public partial class MainWindow UpdateDesktopPageAwareComponentContext(); } + private void SetDesktopPagesHostSnapAnimationEnabled(bool enabled) + { + if (_desktopPagesHostTransform is null) + { + return; + } + + if (enabled) + { + if (!_desktopPagesHostTransitionsSuspended) + { + return; + } + + _desktopPagesHostTransform.Transitions = _desktopPagesHostSnapTransitions; + _desktopPagesHostTransitionsSuspended = false; + return; + } + + if (_desktopPagesHostTransitionsSuspended) + { + return; + } + + _desktopPagesHostSnapTransitions ??= _desktopPagesHostTransform.Transitions; + _desktopPagesHostTransform.Transitions = null; + _desktopPagesHostTransitionsSuspended = true; + } + + private void ClearDesktopPageContextSettle(bool refreshContext) + { + _desktopPageContextSettleRevision++; + _desktopPageContextSettlingSourceIndex = null; + _desktopPageContextSettlingTargetIndex = null; + + if (refreshContext) + { + UpdateDesktopPageAwareComponentContext(); + } + } + + private void BeginDesktopPageContextSettle(int previousIndex, int targetIndex) + { + var sourceIndex = previousIndex >= 0 && previousIndex < _desktopPageCount + ? previousIndex + : (int?)null; + var destinationIndex = targetIndex >= 0 && targetIndex < _desktopPageCount + ? targetIndex + : (int?)null; + + if (sourceIndex == destinationIndex && destinationIndex is not null) + { + ClearDesktopPageContextSettle(refreshContext: false); + return; + } + + if (sourceIndex is null && destinationIndex is null) + { + ClearDesktopPageContextSettle(refreshContext: false); + return; + } + + _desktopPageContextSettleRevision++; + var settleRevision = _desktopPageContextSettleRevision; + _desktopPageContextSettlingSourceIndex = sourceIndex; + _desktopPageContextSettlingTargetIndex = destinationIndex; + + DispatcherTimer.RunOnce( + () => + { + if (settleRevision != _desktopPageContextSettleRevision) + { + return; + } + + _desktopPageContextSettlingSourceIndex = null; + _desktopPageContextSettlingTargetIndex = null; + UpdateDesktopPageAwareComponentContext(); + }, + FluttermotionToken.Page + TimeSpan.FromMilliseconds(36)); + } + private void MoveSurfaceBy(int delta) { if (delta == 0) @@ -373,7 +475,9 @@ public partial class MainWindow return; } + var previousIndex = _currentDesktopSurfaceIndex; _currentDesktopSurfaceIndex = target; + BeginDesktopPageContextSettle(previousIndex, target); ApplyDesktopSurfaceOffset(); PersistSettings(); } @@ -426,6 +530,7 @@ public partial class MainWindow return; } + ClearDesktopPageContextSettle(refreshContext: false); _isDesktopSwipeActive = true; _isDesktopSwipeDirectionLocked = false; _desktopSwipeStartPoint = pointerInViewport; @@ -603,6 +708,7 @@ public partial class MainWindow } _isDesktopSwipeDirectionLocked = true; + SetDesktopPagesHostSnapAnimationEnabled(enabled: false); if (e.Pointer.Captured != DesktopPagesViewport) { e.Pointer.Capture(DesktopPagesViewport); @@ -621,6 +727,7 @@ public partial class MainWindow } _desktopPagesHostTransform.X = tentative; + UpdateDesktopPageAwareComponentContext(); e.Handled = true; } @@ -656,6 +763,7 @@ public partial class MainWindow _desktopSwipeLastTimestamp = 0; if (wasDirectionLocked) { + SetDesktopPagesHostSnapAnimationEnabled(enabled: true); ApplyDesktopSurfaceOffset(); } } @@ -682,6 +790,8 @@ public partial class MainWindow return false; } + SetDesktopPagesHostSnapAnimationEnabled(enabled: true); + var deltaX = _desktopSwipeCurrentPoint.X - _desktopSwipeStartPoint.X; var deltaY = _desktopSwipeCurrentPoint.Y - _desktopSwipeStartPoint.Y; var absDeltaX = Math.Abs(deltaX); diff --git a/LanMountainDesktop/Views/SettingsPages/UpdateSettingsPage.axaml b/LanMountainDesktop/Views/SettingsPages/UpdateSettingsPage.axaml index 5f06263..c778d87 100644 --- a/LanMountainDesktop/Views/SettingsPages/UpdateSettingsPage.axaml +++ b/LanMountainDesktop/Views/SettingsPages/UpdateSettingsPage.axaml @@ -70,9 +70,11 @@ - @@ -80,7 +82,8 @@ Text="{Binding CurrentVersionText}" /> - - +