Browse Source

Merge pull request #11051 from AvaloniaUI/fixes/11015-slider-thumb-not-moving

Fix slider thumb not moving
pull/11072/head
Steven Kirk 4 years ago
committed by GitHub
parent
commit
8365163f58
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 17
      samples/IntegrationTestApp/MainWindow.axaml
  2. 2
      samples/IntegrationTestApp/MainWindow.axaml.cs
  3. 9
      src/Avalonia.Base/Layout/LayoutManager.cs
  4. 12
      src/Avalonia.Controls/Automation/Peers/ThumbAutomationPeer.cs
  5. 4
      src/Avalonia.Controls/Primitives/Thumb.cs
  6. 34
      tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs
  7. 2
      tests/Avalonia.IntegrationTests.Appium/ScrollBarTests.cs
  8. 89
      tests/Avalonia.IntegrationTests.Appium/SliderTests.cs

17
samples/IntegrationTestApp/MainWindow.axaml

@ -170,10 +170,21 @@
</StackPanel>
</Grid>
</TabItem>
<TabItem Header="SliderTab">
<Slider VerticalAlignment="Top" Name="Slider" Value="30"/>
<TabItem Header="Slider">
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<TextBox Name="HorizontalSliderValue"
DockPanel.Dock="Right"
Text="{Binding #HorizontalSlider.Value, Mode=OneWay, StringFormat=\{0:0\}}"
VerticalAlignment="Top"/>
<Slider Name="HorizontalSlider" Value="50"/>
</DockPanel>
<Button Name="ResetSliders">Reset</Button>
</DockPanel>
</TabItem>
<TabItem Header="ScrollBarTab">
<TabItem Header="ScrollBar">
<ScrollBar Name="MyScrollBar" Orientation="Horizontal" AllowAutoHide="False" Width="200" Height="30" Value="20"/>
</TabItem>
</TabControl>

2
samples/IntegrationTestApp/MainWindow.axaml.cs

@ -270,6 +270,8 @@ namespace IntegrationTestApp
this.Get<ListBox>("BasicListBox").SelectedIndex = -1;
if (source?.Name == "MenuClickedMenuItemReset")
this.Get<TextBlock>("ClickedMenuItem").Text = "None";
if (source?.Name == "ResetSliders")
this.Get<Slider>("HorizontalSlider").Value = 50;
if (source?.Name == "ShowTransparentWindow")
ShowTransparentWindow();
if (source?.Name == "ShowTransparentPopup")

9
src/Avalonia.Base/Layout/LayoutManager.cs

@ -2,6 +2,7 @@ using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Avalonia.Logging;
using Avalonia.Rendering;
using Avalonia.Threading;
@ -64,7 +65,6 @@ namespace Avalonia.Layout
}
_toMeasure.Enqueue(control);
_toArrange.Enqueue(control);
QueueLayoutPass();
}
@ -297,6 +297,8 @@ namespace Avalonia.Layout
{
control.Measure(control.PreviousMeasure.Value);
}
_toArrange.Enqueue(control);
}
return true;
@ -313,7 +315,10 @@ namespace Avalonia.Layout
return false;
}
if (control.IsMeasureValid && !control.IsArrangeValid)
if (!control.IsMeasureValid)
return false;
if (!control.IsArrangeValid)
{
if (control is IEmbeddedLayoutRoot embeddedRoot)
control.Arrange(new Rect(embeddedRoot.AllocatedSize));

12
src/Avalonia.Controls/Automation/Peers/ThumbAutomationPeer.cs

@ -0,0 +1,12 @@
using Avalonia.Automation.Peers;
using Avalonia.Controls.Primitives;
namespace Avalonia.Controls.Automation.Peers
{
public class ThumbAutomationPeer : ControlAutomationPeer
{
public ThumbAutomationPeer(Thumb owner) : base(owner) { }
protected override AutomationControlType GetAutomationControlTypeCore() => AutomationControlType.Thumb;
protected override bool IsContentElementCore() => false;
}
}

4
src/Avalonia.Controls/Primitives/Thumb.cs

@ -1,4 +1,6 @@
using System;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Automation.Peers;
using Avalonia.Controls.Metadata;
using Avalonia.Input;
using Avalonia.Interactivity;
@ -45,6 +47,8 @@ namespace Avalonia.Controls.Primitives
remove { RemoveHandler(DragCompletedEvent, value); }
}
protected override AutomationPeer OnCreateAutomationPeer() => new ThumbAutomationPeer(this);
protected virtual void OnDragStarted(VectorEventArgs e)
{
}

34
tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs

@ -457,5 +457,39 @@ namespace Avalonia.Base.UnitTests.Layout
Assert.Equal(1, layoutCount);
}
[Fact]
public void Child_Can_Invalidate_Parent_Measure_During_Arrange()
{
// Issue #11015.
//
// - Child invalidates parent measure in arrange pass
// - Parent is added to measure & arrange queues
// - Arrange pass dequeues parent
// - Measure is not valid so parent is not arranged
// - Parent is measured
// - Parent has been dequeued from arrange queue so no arrange is performed
var child = new LayoutTestControl();
var parent = new LayoutTestControl { Child = child };
var root = new LayoutTestRoot { Child = parent };
root.LayoutManager.ExecuteInitialLayoutPass();
child.DoArrangeOverride = (_, s) =>
{
parent.InvalidateMeasure();
return s;
};
child.InvalidateMeasure();
parent.InvalidateMeasure();
root.LayoutManager.ExecuteLayoutPass();
Assert.True(child.IsMeasureValid);
Assert.True(child.IsArrangeValid);
Assert.True(parent.IsMeasureValid);
Assert.True(parent.IsArrangeValid);
}
}
}

2
tests/Avalonia.IntegrationTests.Appium/ScrollBarTests.cs

@ -13,7 +13,7 @@ namespace Avalonia.IntegrationTests.Appium
_session = fixture.Session;
var tabs = _session.FindElementByAccessibilityId("MainTabs");
var tab = tabs.FindElementByName("ScrollBarTab");
var tab = tabs.FindElementByName("ScrollBar");
tab.Click();
}

89
tests/Avalonia.IntegrationTests.Appium/SliderTests.cs

@ -1,4 +1,5 @@
using System;
using System.Globalization;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Interactions;
using Xunit;
@ -15,21 +16,95 @@ namespace Avalonia.IntegrationTests.Appium
_session = fixture.Session;
var tabs = _session.FindElementByAccessibilityId("MainTabs");
var tab = tabs.FindElementByName("SliderTab");
var tab = tabs.FindElementByName("Slider");
tab.Click();
var reset = _session.FindElementByAccessibilityId("ResetSliders");
reset.Click();
}
[Fact]
public void Horizontal_Changes_Value_Dragging_Thumb_Right()
{
var slider = _session.FindElementByAccessibilityId("HorizontalSlider");
var thumb = slider.FindElementByAccessibilityId("thumb");
var initialThumbRect = thumb.Rect;
new Actions(_session).ClickAndHold(thumb).MoveByOffset(100, 0).Release().Perform();
var value = Math.Round(double.Parse(slider.Text, CultureInfo.InvariantCulture));
var boundValue = double.Parse(
_session.FindElementByAccessibilityId("HorizontalSliderValue").Text,
CultureInfo.InvariantCulture);
Assert.True(value > 50);
Assert.Equal(value, boundValue);
var currentThumbRect = thumb.Rect;
Assert.True(currentThumbRect.Left > initialThumbRect.Left);
}
[Fact]
public void Horizontal_Changes_Value_Dragging_Thumb_Left()
{
var slider = _session.FindElementByAccessibilityId("HorizontalSlider");
var thumb = slider.FindElementByAccessibilityId("thumb");
var initialThumbRect = thumb.Rect;
new Actions(_session).ClickAndHold(thumb).MoveByOffset(-100, 0).Release().Perform();
var value = Math.Round(double.Parse(slider.Text, CultureInfo.InvariantCulture));
var boundValue = double.Parse(
_session.FindElementByAccessibilityId("HorizontalSliderValue").Text,
CultureInfo.InvariantCulture);
Assert.True(value < 50);
Assert.Equal(value, boundValue);
var currentThumbRect = thumb.Rect;
Assert.True(currentThumbRect.Left < initialThumbRect.Left);
}
[Fact]
public void Changes_Value_When_Clicking_Increase_Button()
public void Horizontal_Changes_Value_When_Clicking_Increase_Button()
{
var slider = _session.FindElementByAccessibilityId("Slider");
var slider = _session.FindElementByAccessibilityId("HorizontalSlider");
var thumb = slider.FindElementByAccessibilityId("thumb");
var initialThumbRect = thumb.Rect;
new Actions(_session).MoveToElement(slider, 100, 0, MoveToElementOffsetOrigin.Center).Click().Perform();
var value = Math.Round(double.Parse(slider.Text, CultureInfo.InvariantCulture));
var boundValue = double.Parse(
_session.FindElementByAccessibilityId("HorizontalSliderValue").Text,
CultureInfo.InvariantCulture);
Assert.True(value > 50);
Assert.Equal(value, boundValue);
var currentThumbRect = thumb.Rect;
Assert.True(currentThumbRect.Left > initialThumbRect.Left);
}
[Fact]
public void Horizontal_Changes_Value_When_Clicking_Decrease_Button()
{
var slider = _session.FindElementByAccessibilityId("HorizontalSlider");
var thumb = slider.FindElementByAccessibilityId("thumb");
var initialThumbRect = thumb.Rect;
new Actions(_session).MoveToElement(slider, -100, 0, MoveToElementOffsetOrigin.Center).Click().Perform();
// slider.Text gets the Slider value
Assert.True(double.Parse(slider.Text) == 30);
var value = Math.Round(double.Parse(slider.Text, CultureInfo.InvariantCulture));
var boundValue = double.Parse(
_session.FindElementByAccessibilityId("HorizontalSliderValue").Text,
CultureInfo.InvariantCulture);
new Actions(_session).Click(slider).Perform();
Assert.True(value < 50);
Assert.Equal(value, boundValue);
Assert.Equal(50, Math.Round(double.Parse(slider.Text)));
var currentThumbRect = thumb.Rect;
Assert.True(currentThumbRect.Left < initialThumbRect.Left);
}
}
}

Loading…
Cancel
Save