Browse Source

Merge branch 'master' into Takoooooo-patch-1

pull/6464/head
Nikita Tsukanov 5 years ago
committed by GitHub
parent
commit
56eb50bf20
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      native/Avalonia.Native/src/OSX/window.mm
  2. 6
      src/Avalonia.Base/Collections/AvaloniaList.cs
  3. 7
      src/Avalonia.Controls.DataGrid/Collections/DataGridGroupDescription.cs
  4. 13
      src/Avalonia.Controls.DataGrid/Utils/CellEditBinding.cs
  5. 16
      src/Avalonia.Controls/AutoCompleteBox.cs
  6. 73
      src/Avalonia.Controls/TextBox.cs
  7. 5
      src/Avalonia.Input/AccessKeyHandler.cs
  8. 11
      src/Avalonia.Input/Navigation/TabNavigation.cs
  9. 1
      src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj
  10. 3
      src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs
  11. 1
      src/Windows/Avalonia.Win32.Interop/Wpf/Direct2DImageSurface.cs
  12. 2
      src/Windows/Avalonia.Win32/FramebufferManager.cs
  13. 7
      src/Windows/Avalonia.Win32/PlatformConstants.cs
  14. 4
      src/Windows/Avalonia.Win32/Win32GlManager.cs
  15. 2
      src/Windows/Avalonia.Win32/Win32Platform.cs
  16. 4
      src/Windows/Avalonia.Win32/WindowImpl.cs
  17. 10
      tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
  18. 1
      tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs
  19. 3
      tests/Avalonia.Input.UnitTests/KeyboardDeviceTests.cs
  20. 27
      tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Tab.cs
  21. 2
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs

10
native/Avalonia.Native/src/OSX/window.mm

@ -641,6 +641,7 @@ private:
[Window setCanBecomeKeyAndMain];
[Window disableCursorRects];
[Window setTabbingMode:NSWindowTabbingModeDisallowed];
[Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
}
void HideOrShowTrafficLights ()
@ -1091,14 +1092,7 @@ private:
{
_fullScreenActive = true;
[Window setHasShadow:YES];
[Window setTitleVisibility:NSWindowTitleVisible];
[Window setTitlebarAppearsTransparent:NO];
[Window setTitle:_lastTitle];
Window.styleMask = Window.styleMask | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable;
Window.styleMask = Window.styleMask & ~NSWindowStyleMaskFullSizeContentView;
[Window toggleFullScreen:nullptr];
}
@ -1672,6 +1666,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
switch(event.buttonNumber)
{
case 2:
case 3:
_isMiddlePressed = true;
[self mouseEvent:event withType:MiddleButtonDown];
@ -1704,6 +1699,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
{
switch(event.buttonNumber)
{
case 2:
case 3:
_isMiddlePressed = false;
[self mouseEvent:event withType:MiddleButtonUp];

6
src/Avalonia.Base/Collections/AvaloniaList.cs

@ -280,8 +280,8 @@ namespace Avalonia.Collections
/// <summary>
/// Gets a range of items from the collection.
/// </summary>
/// <param name="index">The first index to remove.</param>
/// <param name="count">The number of items to remove.</param>
/// <param name="index">The zero-based <see cref="AvaloniaList{T}"/> index at which the range starts.</param>
/// <param name="count">The number of elements in the range.</param>
public IEnumerable<T> GetRange(int index, int count)
{
return _inner.GetRange(index, count);
@ -455,7 +455,7 @@ namespace Avalonia.Collections
}
/// <summary>
/// Ensures that the capacity of the list is at least <see cref="capacity"/>.
/// Ensures that the capacity of the list is at least <see cref="Capacity"/>.
/// </summary>
/// <param name="capacity">The capacity.</param>
public void EnsureCapacity(int capacity)

7
src/Avalonia.Controls.DataGrid/Collections/DataGridGroupDescription.cs

@ -83,8 +83,9 @@ namespace Avalonia.Collections
if (key == null)
key = item;
if (_valueConverter != null)
key = _valueConverter.Convert(key, typeof(object), level, culture);
var valueConverter = ValueConverter;
if (valueConverter != null)
key = valueConverter.Convert(key, typeof(object), level, culture);
return key;
}
@ -99,6 +100,8 @@ namespace Avalonia.Collections
}
public override string PropertyName => _propertyPath;
public IValueConverter ValueConverter { get => _valueConverter; set => _valueConverter = value; }
private Type GetPropertyType(object o)
{
return o.GetType().GetNestedPropertyType(_propertyPath);

13
src/Avalonia.Controls.DataGrid/Utils/CellEditBinding.cs

@ -1,10 +1,8 @@
using Avalonia.Data;
using Avalonia.Reactive;
using System;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Reactive.Subjects;
using System.Text;
namespace Avalonia.Controls.Utils
{
@ -67,11 +65,14 @@ namespace Avalonia.Controls.Utils
private void SetSourceValue(object value)
{
_settingSourceValue = true;
if (!_settingSourceValue)
{
_settingSourceValue = true;
_sourceSubject.OnNext(value);
_sourceSubject.OnNext(value);
_settingSourceValue = false;
_settingSourceValue = false;
}
}
private void SetControlValue(object value)
{
@ -157,4 +158,4 @@ namespace Avalonia.Controls.Utils
}
}
}
}
}

16
src/Avalonia.Controls/AutoCompleteBox.cs

@ -2094,7 +2094,21 @@ namespace Avalonia.Controls
bool inResults = !(stringFiltering || objectFiltering);
if (!inResults)
{
inResults = stringFiltering ? TextFilter(text, FormatValue(item)) : ItemFilter(text, item);
if (stringFiltering)
{
inResults = TextFilter(text, FormatValue(item));
}
else
{
if (ItemFilter is null)
{
throw new Exception("ItemFilter property can not be null when FilterMode has value AutoCompleteFilterMode.Custom");
}
else
{
inResults = ItemFilter(text, item);
}
}
}
if (view_count > view_index && inResults && _view[view_index] == item)

73
src/Avalonia.Controls/TextBox.cs

@ -145,6 +145,18 @@ namespace Avalonia.Controls
(o, v) => o.UndoLimit = v,
unsetValue: -1);
public static readonly RoutedEvent<RoutedEventArgs> CopyingToClipboardEvent =
RoutedEvent.Register<TextBox, RoutedEventArgs>(
"CopyingToClipboard", RoutingStrategies.Bubble);
public static readonly RoutedEvent<RoutedEventArgs> CuttingToClipboardEvent =
RoutedEvent.Register<TextBox, RoutedEventArgs>(
"CuttingToClipboard", RoutingStrategies.Bubble);
public static readonly RoutedEvent<RoutedEventArgs> PastingFromClipboardEvent =
RoutedEvent.Register<TextBox, RoutedEventArgs>(
"PastingFromClipboard", RoutingStrategies.Bubble);
readonly struct UndoRedoState : IEquatable<UndoRedoState>
{
public string Text { get; }
@ -500,6 +512,24 @@ namespace Avalonia.Controls
}
}
public event EventHandler<RoutedEventArgs> CopyingToClipboard
{
add => AddHandler(CopyingToClipboardEvent, value);
remove => RemoveHandler(CopyingToClipboardEvent, value);
}
public event EventHandler<RoutedEventArgs> CuttingToClipboard
{
add => AddHandler(CuttingToClipboardEvent, value);
remove => RemoveHandler(CuttingToClipboardEvent, value);
}
public event EventHandler<RoutedEventArgs> PastingFromClipboard
{
add => AddHandler(PastingFromClipboardEvent, value);
remove => RemoveHandler(PastingFromClipboardEvent, value);
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
_presenter = e.NameScope.Get<TextPresenter>("PART_TextPresenter");
@ -638,27 +668,54 @@ namespace Avalonia.Controls
public async void Cut()
{
var text = GetSelection();
if (text is null) return;
if (string.IsNullOrEmpty(text))
{
return;
}
SnapshotUndoRedo();
Copy();
DeleteSelection();
var eventArgs = new RoutedEventArgs(CuttingToClipboardEvent);
RaiseEvent(eventArgs);
if (!eventArgs.Handled)
{
SnapshotUndoRedo();
await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)))
.SetTextAsync(text);
DeleteSelection();
}
}
public async void Copy()
{
var text = GetSelection();
if (text is null) return;
if (string.IsNullOrEmpty(text))
{
return;
}
await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)))
.SetTextAsync(text);
var eventArgs = new RoutedEventArgs(CopyingToClipboardEvent);
RaiseEvent(eventArgs);
if (!eventArgs.Handled)
{
await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)))
.SetTextAsync(text);
}
}
public async void Paste()
{
var eventArgs = new RoutedEventArgs(PastingFromClipboardEvent);
RaiseEvent(eventArgs);
if (eventArgs.Handled)
{
return;
}
var text = await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard))).GetTextAsync();
if (text is null) return;
if (string.IsNullOrEmpty(text))
{
return;
}
SnapshotUndoRedo();
HandleTextInput(text);

5
src/Avalonia.Input/AccessKeyHandler.cs

@ -157,10 +157,9 @@ namespace Avalonia.Input
_restoreFocusElement?.Focus();
_restoreFocusElement = null;
e.Handled = true;
}
// We always handle the Alt key.
e.Handled = true;
}
else if (_altIsDown)
{

11
src/Avalonia.Input/Navigation/TabNavigation.cs

@ -234,7 +234,7 @@ namespace Avalonia.Input.Navigation
// Return the first visible element.
var uiElement = e as InputElement;
if (uiElement is null || uiElement.IsVisible)
if (uiElement is null || IsVisibleAndEnabled(uiElement))
{
if (e is IVisual elementAsVisual)
{
@ -245,7 +245,7 @@ namespace Avalonia.Input.Navigation
{
if (children[i] is InputElement ie)
{
if (ie.IsVisible)
if (IsVisibleAndEnabled(ie))
return ie;
else
{
@ -270,7 +270,7 @@ namespace Avalonia.Input.Navigation
// Return the last visible element.
var uiElement = e as InputElement;
if (uiElement == null || uiElement.IsVisible)
if (uiElement == null || IsVisibleAndEnabled(uiElement))
{
var elementAsVisual = e as IVisual;
@ -283,7 +283,7 @@ namespace Avalonia.Input.Navigation
{
if (children[i] is InputElement ie)
{
if (ie.IsVisible)
if (IsVisibleAndEnabled(ie))
return ie;
else
{
@ -600,7 +600,7 @@ namespace Avalonia.Input.Navigation
var vchild = children[i];
if (vchild == elementAsVisual)
break;
if (vchild.IsVisible == true && vchild is IInputElement ie)
if (vchild is IInputElement ie && IsVisibleAndEnabled(ie))
prev = ie;
}
return prev;
@ -668,5 +668,6 @@ namespace Avalonia.Input.Navigation
}
private static bool IsTabStopOrGroup(IInputElement e) => IsTabStop(e) || IsGroup(e);
private static bool IsVisibleAndEnabled(IInputElement e) => e.IsVisible && e.IsEnabled;
}
}

1
src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj

@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />
<ProjectReference Include="..\Avalonia.Win32\Avalonia.Win32.csproj" />
</ItemGroup>
<Import Project="..\..\..\build\Rx.props" />
<Import Project="..\..\..\build\SharpDX.props" />

3
src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs

@ -1,4 +1,5 @@
using Avalonia.Platform;
using Avalonia.Win32;
using Avalonia.Win32.Interop;
using SharpDX;
using SharpDX.DXGI;
@ -21,7 +22,7 @@ namespace Avalonia.Direct2D1
protected override Size2F GetWindowDpi()
{
if (UnmanagedMethods.ShCoreAvailable)
if (UnmanagedMethods.ShCoreAvailable && Win32Platform.WindowsVersion > PlatformConstants.Windows8)
{
uint dpix, dpiy;

1
src/Windows/Avalonia.Win32.Interop/Wpf/Direct2DImageSurface.cs

@ -150,6 +150,7 @@ namespace Avalonia.Win32.Interop.Wpf
if (_image == null || _oldDpi.X != dpi.X || _oldDpi.Y != dpi.Y)
{
_image = new D3DImage(dpi.X, dpi.Y);
_oldDpi = dpi;
}
_impl.ImageSource = _image;

2
src/Windows/Avalonia.Win32/FramebufferManager.cs

@ -87,7 +87,7 @@ namespace Avalonia.Win32
private Vector GetCurrentDpi()
{
if (UnmanagedMethods.ShCoreAvailable)
if (UnmanagedMethods.ShCoreAvailable && Win32Platform.WindowsVersion > PlatformConstants.Windows8)
{
var monitor =
UnmanagedMethods.MonitorFromWindow(_hwnd, UnmanagedMethods.MONITOR.MONITOR_DEFAULTTONEAREST);

7
src/Windows/Avalonia.Win32/PlatformConstants.cs

@ -1,8 +1,13 @@
using System;
namespace Avalonia.Win32
{
static class PlatformConstants
public static class PlatformConstants
{
public const string WindowHandleType = "HWND";
public const string CursorHandleType = "HCURSOR";
public static readonly Version Windows8 = new Version(6, 2);
public static readonly Version Windows7 = new Version(6, 1);
}
}

4
src/Windows/Avalonia.Win32/Win32GlManager.cs

@ -1,4 +1,3 @@
using System;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Angle;
using Avalonia.OpenGL.Egl;
@ -9,7 +8,6 @@ namespace Avalonia.Win32
{
static class Win32GlManager
{
private static readonly Version Windows7 = new Version(6, 1);
public static void Initialize()
{
@ -22,7 +20,7 @@ namespace Avalonia.Win32
return wgl;
}
if (opts?.AllowEglInitialization ?? Win32Platform.WindowsVersion > Windows7)
if (opts?.AllowEglInitialization ?? Win32Platform.WindowsVersion > PlatformConstants.Windows7)
{
var egl = EglPlatformOpenGlInterface.TryCreate(() => new AngleWin32EglDisplay());

2
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -94,7 +94,7 @@ namespace Avalonia
namespace Avalonia.Win32
{
class Win32Platform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader, IPlatformLifetimeEventsImpl
public class Win32Platform : IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform, IPlatformIconLoader, IPlatformLifetimeEventsImpl
{
private static readonly Win32Platform s_instance = new Win32Platform();
private static Thread _uiThread;

4
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -764,8 +764,8 @@ namespace Avalonia.Win32
RegisterTouchWindow(_hwnd, 0);
}
if (ShCoreAvailable)
{
if (ShCoreAvailable && Win32Platform.WindowsVersion > PlatformConstants.Windows8)
{
var monitor = MonitorFromWindow(
_hwnd,
MONITOR.MONITOR_DEFAULTTONEAREST);

10
tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs

@ -105,6 +105,16 @@ namespace Avalonia.Controls.UnitTests
});
}
[Fact]
public void Custom_FilterMode_Without_ItemFilter_Setting_Throws_Exception()
{
RunTest((control, textbox) =>
{
control.FilterMode = AutoCompleteFilterMode.Custom;
Assert.Throws<Exception>(() => { control.Text = "a"; });
});
}
[Fact]
public void Text_Completion_Via_Text_Property()
{

1
tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs

@ -10,7 +10,6 @@ using Avalonia.Styling;
using Avalonia.UnitTests;
using Moq;
using Xunit;
using System;
using Avalonia.Input.Raw;
using Factory = System.Func<int, System.Action<object>, Avalonia.Controls.Window, Avalonia.AvaloniaObject>;

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

@ -2,7 +2,6 @@
using System.Windows.Input;
using Avalonia.Controls;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
using Avalonia.UnitTests;
using Moq;
using Xunit;
@ -126,7 +125,7 @@ namespace Avalonia.Input.UnitTests
{
private readonly Action _action;
public DelegateCommand(Action action) => _action = action;
public event EventHandler CanExecuteChanged;
public event EventHandler CanExecuteChanged { add { } remove { } }
public bool CanExecute(object parameter) => true;
public void Execute(object parameter) => _action();
}

27
tests/Avalonia.Input.UnitTests/KeyboardNavigationTests_Tab.cs

@ -1225,5 +1225,32 @@ namespace Avalonia.Input.UnitTests
"Button2", "Button3", "Button5", "Button1", "Button6", "Button4"
}, result);
}
[Fact]
public void Cannot_Focus_Child_Of_Disabled_Control()
{
Button start;
Button expected;
var top = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle,
Children =
{
(start = new Button { Name = "Button1" }),
new Border
{
IsEnabled = false,
Child = new Button { Name = "Button2" },
},
(expected = new Button { Name = "Button3" }),
}
};
var current = (IInputElement)start;
var result = KeyboardNavigationHandler.GetNext(current, NavigationDirection.Next);
Assert.Same(expected, result);
}
}
}

2
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs

@ -923,7 +923,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
public bool HasResources => true;
public List<object> RequestedResources { get; } = new List<object>();
public event EventHandler OwnerChanged;
public event EventHandler OwnerChanged { add { } remove { } }
public void AddOwner(IResourceHost owner) => Owner = owner;
public void RemoveOwner(IResourceHost owner) => Owner = null;

Loading…
Cancel
Save