Skip to content

Commit 1e17615

Browse files
authored
Merge pull request #4201 from Flow-Launcher/revert-4118-UI.WPF.Modern
Revert "Upgrade iNKORE.UI.WPF.Modern and refactor scroll logic"
2 parents 27c4d35 + 604fd2b commit 1e17615

File tree

4 files changed

+264
-13
lines changed

4 files changed

+264
-13
lines changed

Flow.Launcher/Flow.Launcher.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
<PrivateAssets>all</PrivateAssets>
139139
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
140140
</PackageReference>
141-
<PackageReference Include="iNKORE.UI.WPF.Modern" Version="0.10.2.1" />
141+
<PackageReference Include="iNKORE.UI.WPF.Modern" Version="0.10.1" />
142142
<PackageReference Include="MdXaml" Version="1.27.0" />
143143
<PackageReference Include="MdXaml.AnimatedGif" Version="1.27.0" />
144144
<PackageReference Include="MdXaml.Html" Version="1.27.0" />
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
using iNKORE.UI.WPF.Modern.Controls;
2+
using iNKORE.UI.WPF.Modern.Controls.Helpers;
3+
using iNKORE.UI.WPF.Modern.Controls.Primitives;
4+
using System;
5+
using System.Windows;
6+
using System.Windows.Controls;
7+
using System.Windows.Input;
8+
9+
namespace Flow.Launcher.Resources.Controls
10+
{
11+
// TODO: Use IsScrollAnimationEnabled property in future: https://github.com/iNKORE-NET/UI.WPF.Modern/pull/347
12+
public class CustomScrollViewerEx : ScrollViewer
13+
{
14+
private double LastVerticalLocation = 0;
15+
private double LastHorizontalLocation = 0;
16+
17+
public CustomScrollViewerEx()
18+
{
19+
Loaded += OnLoaded;
20+
var valueSource = DependencyPropertyHelper.GetValueSource(this, AutoPanningMode.IsEnabledProperty).BaseValueSource;
21+
if (valueSource == BaseValueSource.Default)
22+
{
23+
AutoPanningMode.SetIsEnabled(this, true);
24+
}
25+
}
26+
27+
#region Orientation
28+
29+
public static readonly DependencyProperty OrientationProperty =
30+
DependencyProperty.Register(
31+
nameof(Orientation),
32+
typeof(Orientation),
33+
typeof(CustomScrollViewerEx),
34+
new PropertyMetadata(Orientation.Vertical));
35+
36+
public Orientation Orientation
37+
{
38+
get => (Orientation)GetValue(OrientationProperty);
39+
set => SetValue(OrientationProperty, value);
40+
}
41+
42+
#endregion
43+
44+
#region AutoHideScrollBars
45+
46+
public static readonly DependencyProperty AutoHideScrollBarsProperty =
47+
ScrollViewerHelper.AutoHideScrollBarsProperty
48+
.AddOwner(
49+
typeof(CustomScrollViewerEx),
50+
new PropertyMetadata(true, OnAutoHideScrollBarsChanged));
51+
52+
public bool AutoHideScrollBars
53+
{
54+
get => (bool)GetValue(AutoHideScrollBarsProperty);
55+
set => SetValue(AutoHideScrollBarsProperty, value);
56+
}
57+
58+
private static void OnAutoHideScrollBarsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
59+
{
60+
if (d is CustomScrollViewerEx sv)
61+
{
62+
sv.UpdateVisualState();
63+
}
64+
}
65+
66+
#endregion
67+
68+
private void OnLoaded(object sender, RoutedEventArgs e)
69+
{
70+
LastVerticalLocation = VerticalOffset;
71+
LastHorizontalLocation = HorizontalOffset;
72+
UpdateVisualState(false);
73+
}
74+
75+
/// <inheritdoc/>
76+
protected override void OnInitialized(EventArgs e)
77+
{
78+
base.OnInitialized(e);
79+
80+
if (Style == null && ReadLocalValue(StyleProperty) == DependencyProperty.UnsetValue)
81+
{
82+
SetResourceReference(StyleProperty, typeof(ScrollViewer));
83+
}
84+
}
85+
86+
/// <inheritdoc/>
87+
protected override void OnMouseWheel(MouseWheelEventArgs e)
88+
{
89+
var Direction = GetDirection();
90+
ScrollViewerBehavior.SetIsAnimating(this, true);
91+
92+
if (Direction == Orientation.Vertical)
93+
{
94+
if (ScrollableHeight > 0)
95+
{
96+
e.Handled = true;
97+
}
98+
99+
var WheelChange = e.Delta * (ViewportHeight / 1.5) / ActualHeight;
100+
var newOffset = LastVerticalLocation - WheelChange;
101+
102+
if (newOffset < 0)
103+
{
104+
newOffset = 0;
105+
}
106+
107+
if (newOffset > ScrollableHeight)
108+
{
109+
newOffset = ScrollableHeight;
110+
}
111+
112+
if (newOffset == LastVerticalLocation)
113+
{
114+
return;
115+
}
116+
117+
ScrollToVerticalOffset(LastVerticalLocation);
118+
119+
ScrollToValue(newOffset, Direction);
120+
LastVerticalLocation = newOffset;
121+
}
122+
else
123+
{
124+
if (ScrollableWidth > 0)
125+
{
126+
e.Handled = true;
127+
}
128+
129+
var WheelChange = e.Delta * (ViewportWidth / 1.5) / ActualWidth;
130+
var newOffset = LastHorizontalLocation - WheelChange;
131+
132+
if (newOffset < 0)
133+
{
134+
newOffset = 0;
135+
}
136+
137+
if (newOffset > ScrollableWidth)
138+
{
139+
newOffset = ScrollableWidth;
140+
}
141+
142+
if (newOffset == LastHorizontalLocation)
143+
{
144+
return;
145+
}
146+
147+
ScrollToHorizontalOffset(LastHorizontalLocation);
148+
149+
ScrollToValue(newOffset, Direction);
150+
LastHorizontalLocation = newOffset;
151+
}
152+
}
153+
154+
/// <inheritdoc/>
155+
protected override void OnScrollChanged(ScrollChangedEventArgs e)
156+
{
157+
base.OnScrollChanged(e);
158+
if (!ScrollViewerBehavior.GetIsAnimating(this))
159+
{
160+
LastVerticalLocation = VerticalOffset;
161+
LastHorizontalLocation = HorizontalOffset;
162+
}
163+
}
164+
165+
private Orientation GetDirection()
166+
{
167+
var isShiftDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
168+
169+
if (Orientation == Orientation.Horizontal)
170+
{
171+
return isShiftDown ? Orientation.Vertical : Orientation.Horizontal;
172+
}
173+
else
174+
{
175+
return isShiftDown ? Orientation.Horizontal : Orientation.Vertical;
176+
}
177+
}
178+
179+
/// <summary>
180+
/// Causes the <see cref="ScrollViewerEx"/> to load a new view into the viewport using the specified offsets and zoom factor.
181+
/// </summary>
182+
/// <param name="horizontalOffset">A value between 0 and <see cref="ScrollViewer.ScrollableWidth"/> that specifies the distance the content should be scrolled horizontally.</param>
183+
/// <param name="verticalOffset">A value between 0 and <see cref="ScrollViewer.ScrollableHeight"/> that specifies the distance the content should be scrolled vertically.</param>
184+
/// <param name="zoomFactor">A value between MinZoomFactor and MaxZoomFactor that specifies the required target ZoomFactor.</param>
185+
/// <returns><see langword="true"/> if the view is changed; otherwise, <see langword="false"/>.</returns>
186+
public bool ChangeView(double? horizontalOffset, double? verticalOffset, float? zoomFactor)
187+
{
188+
return ChangeView(horizontalOffset, verticalOffset, zoomFactor, false);
189+
}
190+
191+
/// <summary>
192+
/// Causes the <see cref="ScrollViewerEx"/> to load a new view into the viewport using the specified offsets and zoom factor, and optionally disables scrolling animation.
193+
/// </summary>
194+
/// <param name="horizontalOffset">A value between 0 and <see cref="ScrollViewer.ScrollableWidth"/> that specifies the distance the content should be scrolled horizontally.</param>
195+
/// <param name="verticalOffset">A value between 0 and <see cref="ScrollViewer.ScrollableHeight"/> that specifies the distance the content should be scrolled vertically.</param>
196+
/// <param name="zoomFactor">A value between MinZoomFactor and MaxZoomFactor that specifies the required target ZoomFactor.</param>
197+
/// <param name="disableAnimation"><see langword="true"/> to disable zoom/pan animations while changing the view; otherwise, <see langword="false"/>. The default is false.</param>
198+
/// <returns><see langword="true"/> if the view is changed; otherwise, <see langword="false"/>.</returns>
199+
public bool ChangeView(double? horizontalOffset, double? verticalOffset, float? zoomFactor, bool disableAnimation)
200+
{
201+
if (disableAnimation)
202+
{
203+
if (horizontalOffset.HasValue)
204+
{
205+
ScrollToHorizontalOffset(horizontalOffset.Value);
206+
}
207+
208+
if (verticalOffset.HasValue)
209+
{
210+
ScrollToVerticalOffset(verticalOffset.Value);
211+
}
212+
}
213+
else
214+
{
215+
if (horizontalOffset.HasValue)
216+
{
217+
ScrollToHorizontalOffset(LastHorizontalLocation);
218+
ScrollToValue(Math.Min(ScrollableWidth, horizontalOffset.Value), Orientation.Horizontal);
219+
LastHorizontalLocation = horizontalOffset.Value;
220+
}
221+
222+
if (verticalOffset.HasValue)
223+
{
224+
ScrollToVerticalOffset(LastVerticalLocation);
225+
ScrollToValue(Math.Min(ScrollableHeight, verticalOffset.Value), Orientation.Vertical);
226+
LastVerticalLocation = verticalOffset.Value;
227+
}
228+
}
229+
230+
return true;
231+
}
232+
233+
private void ScrollToValue(double value, Orientation Direction)
234+
{
235+
if (Direction == Orientation.Vertical)
236+
{
237+
ScrollToVerticalOffset(value);
238+
}
239+
else
240+
{
241+
ScrollToHorizontalOffset(value);
242+
}
243+
244+
ScrollViewerBehavior.SetIsAnimating(this, false);
245+
}
246+
247+
private void UpdateVisualState(bool useTransitions = true)
248+
{
249+
var stateName = AutoHideScrollBars ? "NoIndicator" : "MouseIndicator";
250+
VisualStateManager.GoToState(this, stateName, useTransitions);
251+
}
252+
}
253+
}

Flow.Launcher/Themes/Base.xaml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,14 +252,12 @@
252252
<Setter Property="Template">
253253
<Setter.Value>
254254
<ControlTemplate TargetType="ListBox">
255-
<ui:ScrollViewerEx
255+
<cc:CustomScrollViewerEx
256256
x:Name="ListBoxScrollViewer"
257257
Focusable="False"
258-
IsScrollAnimationEnabled="False"
259-
RewriteWheelChange="True"
260258
Template="{DynamicResource ScrollViewerControlTemplate}">
261-
<ui:ScrollViewerEx.Style>
262-
<Style TargetType="ui:ScrollViewerEx">
259+
<cc:CustomScrollViewerEx.Style>
260+
<Style TargetType="cc:CustomScrollViewerEx">
263261
<Style.Triggers>
264262
<Trigger Property="ComputedVerticalScrollBarVisibility" Value="Visible">
265263
<Setter Property="Margin" Value="0 0 0 0" />
@@ -271,9 +269,9 @@
271269
</Trigger>
272270
</Style.Triggers>
273271
</Style>
274-
</ui:ScrollViewerEx.Style>
272+
</cc:CustomScrollViewerEx.Style>
275273
<VirtualizingStackPanel IsItemsHost="True" />
276-
</ui:ScrollViewerEx>
274+
</cc:CustomScrollViewerEx>
277275
</ControlTemplate>
278276
</Setter.Value>
279277
</Setter>

Flow.Launcher/packages.lock.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
},
2929
"iNKORE.UI.WPF.Modern": {
3030
"type": "Direct",
31-
"requested": "[0.10.2.1, )",
32-
"resolved": "0.10.2.1",
33-
"contentHash": "nGwuuVul+TcLCTgPmaAZCc0fYFqUpCNZ8PiulVT3gZnsWt/AvxMZ0DSPpuyI/iRPc/NhFIg9lSIR7uaHWV0I/Q==",
31+
"requested": "[0.10.1, )",
32+
"resolved": "0.10.1",
33+
"contentHash": "nRYmBosiL+42eUpLbHeqP7qJqtp5EpzuIMZTpvq4mFV33VB/JjkFg1y82gk50pjkXlAQWDvRyrfSAmPR5AM+3g==",
3434
"dependencies": {
3535
"iNKORE.UI.WPF": "1.2.8"
3636
}
@@ -1619,7 +1619,7 @@
16191619
"FSharp.Core": "[9.0.303, )",
16201620
"Flow.Launcher.Infrastructure": "[1.0.0, )",
16211621
"Flow.Launcher.Localization": "[0.0.6, )",
1622-
"Flow.Launcher.Plugin": "[5.1.0, )",
1622+
"Flow.Launcher.Plugin": "[5.0.0, )",
16231623
"Meziantou.Framework.Win32.Jobs": "[3.4.5, )",
16241624
"Microsoft.IO.RecyclableMemoryStream": "[3.0.1, )",
16251625
"SemanticVersioning": "[3.0.0, )",
@@ -1634,7 +1634,7 @@
16341634
"BitFaster.Caching": "[2.5.4, )",
16351635
"CommunityToolkit.Mvvm": "[8.4.0, )",
16361636
"Flow.Launcher.Localization": "[0.0.6, )",
1637-
"Flow.Launcher.Plugin": "[5.1.0, )",
1637+
"Flow.Launcher.Plugin": "[5.0.0, )",
16381638
"InputSimulator": "[1.0.4, )",
16391639
"MemoryPack": "[1.21.4, )",
16401640
"Microsoft.VisualStudio.Threading": "[17.14.15, )",

0 commit comments

Comments
 (0)