Browse Source

Merge branch 'master' into fixes/Warnings/ControlCatagol

pull/8275/head
Max Katz 4 years ago
committed by GitHub
parent
commit
669e004589
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      samples/ControlCatalog/Pages/NumericUpDownPage.xaml
  2. 4
      src/Avalonia.Base/Matrix.cs
  3. 2
      src/Avalonia.Controls/Calendar/CalendarItem.cs
  4. 111
      src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs
  5. 6
      src/Avalonia.Controls/NumericUpDown/NumericUpDownValueChangedEventArgs.cs
  6. 20
      src/Web/Avalonia.Web.Blazor/AvaloniaView.razor
  7. 38
      src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs
  8. 4
      src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
  9. 10
      tests/Avalonia.Base.UnitTests/Media/MatrixTests.cs

2
samples/ControlCatalog/Pages/NumericUpDownPage.xaml

@ -65,7 +65,7 @@
Margin="2" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Margin="10,2,2,2">Value:</TextBlock>
<NumericUpDown Grid.Row="3" Grid.Column="1" Value="{Binding #upDown.Value}" VerticalAlignment="Center"
<NumericUpDown Grid.Row="3" Grid.Column="1" Value="{Binding DecimalValue}" VerticalAlignment="Center"
Margin="2" HorizontalAlignment="Center"/>

4
src/Avalonia.Base/Matrix.cs

@ -450,13 +450,13 @@ namespace Avalonia
inverted = new Matrix(
(_m22 * _m33 - _m32 * _m23) * invdet,
(_m13 * _m31 - _m12 * _m33) * invdet,
(_m13 * _m32 - _m12 * _m33) * invdet,
(_m12 * _m23 - _m13 * _m22) * invdet,
(_m23 * _m31 - _m21 * _m33) * invdet,
(_m11 * _m33 - _m13 * _m31) * invdet,
(_m21 * _m13 - _m11 * _m23) * invdet,
(_m21 * _m32 - _m31 * _m22) * invdet,
(_m21 * _m12 - _m11 * _m32) * invdet,
(_m31 * _m12 - _m11 * _m32) * invdet,
(_m11 * _m22 - _m21 * _m12) * invdet
);

2
src/Avalonia.Controls/Calendar/CalendarItem.cs

@ -218,7 +218,7 @@ namespace Avalonia.Controls.Primitives
if (YearView != null)
{
var childCount = Calendar.RowsPerYear * Calendar.ColumnsPerYear;
var children = new List<IControl>(childCount);
using var children = new PooledList<IControl>(childCount);
EventHandler<PointerPressedEventArgs> monthCalendarButtonMouseDown = Month_CalendarButtonMouseDown;
EventHandler<PointerReleasedEventArgs> monthCalendarButtonMouseUp = Month_CalendarButtonMouseUp;

111
src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs

@ -107,8 +107,8 @@ namespace Avalonia.Controls
/// <summary>
/// Defines the <see cref="Value"/> property.
/// </summary>
public static readonly DirectProperty<NumericUpDown, decimal> ValueProperty =
AvaloniaProperty.RegisterDirect<NumericUpDown, decimal>(nameof(Value), updown => updown.Value,
public static readonly DirectProperty<NumericUpDown, decimal?> ValueProperty =
AvaloniaProperty.RegisterDirect<NumericUpDown, decimal?>(nameof(Value), updown => updown.Value,
(updown, v) => updown.Value = v, defaultBindingMode: BindingMode.TwoWay, enableDataValidation: true);
/// <summary>
@ -131,7 +131,7 @@ namespace Avalonia.Controls
private IDisposable? _textBoxTextChangedSubscription;
private decimal _value;
private decimal? _value;
private string? _text;
private bool _internalValueSet;
private bool _clipValueToMinMax;
@ -277,7 +277,7 @@ namespace Avalonia.Controls
/// <summary>
/// Gets or sets the value.
/// </summary>
public decimal Value
public decimal? Value
{
get { return _value; }
set
@ -351,7 +351,7 @@ namespace Avalonia.Controls
/// <inheritdoc />
protected override void OnLostFocus(RoutedEventArgs e)
{
CommitInput();
CommitInput(true);
base.OnLostFocus(e);
}
@ -489,9 +489,9 @@ namespace Avalonia.Controls
{
SetValidSpinDirection();
}
if (ClipValueToMinMax)
if (ClipValueToMinMax && Value.HasValue)
{
Value = MathUtilities.Clamp(Value, Minimum, Maximum);
Value = MathUtilities.Clamp(Value.Value, Minimum, Maximum);
}
}
@ -506,9 +506,9 @@ namespace Avalonia.Controls
{
SetValidSpinDirection();
}
if (ClipValueToMinMax)
if (ClipValueToMinMax && Value.HasValue)
{
Value = MathUtilities.Clamp(Value, Minimum, Maximum);
Value = MathUtilities.Clamp(Value.Value, Minimum, Maximum);
}
}
@ -530,7 +530,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="oldValue">The old value.</param>
/// <param name="newValue">The new value.</param>
protected virtual void OnValueChanged(decimal oldValue, decimal newValue)
protected virtual void OnValueChanged(decimal? oldValue, decimal? newValue)
{
if (!_internalValueSet && IsInitialized)
{
@ -573,7 +573,7 @@ namespace Avalonia.Controls
/// Called when the <see cref="Value"/> property has to be coerced.
/// </summary>
/// <param name="baseValue">The value.</param>
protected virtual decimal OnCoerceValue(decimal baseValue)
protected virtual decimal? OnCoerceValue(decimal? baseValue)
{
return baseValue;
}
@ -607,7 +607,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="oldValue">The old value.</param>
/// <param name="newValue">The new value.</param>
protected virtual void RaiseValueChangedEvent(decimal oldValue, decimal newValue)
protected virtual void RaiseValueChangedEvent(decimal? oldValue, decimal? newValue)
{
var e = new NumericUpDownValueChangedEventArgs(ValueChangedEvent, oldValue, newValue);
RaiseEvent(e);
@ -616,9 +616,9 @@ namespace Avalonia.Controls
/// <summary>
/// Converts the formatted text to a value.
/// </summary>
private decimal ConvertTextToValue(string text)
private decimal? ConvertTextToValue(string? text)
{
decimal result = 0;
decimal? result = null;
if (string.IsNullOrEmpty(text))
{
@ -635,9 +635,9 @@ namespace Avalonia.Controls
result = ConvertTextToValueCore(currentValueText, text);
if (ClipValueToMinMax)
if (ClipValueToMinMax && result.HasValue)
{
return MathUtilities.Clamp(result, Minimum, Maximum);
return MathUtilities.Clamp(result.Value, Minimum, Maximum);
}
ValidateMinMax(result);
@ -649,7 +649,7 @@ namespace Avalonia.Controls
/// Converts the value to formatted text.
/// </summary>
/// <returns></returns>
private string ConvertValueToText()
private string? ConvertValueToText()
{
//Manage FormatString of type "{}{0:N2} °" (in xaml) or "{0:N2} °" in code-behind.
if (FormatString.Contains("{0"))
@ -657,7 +657,7 @@ namespace Avalonia.Controls
return string.Format(NumberFormat, FormatString, Value);
}
return Value.ToString(FormatString, NumberFormat);
return Value?.ToString(FormatString, NumberFormat);
}
/// <summary>
@ -665,7 +665,16 @@ namespace Avalonia.Controls
/// </summary>
private void OnIncrement()
{
var result = Value + Increment;
decimal result;
if (Value.HasValue)
{
result = Value.Value + Increment;
}
else
{
result = Minimum;
}
Value = MathUtilities.Clamp(result, Minimum, Maximum);
}
@ -674,7 +683,17 @@ namespace Avalonia.Controls
/// </summary>
private void OnDecrement()
{
var result = Value - Increment;
decimal result;
if (Value.HasValue)
{
result = Value.Value - Increment;
}
else
{
result = Maximum;
}
Value = MathUtilities.Clamp(result, Minimum, Maximum);
}
@ -688,6 +707,11 @@ namespace Avalonia.Controls
// Zero increment always prevents spin.
if (Increment != 0 && !IsReadOnly)
{
if (!Value.HasValue)
{
validDirections = ValidSpinDirections.Increase | ValidSpinDirections.Decrease;
}
if (Value < Maximum)
{
validDirections = validDirections | ValidSpinDirections.Increase;
@ -825,13 +849,13 @@ namespace Avalonia.Controls
{
if (e.Sender is NumericUpDown upDown)
{
var oldValue = (decimal)e.OldValue!;
var newValue = (decimal)e.NewValue!;
var oldValue = (decimal?)e.OldValue;
var newValue = (decimal?)e.NewValue;
upDown.OnValueChanged(oldValue, newValue);
}
}
private void SetValueInternal(decimal value)
private void SetValueInternal(decimal? value)
{
_internalValueSet = true;
try
@ -946,9 +970,9 @@ namespace Avalonia.Controls
remove { RemoveHandler(ValueChangedEvent, value); }
}
private bool CommitInput()
private bool CommitInput(bool forceTextUpdate = false)
{
return SyncTextAndValueProperties(true, Text);
return SyncTextAndValueProperties(true, Text, forceTextUpdate);
}
/// <summary>
@ -978,28 +1002,24 @@ namespace Avalonia.Controls
{
if (updateValueFromText)
{
if (!string.IsNullOrEmpty(text))
try
{
try
var newValue = ConvertTextToValue(text);
if (!Equals(newValue, Value))
{
var newValue = ConvertTextToValue(text);
if (!Equals(newValue, Value))
{
SetValueInternal(newValue);
}
}
catch
{
parsedTextIsValid = false;
SetValueInternal(newValue);
}
}
catch
{
parsedTextIsValid = false;
}
}
// Do not touch the ongoing text input from user.
if (!_isTextChangedFromUI)
{
var keepEmpty = !forceTextUpdate && string.IsNullOrEmpty(Text);
if (!keepEmpty)
if (forceTextUpdate)
{
var newText = ConvertValueToText();
if (!Equals(Text, newText))
@ -1036,10 +1056,15 @@ namespace Avalonia.Controls
return parsedTextIsValid;
}
private decimal ConvertTextToValueCore(string currentValueText, string text)
private decimal? ConvertTextToValueCore(string? currentValueText, string? text)
{
decimal result;
if (string.IsNullOrEmpty(text))
{
return null;
}
if (IsPercent(FormatString))
{
result = ParsePercent(text, NumberFormat);
@ -1052,7 +1077,7 @@ namespace Avalonia.Controls
var shouldThrow = true;
// Check if CurrentValueText is also failing => it also contains special characters. ex : 90°
if (!decimal.TryParse(currentValueText, ParsingNumberStyle, NumberFormat, out var _))
if (!string.IsNullOrEmpty(currentValueText) && !decimal.TryParse(currentValueText, ParsingNumberStyle, NumberFormat, out var _))
{
// extract non-digit characters
var currentValueTextSpecialCharacters = currentValueText.Where(c => !char.IsDigit(c));
@ -1082,8 +1107,12 @@ namespace Avalonia.Controls
return result;
}
private void ValidateMinMax(decimal value)
private void ValidateMinMax(decimal? value)
{
if (!value.HasValue)
{
return;
}
if (value < Minimum)
{
throw new ArgumentOutOfRangeException(nameof(value), string.Format("Value must be greater than Minimum value of {0}", Minimum));

6
src/Avalonia.Controls/NumericUpDown/NumericUpDownValueChangedEventArgs.cs

@ -4,13 +4,13 @@ namespace Avalonia.Controls
{
public class NumericUpDownValueChangedEventArgs : RoutedEventArgs
{
public NumericUpDownValueChangedEventArgs(RoutedEvent routedEvent, decimal oldValue, decimal newValue) : base(routedEvent)
public NumericUpDownValueChangedEventArgs(RoutedEvent routedEvent, decimal? oldValue, decimal? newValue) : base(routedEvent)
{
OldValue = oldValue;
NewValue = newValue;
}
public decimal OldValue { get; }
public decimal NewValue { get; }
public decimal? OldValue { get; }
public decimal? NewValue { get; }
}
}

20
src/Web/Avalonia.Web.Blazor/AvaloniaView.razor

@ -1,24 +1,26 @@
<div id="container" class="avalonia-container" tabindex="0" oncontextmenu="return false;"
ontouchcancel="@OnTouchCancel"
ontouchmove="@OnTouchMove"
onwheel="@OnWheel"
onkeydown="@OnKeyDown"
onkeyup="@OnKeyUp"
onpointerdown="@OnPointerDown"
onpointerup="@OnPointerUp"
onpointermove="@OnPointerMove">
@onwheel="OnWheel"
@onkeydown="OnKeyDown"
@onkeyup="OnKeyUp"
@onpointerdown="OnPointerDown"
@onpointerup="OnPointerUp"
@onpointermove="OnPointerMove"
@onpointercancel="OnPointerCancel">
<canvas id="htmlCanvas" @ref="_htmlCanvas" @attributes="AdditionalAttributes"/>
<div id="nativeControlsContainer" @ref="_nativeControlsContainer" />
<input id="inputElement" @ref="_inputElement" type="text" oninput="@OnInput"
<input id="inputElement" @ref="_inputElement" type="text" @oninput="OnInput"
onpaste="return false;"
oncopy="return false;"
oncut="return false;"/>
</div>
<style>
#container{
touch-action: none;
}
#htmlCanvas {
opacity: 1;
background-color: #ccc;

38
src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs

@ -57,27 +57,23 @@ namespace Avalonia.Web.Blazor
return _nativeControlHost ?? throw new InvalidOperationException("Blazor View wasn't initialized yet");
}
private void OnTouchCancel(TouchEventArgs e)
private void OnPointerCancel(Microsoft.AspNetCore.Components.Web.PointerEventArgs e)
{
foreach (var touch in e.ChangedTouches)
if (e.PointerType == "touch")
{
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchCancel, new Point(touch.ClientX, touch.ClientY),
GetModifiers(e), touch.Identifier);
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchCancel, new Point(e.ClientX, e.ClientY),
GetModifiers(e), e.PointerId);
}
}
private void OnTouchMove(TouchEventArgs e)
private void OnPointerMove(Microsoft.AspNetCore.Components.Web.PointerEventArgs e)
{
foreach (var touch in e.ChangedTouches)
if (e.PointerType == "touch")
{
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchUpdate, new Point(touch.ClientX, touch.ClientY),
GetModifiers(e), touch.Identifier);
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchUpdate, new Point(e.ClientX, e.ClientY),
GetModifiers(e), e.PointerId);
}
}
private void OnPointerMove(Microsoft.AspNetCore.Components.Web.PointerEventArgs e)
{
if (e.PointerType != "touch")
else
{
_topLevelImpl.RawMouseEvent(RawPointerEventType.Move, new Point(e.ClientX, e.ClientY), GetModifiers(e));
}
@ -174,22 +170,6 @@ namespace Avalonia.Web.Blazor
return modifiers;
}
private static RawInputModifiers GetModifiers(TouchEventArgs e)
{
var modifiers = RawInputModifiers.None;
if (e.CtrlKey)
modifiers |= RawInputModifiers.Control;
if (e.AltKey)
modifiers |= RawInputModifiers.Alt;
if (e.ShiftKey)
modifiers |= RawInputModifiers.Shift;
if (e.MetaKey)
modifiers |= RawInputModifiers.Meta;
return modifiers;
}
private static RawInputModifiers GetModifiers(Microsoft.AspNetCore.Components.Web.PointerEventArgs e)
{
var modifiers = RawInputModifiers.None;

4
src/Windows/Avalonia.Win32/Avalonia.Win32.csproj

@ -18,4 +18,8 @@
</ItemGroup>
<Import Project="$(MSBuildThisFileDirectory)\..\..\..\build\System.Drawing.Common.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" />
<PropertyGroup Label="Warnings">
<NoWarn Condition="'$(NoWarn)' == ''">CA1416</NoWarn>
<NoWarn Condition="'$(NoWarn)' != ''">$(NoWarn),CA1416</NoWarn>
</PropertyGroup>
</Project>

10
tests/Avalonia.Base.UnitTests/Media/MatrixTests.cs

@ -30,6 +30,16 @@ namespace Avalonia.Base.UnitTests.Media
Assert.True(matrix.HasInverse);
}
[Fact]
public void Invert_Should_Work()
{
var matrix = new Matrix(1, 2, 3, 0, 1, 4, 5, 6, 0);
var inverted = matrix.Invert();
Assert.Equal(matrix * inverted, Matrix.Identity);
Assert.Equal(inverted * matrix, Matrix.Identity);
}
[Fact]
public void Can_Decompose_Translation()
{

Loading…
Cancel
Save