Browse Source

Merge branch 'master' into fixes/5947-gradient-drawingcontext

pull/6066/head
Benedikt Stebner 5 years ago
committed by GitHub
parent
commit
d27a940537
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      src/Avalonia.Input/KeyboardDevice.cs
  2. 61
      src/Avalonia.Visuals/Media/PolyLineSegment.cs
  3. 46
      tests/Avalonia.Input.UnitTests/KeyboardDeviceTests.cs

23
src/Avalonia.Input/KeyboardDevice.cs

@ -217,12 +217,31 @@ namespace Avalonia.Input
{
var bindings = (currentHandler as IInputElement)?.KeyBindings;
if (bindings != null)
{
KeyBinding[]? bindingsCopy = null;
// Create a copy of the KeyBindings list if there's a binding which matches the event.
// If we don't do this the foreach loop will throw an InvalidOperationException when the KeyBindings list is changed.
// This can happen when a new view is loaded which adds its own KeyBindings to the handler.
foreach (var binding in bindings)
{
if (ev.Handled)
if (binding.Gesture?.Matches(ev) == true)
{
bindingsCopy = bindings.ToArray();
break;
binding.TryHandle(ev);
}
}
if (bindingsCopy is object)
{
foreach (var binding in bindingsCopy)
{
if (ev.Handled)
break;
binding.TryHandle(ev);
}
}
}
currentHandler = currentHandler.VisualParent;
}

61
src/Avalonia.Visuals/Media/PolyLineSegment.cs

@ -0,0 +1,61 @@
using System.Collections.Generic;
using Avalonia.Collections;
namespace Avalonia.Media
{
/// <summary>
/// Represents a set of line segments defined by a points collection with each Point specifying the end point of a line segment.
/// </summary>
public sealed class PolyLineSegment : PathSegment
{
/// <summary>
/// Defines the <see cref="Points"/> property.
/// </summary>
public static readonly StyledProperty<Points> PointsProperty
= AvaloniaProperty.Register<PolyLineSegment, Points>(nameof(Points));
/// <summary>
/// Gets or sets the points.
/// </summary>
/// <value>
/// The points.
/// </value>
public AvaloniaList<Point> Points
{
get => GetValue(PointsProperty);
set => SetValue(PointsProperty, value);
}
/// <summary>
/// Initializes a new instance of the <see cref="PolyLineSegment"/> class.
/// </summary>
public PolyLineSegment()
{
Points = new Points();
}
/// <summary>
/// Initializes a new instance of the <see cref="PolyLineSegment"/> class.
/// </summary>
/// <param name="points">The points.</param>
public PolyLineSegment(IEnumerable<Point> points) : this()
{
Points.AddRange(points);
}
protected internal override void ApplyTo(StreamGeometryContext ctx)
{
var points = Points;
if (points.Count > 0)
{
for (int i = 0; i < points.Count; i++)
{
ctx.LineTo(points[i]);
}
}
}
public override string ToString()
=> Points.Count >= 1 ? "L " + string.Join(" ", Points) : "";
}
}

46
tests/Avalonia.Input.UnitTests/KeyboardDeviceTests.cs

@ -1,5 +1,9 @@
using Avalonia.Input.Raw;
using System;
using System.Windows.Input;
using Avalonia.Controls;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
using Avalonia.UnitTests;
using Moq;
using Xunit;
@ -86,5 +90,45 @@ namespace Avalonia.Input.UnitTests
focused.Verify(x => x.RaiseEvent(It.IsAny<TextInputEventArgs>()));
}
[Fact]
public void Can_Change_KeyBindings_In_Keybinding_Event_Handler()
{
var target = new KeyboardDevice();
var button = new Button();
var root = new TestRoot(button);
var raised = 0;
button.KeyBindings.Add(new KeyBinding
{
Gesture = new KeyGesture(Key.O, KeyModifiers.Control),
Command = new DelegateCommand(() =>
{
button.KeyBindings.Clear();
++raised;
}),
});
target.SetFocusedElement(button, NavigationMethod.Pointer, 0);
target.ProcessRawEvent(
new RawKeyEventArgs(
target,
0,
root,
RawKeyEventType.KeyDown,
Key.O,
RawInputModifiers.Control));
Assert.Equal(1, raised);
}
private class DelegateCommand : ICommand
{
private readonly Action _action;
public DelegateCommand(Action action) => _action = action;
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => true;
public void Execute(object parameter) => _action();
}
}
}

Loading…
Cancel
Save