committed by
GitHub
32 changed files with 735 additions and 103 deletions
@ -0,0 +1,23 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
namespace Avalonia |
|||
{ |
|||
/// <summary>
|
|||
/// Provides extension methods for enums.
|
|||
/// </summary>
|
|||
public static class EnumExtensions |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static unsafe bool HasFlagCustom<T>(this T value, T flag) where T : unmanaged, Enum |
|||
{ |
|||
var intValue = *(int*)&value; |
|||
var intFlag = *(int*)&flag; |
|||
|
|||
return (intValue & intFlag) == intFlag; |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +1,19 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System.Collections; |
|||
using System.Collections.Specialized; |
|||
|
|||
namespace Avalonia.Controls.Presenters |
|||
{ |
|||
public interface IItemsPresenter : IPresenter |
|||
{ |
|||
IEnumerable Items { get; set; } |
|||
|
|||
IPanel Panel { get; } |
|||
|
|||
void ItemsChanged(NotifyCollectionChangedEventArgs e); |
|||
|
|||
void ScrollIntoView(object item); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,109 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Reactive.Disposables; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Threading; |
|||
using Avalonia.UnitTests; |
|||
using Avalonia.VisualTree; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Controls.UnitTests |
|||
{ |
|||
public class TolTipTests |
|||
{ |
|||
private MouseTestHelper _mouseHelper = new MouseTestHelper(); |
|||
|
|||
[Fact] |
|||
public void Should_Not_Open_On_Detached_Control() |
|||
{ |
|||
//issue #3188
|
|||
var control = new Decorator() |
|||
{ |
|||
[ToolTip.TipProperty] = "Tip", |
|||
[ToolTip.ShowDelayProperty] = 0 |
|||
}; |
|||
|
|||
Assert.False((control as IVisual).IsAttachedToVisualTree); |
|||
|
|||
//here in issue #3188 exception is raised
|
|||
_mouseHelper.Enter(control); |
|||
|
|||
Assert.False(ToolTip.GetIsOpen(control)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Open_On_Pointer_Enter() |
|||
{ |
|||
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|||
{ |
|||
var window = new Window(); |
|||
|
|||
var target = new Decorator() |
|||
{ |
|||
[ToolTip.TipProperty] = "Tip", |
|||
[ToolTip.ShowDelayProperty] = 0 |
|||
}; |
|||
|
|||
window.Content = target; |
|||
|
|||
window.ApplyTemplate(); |
|||
window.Presenter.ApplyTemplate(); |
|||
|
|||
Assert.True((target as IVisual).IsAttachedToVisualTree); |
|||
|
|||
_mouseHelper.Enter(target); |
|||
|
|||
Assert.True(ToolTip.GetIsOpen(target)); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Open_On_Pointer_Enter_With_Delay() |
|||
{ |
|||
Action timercallback = null; |
|||
var delay = TimeSpan.Zero; |
|||
|
|||
var pti = Mock.Of<IPlatformThreadingInterface>(x => x.CurrentThreadIsLoopThread == true); |
|||
|
|||
Mock.Get(pti) |
|||
.Setup(v => v.StartTimer(It.IsAny<DispatcherPriority>(), It.IsAny<TimeSpan>(), It.IsAny<Action>())) |
|||
.Callback<DispatcherPriority, TimeSpan, Action>((priority, interval, tick) => |
|||
{ |
|||
delay = interval; |
|||
timercallback = tick; |
|||
}) |
|||
.Returns(Disposable.Empty); |
|||
|
|||
using (UnitTestApplication.Start(TestServices.StyledWindow.With(threadingInterface: pti))) |
|||
{ |
|||
var window = new Window(); |
|||
|
|||
var target = new Decorator() |
|||
{ |
|||
[ToolTip.TipProperty] = "Tip", |
|||
[ToolTip.ShowDelayProperty] = 1 |
|||
}; |
|||
|
|||
window.Content = target; |
|||
|
|||
window.ApplyTemplate(); |
|||
window.Presenter.ApplyTemplate(); |
|||
|
|||
Assert.True((target as IVisual).IsAttachedToVisualTree); |
|||
|
|||
_mouseHelper.Enter(target); |
|||
|
|||
Assert.Equal(TimeSpan.FromMilliseconds(1), delay); |
|||
Assert.NotNull(timercallback); |
|||
Assert.False(ToolTip.GetIsOpen(target)); |
|||
|
|||
timercallback(); |
|||
|
|||
Assert.True(ToolTip.GetIsOpen(target)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Avalonia.Controls; |
|||
using Avalonia.UnitTests; |
|||
using Avalonia.VisualTree; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Input.UnitTests |
|||
{ |
|||
public class PointerTests |
|||
{ |
|||
[Fact] |
|||
public void On_Capture_Transfer_PointerCaptureLost_Should_Propagate_Up_To_The_Common_Parent() |
|||
{ |
|||
Border initialParent, initialCapture, newParent, newCapture; |
|||
var el = new StackPanel |
|||
{ |
|||
Children = |
|||
{ |
|||
(initialParent = new Border { Child = initialCapture = new Border() }), |
|||
(newParent = new Border { Child = newCapture = new Border() }) |
|||
} |
|||
}; |
|||
var receivers = new List<object>(); |
|||
var root = new TestRoot(el); |
|||
foreach (InputElement d in root.GetSelfAndVisualDescendants()) |
|||
d.PointerCaptureLost += (s, e) => receivers.Add(s); |
|||
var pointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true); |
|||
|
|||
pointer.Capture(initialCapture); |
|||
pointer.Capture(newCapture); |
|||
Assert.True(receivers.SequenceEqual(new[] { initialCapture, initialParent })); |
|||
|
|||
receivers.Clear(); |
|||
pointer.Capture(null); |
|||
Assert.True(receivers.SequenceEqual(new object[] { newCapture, newParent, el, root })); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue