Browse Source

Merge branch 'master' into compile-time-grid-definitions

pull/5088/head
Dariusz Komosiński 5 years ago
committed by GitHub
parent
commit
d4283c209d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      src/Avalonia.Controls/AutoCompleteBox.cs
  2. 4
      src/Avalonia.Controls/Generators/ItemContainerInfo.cs
  3. 31
      src/Avalonia.Native/DoubleClickHelper.cs
  4. 22
      src/Avalonia.Native/WindowImpl.cs
  5. 29
      src/Avalonia.Visuals/Matrix.cs
  6. 8
      src/Avalonia.Visuals/VisualExtensions.cs
  7. 17
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  8. 19
      tests/Avalonia.Visuals.UnitTests/VisualTests.cs

7
src/Avalonia.Controls/AutoCompleteBox.cs

@ -1405,8 +1405,11 @@ namespace Avalonia.Controls
break; break;
case Key.Enter: case Key.Enter:
OnAdapterSelectionComplete(this, new RoutedEventArgs()); if (IsDropDownOpen)
e.Handled = true; {
OnAdapterSelectionComplete(this, new RoutedEventArgs());
e.Handled = true;
}
break; break;
default: default:

4
src/Avalonia.Controls/Generators/ItemContainerInfo.cs

@ -37,6 +37,6 @@ namespace Avalonia.Controls.Generators
/// <summary> /// <summary>
/// Gets the index of the item in the <see cref="ItemsControl.Items"/> collection. /// Gets the index of the item in the <see cref="ItemsControl.Items"/> collection.
/// </summary> /// </summary>
public int Index { get; internal set; } public int Index { get; set; }
} }
} }

31
src/Avalonia.Native/DoubleClickHelper.cs

@ -0,0 +1,31 @@
using Avalonia.Platform;
namespace Avalonia.Native
{
internal class DoubleClickHelper
{
private int _clickCount;
private Rect _lastClickRect;
private ulong _lastClickTime;
public bool IsDoubleClick(
ulong timestamp,
Point p)
{
var settings = AvaloniaLocator.Current.GetService<IPlatformSettings>();
var doubleClickTime = settings.DoubleClickTime.TotalMilliseconds;
if (!_lastClickRect.Contains(p) || timestamp - _lastClickTime > doubleClickTime)
{
_clickCount = 0;
}
++_clickCount;
_lastClickTime = timestamp;
_lastClickRect = new Rect(p, new Size())
.Inflate(new Thickness(settings.DoubleClickSize.Width / 2, settings.DoubleClickSize.Height / 2));
return _clickCount == 2;
}
}
}

22
src/Avalonia.Native/WindowImpl.cs

@ -1,4 +1,5 @@
using System; using System;
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Platform; using Avalonia.Controls.Platform;
using Avalonia.Input; using Avalonia.Input;
@ -17,6 +18,8 @@ namespace Avalonia.Native
private readonly AvaloniaNativePlatformOpenGlInterface _glFeature; private readonly AvaloniaNativePlatformOpenGlInterface _glFeature;
IAvnWindow _native; IAvnWindow _native;
private double _extendTitleBarHeight = -1; private double _extendTitleBarHeight = -1;
private DoubleClickHelper _doubleClickHelper;
internal WindowImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts, internal WindowImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts,
AvaloniaNativePlatformOpenGlInterface glFeature) : base(opts, glFeature) AvaloniaNativePlatformOpenGlInterface glFeature) : base(opts, glFeature)
@ -24,6 +27,8 @@ namespace Avalonia.Native
_factory = factory; _factory = factory;
_opts = opts; _opts = opts;
_glFeature = glFeature; _glFeature = glFeature;
_doubleClickHelper = new DoubleClickHelper();
using (var e = new WindowEvents(this)) using (var e = new WindowEvents(this))
{ {
var context = _opts.UseGpu ? glFeature?.MainContext : null; var context = _opts.UseGpu ? glFeature?.MainContext : null;
@ -118,7 +123,22 @@ namespace Avalonia.Native
if(visual == null) if(visual == null)
{ {
_native.BeginMoveDrag(); if (_doubleClickHelper.IsDoubleClick(e.Timestamp, e.Position))
{
// TOGGLE WINDOW STATE.
if (WindowState == WindowState.Maximized || WindowState == WindowState.FullScreen)
{
WindowState = WindowState.Normal;
}
else
{
WindowState = WindowState.Maximized;
}
}
else
{
_native.BeginMoveDrag();
}
} }
} }
} }

29
src/Avalonia.Visuals/Matrix.cs

@ -282,25 +282,44 @@ namespace Avalonia
} }
/// <summary> /// <summary>
/// Inverts the Matrix. /// Attempts to invert the Matrix.
/// </summary> /// </summary>
/// <returns>The inverted matrix.</returns> /// <returns>The inverted matrix or <see langword="null"/> when matrix is not invertible.</returns>
public Matrix Invert() public bool TryInvert(out Matrix inverted)
{ {
double d = GetDeterminant(); double d = GetDeterminant();
if (MathUtilities.IsZero(d)) if (MathUtilities.IsZero(d))
{ {
throw new InvalidOperationException("Transform is not invertible."); inverted = default;
return false;
} }
return new Matrix( inverted = new Matrix(
_m22 / d, _m22 / d,
-_m12 / d, -_m12 / d,
-_m21 / d, -_m21 / d,
_m11 / d, _m11 / d,
((_m21 * _m32) - (_m22 * _m31)) / d, ((_m21 * _m32) - (_m22 * _m31)) / d,
((_m12 * _m31) - (_m11 * _m32)) / d); ((_m12 * _m31) - (_m11 * _m32)) / d);
return true;
}
/// <summary>
/// Inverts the Matrix.
/// </summary>
/// <exception cref="InvalidOperationException">Matrix is not invertible.</exception>
/// <returns>The inverted matrix.</returns>
public Matrix Invert()
{
if (!TryInvert(out Matrix inverted))
{
throw new InvalidOperationException("Transform is not invertible.");
}
return inverted;
} }
/// <summary> /// <summary>

8
src/Avalonia.Visuals/VisualExtensions.cs

@ -50,7 +50,13 @@ namespace Avalonia
{ {
var thisOffset = GetOffsetFrom(common, from); var thisOffset = GetOffsetFrom(common, from);
var thatOffset = GetOffsetFrom(common, to); var thatOffset = GetOffsetFrom(common, to);
return -thatOffset * thisOffset;
if (!thatOffset.TryInvert(out var thatOffsetInverted))
{
return null;
}
return thatOffsetInverted * thisOffset;
} }
return null; return null;

17
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -3,6 +3,8 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.OpenGL; using Avalonia.OpenGL;
@ -166,12 +168,13 @@ namespace Avalonia.Skia
LinearMetrics = true LinearMetrics = true
}; };
private static readonly SKTextBlobBuilder s_textBlobBuilder = new SKTextBlobBuilder(); private static readonly ThreadLocal<SKTextBlobBuilder> s_textBlobBuilderThreadLocal = new ThreadLocal<SKTextBlobBuilder>(() => new SKTextBlobBuilder());
/// <inheritdoc /> /// <inheritdoc />
public IGlyphRunImpl CreateGlyphRun(GlyphRun glyphRun, out double width) public IGlyphRunImpl CreateGlyphRun(GlyphRun glyphRun, out double width)
{ {
var count = glyphRun.GlyphIndices.Length; var count = glyphRun.GlyphIndices.Length;
var textBlobBuilder = s_textBlobBuilderThreadLocal.Value;
var glyphTypeface = (GlyphTypefaceImpl)glyphRun.GlyphTypeface.PlatformImpl; var glyphTypeface = (GlyphTypefaceImpl)glyphRun.GlyphTypeface.PlatformImpl;
@ -191,15 +194,15 @@ namespace Avalonia.Skia
{ {
if (glyphTypeface.IsFixedPitch) if (glyphTypeface.IsFixedPitch)
{ {
s_textBlobBuilder.AddRun(glyphRun.GlyphIndices.Buffer.Span, s_font); textBlobBuilder.AddRun(glyphRun.GlyphIndices.Buffer.Span, s_font);
textBlob = s_textBlobBuilder.Build(); textBlob = textBlobBuilder.Build();
width = glyphTypeface.GetGlyphAdvance(glyphRun.GlyphIndices[0]) * scale * glyphRun.GlyphIndices.Length; width = glyphTypeface.GetGlyphAdvance(glyphRun.GlyphIndices[0]) * scale * glyphRun.GlyphIndices.Length;
} }
else else
{ {
var buffer = s_textBlobBuilder.AllocateHorizontalRun(s_font, count, 0); var buffer = textBlobBuilder.AllocateHorizontalRun(s_font, count, 0);
var positions = buffer.GetPositionSpan(); var positions = buffer.GetPositionSpan();
@ -219,12 +222,12 @@ namespace Avalonia.Skia
buffer.SetGlyphs(glyphRun.GlyphIndices.Buffer.Span); buffer.SetGlyphs(glyphRun.GlyphIndices.Buffer.Span);
textBlob = s_textBlobBuilder.Build(); textBlob = textBlobBuilder.Build();
} }
} }
else else
{ {
var buffer = s_textBlobBuilder.AllocatePositionedRun(s_font, count); var buffer = textBlobBuilder.AllocatePositionedRun(s_font, count);
var glyphPositions = buffer.GetPositionSpan(); var glyphPositions = buffer.GetPositionSpan();
@ -250,7 +253,7 @@ namespace Avalonia.Skia
width = currentX; width = currentX;
textBlob = s_textBlobBuilder.Build(); textBlob = textBlobBuilder.Build();
} }
return new GlyphRunImpl(textBlob); return new GlyphRunImpl(textBlob);

19
tests/Avalonia.Visuals.UnitTests/VisualTests.cs

@ -235,6 +235,25 @@ namespace Avalonia.Visuals.UnitTests
Assert.Equal(new Point(100, 100), point); Assert.Equal(new Point(100, 100), point);
} }
[Fact]
public void TransformToVisual_With_NonInvertible_RenderTransform_Should_Work()
{
var child = new Decorator
{
Width = 100,
Height = 100,
RenderTransform = new ScaleTransform() { ScaleX = 0, ScaleY = 0 }
};
var root = new TestRoot() { Child = child, Width = 400, Height = 400 };
root.Measure(Size.Infinity);
root.Arrange(new Rect(new Point(), root.DesiredSize));
var tr = root.TransformToVisual(child);
Assert.Null(tr);
}
[Fact] [Fact]
public void Should_Not_Log_Binding_Error_When_Not_Attached_To_Logical_Tree() public void Should_Not_Log_Binding_Error_When_Not_Attached_To_Logical_Tree()
{ {

Loading…
Cancel
Save