Browse Source

Merge branch 'master' into colorpicker-updates-3

pull/9140/head
robloo 4 years ago
parent
commit
a0915da613
  1. 5
      .editorconfig
  2. 4
      NOTICE.md
  3. 2
      src/Android/Avalonia.Android/AvaloniaView.cs
  4. 2
      src/Avalonia.Base/Media/TextFormatting/Unicode/GraphemeBreak.cs
  5. 91
      src/Avalonia.Controls/TextBox.cs
  6. 2
      src/Avalonia.Controls/TextBoxTextInputMethodClient.cs
  7. 20
      src/Avalonia.Controls/TextChangedEventArgs.cs
  8. 20
      src/Avalonia.Controls/TextChangingEventArgs.cs
  9. 2
      src/Avalonia.DesignerSupport/Remote/HtmlTransport/SimpleWebSocketHttpServer.cs
  10. 6
      src/Avalonia.FreeDesktop/DBusMenuExporter.cs
  11. 2
      src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
  12. 5
      src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj
  13. 4
      src/Windows/Avalonia.Win32/Win32Platform.cs
  14. 4
      src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj
  15. 2
      tests/Avalonia.Base.UnitTests/VisualTree/MockRenderInterface.cs
  16. 2
      tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs

5
.editorconfig

@ -137,6 +137,11 @@ space_within_single_line_array_initializer_braces = true
#Net Analyzer #Net Analyzer
dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed. dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed.
# CA1802: Use literals where appropriate
dotnet_diagnostic.CA1802.severity = warning
# CA1825: Avoid zero-length array allocations
dotnet_diagnostic.CA1825.severity = warning
# Wrapping preferences # Wrapping preferences
csharp_wrap_before_ternary_opsigns = false csharp_wrap_before_ternary_opsigns = false

4
NOTICE.md

@ -111,7 +111,7 @@ DEALINGS IN THE SOFTWARE.
# Metsys.Bson # Metsys.Bson
Copyright (c) 2010, Karl Seguin - http://www.openmymind.net/ Copyright (c) 2010, Karl Seguin - https://www.openmymind.net/
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -302,4 +302,4 @@ https://github.com/chromium/chromium
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

2
src/Android/Avalonia.Android/AvaloniaView.cs

@ -74,7 +74,7 @@ namespace Avalonia.Android
class ViewImpl : TopLevelImpl class ViewImpl : TopLevelImpl
{ {
public ViewImpl(AvaloniaView avaloniaView) : base(avaloniaView, true) public ViewImpl(AvaloniaView avaloniaView) : base(avaloniaView)
{ {
View.Focusable = true; View.Focusable = true;
View.FocusChange += ViewImpl_FocusChange; View.FocusChange += ViewImpl_FocusChange;

2
src/Avalonia.Base/Media/TextFormatting/Unicode/GraphemeBreak.cs

@ -2,6 +2,6 @@ namespace Avalonia.Media.TextFormatting.Unicode
{ {
internal static class GraphemeBreak internal static class GraphemeBreak
{ {
public static byte[] Data => new byte[0]; public static byte[] Data => System.Array.Empty<byte>();
} }
} }

91
src/Avalonia.Controls/TextBox.cs

@ -18,6 +18,7 @@ using Avalonia.Media.TextFormatting;
using Avalonia.Media.TextFormatting.Unicode; using Avalonia.Media.TextFormatting.Unicode;
using Avalonia.Automation.Peers; using Avalonia.Automation.Peers;
using System.Diagnostics; using System.Diagnostics;
using Avalonia.Threading;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -159,18 +160,41 @@ namespace Avalonia.Controls
(o, v) => o.UndoLimit = v, (o, v) => o.UndoLimit = v,
unsetValue: -1); unsetValue: -1);
/// <summary>
/// Defines the <see cref="CopyingToClipboard"/> event.
/// </summary>
public static readonly RoutedEvent<RoutedEventArgs> CopyingToClipboardEvent = public static readonly RoutedEvent<RoutedEventArgs> CopyingToClipboardEvent =
RoutedEvent.Register<TextBox, RoutedEventArgs>( RoutedEvent.Register<TextBox, RoutedEventArgs>(
nameof(CopyingToClipboard), RoutingStrategies.Bubble); nameof(CopyingToClipboard), RoutingStrategies.Bubble);
/// <summary>
/// Defines the <see cref="CuttingToClipboard"/> event.
/// </summary>
public static readonly RoutedEvent<RoutedEventArgs> CuttingToClipboardEvent = public static readonly RoutedEvent<RoutedEventArgs> CuttingToClipboardEvent =
RoutedEvent.Register<TextBox, RoutedEventArgs>( RoutedEvent.Register<TextBox, RoutedEventArgs>(
nameof(CuttingToClipboard), RoutingStrategies.Bubble); nameof(CuttingToClipboard), RoutingStrategies.Bubble);
/// <summary>
/// Defines the <see cref="PastingFromClipboard"/> event.
/// </summary>
public static readonly RoutedEvent<RoutedEventArgs> PastingFromClipboardEvent = public static readonly RoutedEvent<RoutedEventArgs> PastingFromClipboardEvent =
RoutedEvent.Register<TextBox, RoutedEventArgs>( RoutedEvent.Register<TextBox, RoutedEventArgs>(
nameof(PastingFromClipboard), RoutingStrategies.Bubble); nameof(PastingFromClipboard), RoutingStrategies.Bubble);
/// <summary>
/// Defines the <see cref="TextChanged"/> event.
/// </summary>
public static readonly RoutedEvent<TextChangedEventArgs> TextChangedEvent =
RoutedEvent.Register<TextBox, TextChangedEventArgs>(
nameof(TextChanged), RoutingStrategies.Bubble);
/// <summary>
/// Defines the <see cref="TextChanging"/> event.
/// </summary>
public static readonly RoutedEvent<TextChangingEventArgs> TextChangingEvent =
RoutedEvent.Register<TextBox, TextChangingEventArgs>(
nameof(TextChanging), RoutingStrategies.Bubble);
readonly struct UndoRedoState : IEquatable<UndoRedoState> readonly struct UndoRedoState : IEquatable<UndoRedoState>
{ {
public string? Text { get; } public string? Text { get; }
@ -359,8 +383,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public double LineHeight public double LineHeight
{ {
get { return GetValue(LineHeightProperty); } get => GetValue(LineHeightProperty);
set { SetValue(LineHeightProperty, value); } set => SetValue(LineHeightProperty, value);
} }
[Content] [Content]
@ -376,11 +400,19 @@ namespace Avalonia.Controls
CaretIndex = CoerceCaretIndex(caretIndex, value); CaretIndex = CoerceCaretIndex(caretIndex, value);
SelectionStart = CoerceCaretIndex(selectionStart, value); SelectionStart = CoerceCaretIndex(selectionStart, value);
SelectionEnd = CoerceCaretIndex(selectionEnd, value); SelectionEnd = CoerceCaretIndex(selectionEnd, value);
if (SetAndRaise(TextProperty, ref _text, value) && IsUndoEnabled && !_isUndoingRedoing)
var textChanged = SetAndRaise(TextProperty, ref _text, value);
if (textChanged && IsUndoEnabled && !_isUndoingRedoing)
{ {
_undoRedoHelper.Clear(); _undoRedoHelper.Clear();
SnapshotUndoRedo(); // so we always have an initial state SnapshotUndoRedo(); // so we always have an initial state
} }
if (textChanged)
{
RaiseTextChangeEvents();
}
} }
} }
@ -564,6 +596,27 @@ namespace Avalonia.Controls
remove => RemoveHandler(PastingFromClipboardEvent, value); remove => RemoveHandler(PastingFromClipboardEvent, value);
} }
/// <summary>
/// Occurs asynchronously after text changes and the new text is rendered.
/// </summary>
public event EventHandler<TextChangedEventArgs>? TextChanged
{
add => AddHandler(TextChangedEvent, value);
remove => RemoveHandler(TextChangedEvent, value);
}
/// <summary>
/// Occurs synchronously when text starts to change but before it is rendered.
/// </summary>
/// <remarks>
/// This event occurs just after the <see cref="Text"/> property value has been updated.
/// </remarks>
public event EventHandler<TextChangingEventArgs>? TextChanging
{
add => AddHandler(TextChangingEvent, value);
remove => RemoveHandler(TextChangingEvent, value);
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e) protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{ {
_presenter = e.NameScope.Get<TextPresenter>("PART_TextPresenter"); _presenter = e.NameScope.Get<TextPresenter>("PART_TextPresenter");
@ -1252,7 +1305,7 @@ namespace Avalonia.Controls
if (text != null && _wordSelectionStart >= 0) if (text != null && _wordSelectionStart >= 0)
{ {
var distance = caretIndex - _wordSelectionStart; var distance = caretIndex - _wordSelectionStart;
if (distance <= 0) if (distance <= 0)
{ {
@ -1539,11 +1592,39 @@ namespace Avalonia.Controls
return text.Substring(start, end - start); return text.Substring(start, end - start);
} }
/// <summary>
/// Raises both the <see cref="TextChanging"/> and <see cref="TextChanged"/> events.
/// </summary>
/// <remarks>
/// This must be called after the <see cref="Text"/> property is set.
/// </remarks>
private void RaiseTextChangeEvents()
{
// Note the following sequence of these events (following WinUI)
// 1. TextChanging occurs synchronously when text starts to change but before it is rendered.
// This occurs after the Text property is set.
// 2. TextChanged occurs asynchronously after text changes and the new text is rendered.
var textChangingEventArgs = new TextChangingEventArgs(TextChangingEvent);
RaiseEvent(textChangingEventArgs);
Dispatcher.UIThread.Post(() =>
{
var textChangedEventArgs = new TextChangedEventArgs(TextChangedEvent);
RaiseEvent(textChangedEventArgs);
}, DispatcherPriority.Normal);
}
private void SetTextInternal(string value, bool raiseTextChanged = true) private void SetTextInternal(string value, bool raiseTextChanged = true)
{ {
if (raiseTextChanged) if (raiseTextChanged)
{ {
SetAndRaise(TextProperty, ref _text, value); bool textChanged = SetAndRaise(TextProperty, ref _text, value);
if (textChanged)
{
RaiseTextChangeEvents();
}
} }
else else
{ {

2
src/Avalonia.Controls/TextBoxTextInputMethodClient.cs

@ -64,7 +64,7 @@ namespace Avalonia.Controls
return new TextInputMethodSurroundingText return new TextInputMethodSurroundingText
{ {
Text = lineText ?? "", Text = lineText ?? "",
AnchorOffset = anchorOffset, AnchorOffset = anchorOffset,
CursorOffset = cursorOffset CursorOffset = cursorOffset
}; };

20
src/Avalonia.Controls/TextChangedEventArgs.cs

@ -0,0 +1,20 @@
using Avalonia.Interactivity;
namespace Avalonia.Controls
{
/// <summary>
/// Provides data specific to a TextChanged event.
/// </summary>
public class TextChangedEventArgs : RoutedEventArgs
{
public TextChangedEventArgs(RoutedEvent? routedEvent)
: base (routedEvent)
{
}
public TextChangedEventArgs(RoutedEvent? routedEvent, IInteractive? source)
: base(routedEvent, source)
{
}
}
}

20
src/Avalonia.Controls/TextChangingEventArgs.cs

@ -0,0 +1,20 @@
using Avalonia.Interactivity;
namespace Avalonia.Controls
{
/// <summary>
/// Provides data specific to a TextChanging event.
/// </summary>
public class TextChangingEventArgs : RoutedEventArgs
{
public TextChangingEventArgs(RoutedEvent? routedEvent)
: base (routedEvent)
{
}
public TextChangingEventArgs(RoutedEvent? routedEvent, IInteractive? source)
: base(routedEvent, source)
{
}
}
}

2
src/Avalonia.DesignerSupport/Remote/HtmlTransport/SimpleWebSocketHttpServer.cs

@ -140,7 +140,7 @@ namespace Avalonia.DesignerSupport.Remote.HtmlTransport
IsWebsocketRequest = true; IsWebsocketRequest = true;
if (headers.TryGetValue("Sec-WebSocket-Protocol", out h)) if (headers.TryGetValue("Sec-WebSocket-Protocol", out h))
WebSocketProtocols = h.Split(',').Select(x => x.Trim()).ToArray(); WebSocketProtocols = h.Split(',').Select(x => x.Trim()).ToArray();
else WebSocketProtocols = new string[0]; else WebSocketProtocols = Array.Empty<string>();
} }
} }

6
src/Avalonia.FreeDesktop/DBusMenuExporter.cs

@ -340,7 +340,7 @@ namespace Avalonia.FreeDesktop
{ {
var id = item == null ? 0 : GetId(item); var id = item == null ? 0 : GetId(item);
var props = GetProperties((item, menu), propertyNames); var props = GetProperties((item, menu), propertyNames);
var children = (depth == 0 || menu == null) ? new object[0] : new object[menu.Items.Count]; var children = (depth == 0 || menu == null) ? Array.Empty<object>() : new object[menu.Items.Count];
if(menu != null) if(menu != null)
for (var c = 0; c < children.Length; c++) for (var c = 0; c < children.Length; c++)
{ {
@ -397,7 +397,7 @@ namespace Avalonia.FreeDesktop
{ {
foreach (var e in Events) foreach (var e in Events)
HandleEvent(e.id, e.eventId, e.data, e.timestamp); HandleEvent(e.id, e.eventId, e.data, e.timestamp);
return Task.FromResult(new int[0]); return Task.FromResult(Array.Empty<int>());
} }
public async Task<bool> AboutToShowAsync(int Id) public async Task<bool> AboutToShowAsync(int Id)
@ -407,7 +407,7 @@ namespace Avalonia.FreeDesktop
public async Task<(int[] updatesNeeded, int[] idErrors)> AboutToShowGroupAsync(int[] Ids) public async Task<(int[] updatesNeeded, int[] idErrors)> AboutToShowGroupAsync(int[] Ids)
{ {
return (new int[0], new int[0]); return (Array.Empty<int>(), Array.Empty<int>());
} }
#region Events #region Events

2
src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs

@ -99,7 +99,7 @@ namespace Avalonia.LinuxFramebuffer.Output
// prepare for the new ioctl call // prepare for the new ioctl call
var handles = new uint[] {handle, 0, 0, 0}; var handles = new uint[] {handle, 0, 0, 0};
var pitches = new uint[] {stride, 0, 0, 0}; var pitches = new uint[] {stride, 0, 0, 0};
var offsets = new uint[] {}; var offsets = Array.Empty<uint>();
var ret = drmModeAddFB2(_card.Fd, w, h, format, handles, pitches, var ret = drmModeAddFB2(_card.Fd, w, h, format, handles, pitches,
offsets, out var fbHandle, 0); offsets, out var fbHandle, 0);

5
src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj

@ -5,6 +5,11 @@
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<PackageId>Avalonia.Markup.Xaml.Loader</PackageId> <PackageId>Avalonia.Markup.Xaml.Loader</PackageId>
<DefineConstants>$(DefineConstants);XAMLX_INTERNAL</DefineConstants> <DefineConstants>$(DefineConstants);XAMLX_INTERNAL</DefineConstants>
<LangVersion>10</LangVersion>
</PropertyGroup>
<!--Disable Net Perf. analyzer for submodule to avoid commit issue -->
<PropertyGroup>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
</PropertyGroup> </PropertyGroup>
<Import Project="IncludeXamlIlSre.props" /> <Import Project="IncludeXamlIlSre.props" />
<ItemGroup> <ItemGroup>

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

@ -241,8 +241,8 @@ namespace Avalonia.Win32
}); });
} }
private static readonly int SignalW = unchecked((int) 0xdeadbeaf); private const int SignalW = unchecked((int)0xdeadbeaf);
private static readonly int SignalL = unchecked((int)0x12345678); private const int SignalL = unchecked((int)0x12345678);
public void Signal(DispatcherPriority prio) public void Signal(DispatcherPriority prio)
{ {

4
src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj

@ -3,6 +3,10 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks> <TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<!--Disable Net Perf. analyzer for submodule to avoid commit issue -->
<PropertyGroup>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" /> <ProjectReference Include="..\..\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
<ProjectReference Include="..\..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" /> <ProjectReference Include="..\..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />

2
tests/Avalonia.Base.UnitTests/VisualTree/MockRenderInterface.cs

@ -235,7 +235,7 @@ namespace Avalonia.Base.UnitTests.VisualTree
public bool FillContains(Point point) public bool FillContains(Point point)
{ {
// Use the algorithm from http://www.blackpawn.com/texts/pointinpoly/default.html // Use the algorithm from https://www.blackpawn.com/texts/pointinpoly/default.html
// to determine if the point is in the geometry (since it will always be convex in this situation) // to determine if the point is in the geometry (since it will always be convex in this situation)
for (int i = 0; i < points.Count; i++) for (int i = 0; i < points.Count; i++)
{ {

2
tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs

@ -148,7 +148,7 @@ namespace Avalonia.UnitTests
public bool FillContains(Point point) public bool FillContains(Point point)
{ {
// Use the algorithm from http://www.blackpawn.com/texts/pointinpoly/default.html // Use the algorithm from https://www.blackpawn.com/texts/pointinpoly/default.html
// to determine if the point is in the geometry (since it will always be convex in this situation) // to determine if the point is in the geometry (since it will always be convex in this situation)
for (int i = 0; i < points.Count; i++) for (int i = 0; i < points.Count; i++)
{ {

Loading…
Cancel
Save