添加滚动速度选项 (#710)

This commit is contained in:
Poker 2025-04-01 18:38:27 +08:00 committed by GitHub
parent e4296278e8
commit 94cd76f422
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 86 additions and 34 deletions

View File

@ -5,6 +5,7 @@ using System;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
using Windows.System;
using CommunityToolkit.WinUI.Controls;
@ -24,6 +25,23 @@ namespace Pixeval.Controls;
/// <remarks><see cref="ItemsView.ItemTemplate"/>中必须使用<see cref="ItemContainer"/>作为根元素</remarks>
public sealed partial class AdvancedItemsView : ItemsView
{
public static float ScrollRate
{
get;
set
{
field = value switch
{
< 0.1f => 0,
> 10 => 10,
_ => value
};
ScrollRateChanged?.Invoke();
}
}
private static event Action? ScrollRateChanged;
public event Func<AdvancedItemsView, EventArgs, Task<bool>> LoadMoreRequested;
/// <summary>
@ -89,12 +107,27 @@ public sealed partial class AdvancedItemsView : ItemsView
return false;
};
_scrollViewOnPropertyChangedToken = RegisterPropertyChangedCallback(ScrollViewProperty, ScrollViewOnPropertyChanged);
var itemsSourceOnPropertyChangedToken = RegisterPropertyChangedCallback(ItemsSourceProperty, ItemsSourceOnPropertyChanged);
Unloaded += (_, _) =>
_itemsSourceOnPropertyChangedToken = RegisterPropertyChangedCallback(ItemsSourceProperty, ItemsSourceOnPropertyChanged);
// 本方法之后会触发<see cref="AdvancedItemsViewOnSizeChanged"/>
Loaded += static async (sender, _) =>
{
UnregisterPropertyChangedCallback(ScrollViewProperty, _scrollViewOnPropertyChangedToken);
UnregisterPropertyChangedCallback(ItemsSourceProperty, itemsSourceOnPropertyChangedToken);
var aiv = (AdvancedItemsView) sender;
ScrollRateChanged += aiv.OnScrollRateChanged;
aiv.OnScrollRateChanged();
if (aiv.ScrollView is null || aiv._itemsRepeater != null!)
return;
aiv.ScrollView.ViewChanged += aiv.ScrollView_ViewChanged;
aiv.ScrollView.PointerWheelChanged += aiv.ScrollView_PointerWheelChanged;
aiv._itemsRepeater = aiv.ScrollView.Content.To<ItemsRepeater>();
aiv._itemsRepeater.SizeChanged += aiv.AdvancedItemsViewOnSizeChanged;
await aiv.TryRaiseLoadMoreRequestedAsync();
};
Unloaded += static (sender, _) =>
{
var aiv = (AdvancedItemsView) sender;
ScrollRateChanged -= aiv.OnScrollRateChanged;
aiv.UnregisterPropertyChangedCallback(ItemsSourceProperty, aiv._itemsSourceOnPropertyChangedToken);
};
}
@ -234,38 +267,46 @@ public sealed partial class AdvancedItemsView : ItemsView
#region EventHandlers
private readonly long _scrollViewOnPropertyChangedToken;
private readonly long _itemsSourceOnPropertyChangedToken;
/// <summary>
/// 本方法之后会触发<see cref="AdvancedItemsViewOnSizeChanged"/>
/// </summary>
private void ScrollViewOnPropertyChanged(DependencyObject sender, DependencyProperty dp)
private void OnScrollRateChanged()
{
UnregisterPropertyChangedCallback(ScrollViewProperty, _scrollViewOnPropertyChangedToken);
ScrollView.ViewChanged += ScrollView_ViewChanged;
ScrollView.PointerWheelChanged += ScrollView_PointerWheelChanged;
_itemsRepeater = ScrollView.Content.To<ItemsRepeater>();
_itemsRepeater.SizeChanged += AdvancedItemsViewOnSizeChanged;
if (ScrollView is not null)
ScrollView.IgnoredInputKinds =
ScrollRate >= 0.1 ? ScrollingInputKinds.MouseWheel : ScrollingInputKinds.None;
}
private void ScrollView_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
var scrollView = (ScrollView)sender;
var currentPoint = e.GetCurrentPoint(scrollView);
if (e.KeyModifiers is VirtualKeyModifiers.Control)
{
var offset = e.GetCurrentPoint(scrollView).Properties.MouseWheelDelta > 0 ? 20 : -20;
var offset = currentPoint.Properties.MouseWheelDelta > 0 ? 20 : -20;
if (scrollView.ComputedVerticalScrollMode is ScrollingScrollMode.Enabled && MinItemHeight + offset is var i and > 100 and < 500)
if (scrollView.ComputedVerticalScrollMode is ScrollingScrollMode.Enabled &&
MinItemHeight + offset is var i and > 100 and < 500)
MinItemHeight = i;
if (scrollView.ComputedHorizontalScrollMode is ScrollingScrollMode.Enabled && MinItemWidth + offset is var j and > 100 and < 500)
if (scrollView.ComputedHorizontalScrollMode is ScrollingScrollMode.Enabled &&
MinItemWidth + offset is var j and > 100 and < 500)
MinItemWidth = j;
}
else if (scrollView is
{
ComputedVerticalScrollMode: ScrollingScrollMode.Disabled,
ComputedHorizontalScrollMode: ScrollingScrollMode.Enabled
})
_ = scrollView.AddScrollVelocity(new(-e.GetCurrentPoint(scrollView).Properties.MouseWheelDelta, 0), null);
else
{
var rate = currentPoint.Properties.MouseWheelDelta * ScrollRate;
_ = scrollView switch
{
{
ComputedVerticalScrollMode: ScrollingScrollMode.Disabled,
ComputedHorizontalScrollMode: ScrollingScrollMode.Enabled
} => scrollView.AddScrollVelocity(new(-rate, 0), new(0.99f)),
{
ComputedVerticalScrollMode: ScrollingScrollMode.Enabled,
ComputedHorizontalScrollMode: ScrollingScrollMode.Disabled
} => scrollView.AddScrollVelocity(new(0, -rate), new(0.99f)),
_ => 0
};
}
}
private void AdvancedItemsViewOnSelectionChanged(ItemsView sender, ItemsViewSelectionChangedEventArgs e)

View File

@ -21,6 +21,7 @@ using Microsoft.UI.Xaml.Controls;
using Pixeval.Util.UI;
using Pixeval.Utilities;
using Mako.Model;
using Pixeval.Controls;
using WinUI3Utilities;
#if DEBUG
@ -54,6 +55,8 @@ public partial class App
if (AppViewModel.AppSettings.AppFontFamilyName.IsNotNullOrEmpty())
Current.Resources[ApplicationWideFontKey] = new FontFamily(AppViewModel.AppSettings.AppFontFamilyName);
AdvancedItemsView.ScrollRate = (float)AppViewModel.AppSettings.ScrollRate;
var current = AppInstance.GetCurrent();
var kind = current.GetActivatedEventArgs().Kind;
switch (kind)

View File

@ -169,6 +169,9 @@ public partial record AppSettings() : IWindowSettings
[SettingsEntry(Symbol.DismissSquareMultiple, nameof(ReconfirmationOfClosingWindowEntryHeader), nameof(ReconfirmationOfClosingWindowEntryDescription))]
public bool ReconfirmationOfClosingWindow { get; set; } = true;
[SettingsEntry(Symbol.TopSpeed, nameof(ScrollRateEntryHeader), nameof(ScrollRateEntryDescription))]
public double ScrollRate { get; set; }
[SettingsEntry(Symbol.Box, nameof(PixivNameResolverHeaderText), nameof(PixivNameResolverDescriptionText))]
public string[] PixivAppApiNameResolver { get; set; } =
[

View File

@ -18,19 +18,11 @@ using Pixeval.Options;
using Pixeval.Settings;
using Pixeval.Settings.Models;
using Pixeval.Util.ComponentModels;
using Pixeval.Util;
using Pixeval.Util.IO;
using Pixeval.Util.UI;
using Pixeval.Utilities;
using WinUI3Utilities;
using BackdropTypeExtension = Pixeval.Util.BackdropTypeExtension;
using ElementThemeExtension = Pixeval.Util.ElementThemeExtension;
using NovelRankOptionExtension = Pixeval.Util.NovelRankOptionExtension;
using RankOptionExtension = Pixeval.Util.RankOptionExtension;
using SearchIllustrationTagMatchOptionExtension = Pixeval.Util.SearchIllustrationTagMatchOptionExtension;
using SearchNovelTagMatchOptionExtension = Pixeval.Util.SearchNovelTagMatchOptionExtension;
using SimpleWorkTypeExtension = Pixeval.Util.SimpleWorkTypeExtension;
using TargetFilterExtension = Pixeval.Util.TargetFilterExtension;
using WorkSortOptionExtension = Pixeval.Util.WorkSortOptionExtension;
namespace Pixeval.Pages.Misc;
@ -133,7 +125,14 @@ public partial class SettingsPageViewModel : UiObservableObject, IDisposable
Placeholder = SettingsPageResources.BlockedTagsTokenizingTextBoxPlaceholderText
},
new BoolAppSettingsEntry(AppSettings,
t => t.BrowseOriginalImage)
t => t.BrowseOriginalImage),
new DoubleAppSettingsEntry(AppSettings,
t => t.ScrollRate)
{
Max = 10,
Min = 0,
ValueChanged = d => AdvancedItemsView.ScrollRate = (float)d
}
},
new(SettingsEntryCategory.Search)
{

View File

@ -531,6 +531,12 @@
<data name="ReconfirmationOfClosingWindowEntry.Header" xml:space="preserve">
<value>关闭窗口再次确认</value>
</data>
<data name="ScrollRateEntry.Description" xml:space="preserve">
<value>低于0.1时关闭,开启后可自定义滚动速率,但可能造成不好的体验</value>
</data>
<data name="ScrollRateEntry.Header" xml:space="preserve">
<value>滚动速率</value>
</data>
<data name="SearchSettingsGroup.Text" xml:space="preserve">
<value>搜索设置</value>
</data>