diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm index 908b9e1022c..3acc5e365b0 100644 --- a/native/Avalonia.Native/src/OSX/window.mm +++ b/native/Avalonia.Native/src/OSX/window.mm @@ -1283,6 +1283,9 @@ -(AvnWindow*) initWithParent: (WindowBaseImpl*) parent _closed = false; _lastScaling = [self backingScaleFactor]; + [self setOpaque:NO]; + [self setBackgroundColor: [NSColor clearColor]]; + [self invalidateShadow]; return self; } diff --git a/readme.md b/readme.md index 512b35a4549..97c65093620 100644 --- a/readme.md +++ b/readme.md @@ -22,7 +22,7 @@ Avalonia [Visual Studio Extension](https://marketplace.visualstudio.com/items?it For those without Visual Studio, a starter guide for .NET Core CLI can be found [here](http://avaloniaui.net/docs/quickstart/create-new-project#net-core). -Avalonia is delivered via NuGet package manager. You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Avalonia/), [nightly](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed)) +Avalonia is delivered via NuGet package manager. You can find the packages here: [stable(ish)](https://www.nuget.org/packages/Avalonia/) Use these commands in the Package Manager console to install Avalonia manually: ``` diff --git a/scripts/avalonia-rename.ps1 b/scripts/avalonia-rename.ps1 deleted file mode 100644 index c77dffb55da..00000000000 --- a/scripts/avalonia-rename.ps1 +++ /dev/null @@ -1,64 +0,0 @@ -function Get-NewDirectoryName { - param ([System.IO.DirectoryInfo]$item) - - $name = $item.Name.Replace("perspex", "avalonia") - $name = $name.Replace("Perspex", "Avalonia") - Join-Path $item.Parent.FullName $name -} - -function Get-NewFileName { - param ([System.IO.FileInfo]$item) - - $name = $item.Name.Replace("perspex", "avalonia") - $name = $name.Replace("Perspex", "Avalonia") - Join-Path $item.DirectoryName $name -} - -function Rename-Contents { - param ([System.IO.FileInfo] $file) - - $extensions = @(".cs",".xaml",".csproj",".sln",".md",".json",".yml",".partial",".ps1",".nuspec",".htm",".html",".gitmodules".".xml",".plist",".targets",".projitems",".shproj",".xib") - - if ($extensions.Contains($file.Extension)) { - $text = [IO.File]::ReadAllText($file.FullName) - $text = $text.Replace("github.com/perspex", "github.com/avaloniaui") - $text = $text.Replace("github.com/Perspex", "github.com/AvaloniaUI") - $text = $text.Replace("perspex", "avalonia") - $text = $text.Replace("Perspex", "Avalonia") - $text = $text.Replace("PERSPEX", "AVALONIA") - [IO.File]::WriteAllText($file.FullName, $text) - } -} - -function Process-Files { - param ([System.IO.DirectoryInfo] $item) - - $dirs = Get-ChildItem -Path $item.FullName -Directory - $files = Get-ChildItem -Path $item.FullName -File - - foreach ($dir in $dirs) { - Process-Files $dir.FullName - } - - foreach ($file in $files) { - Rename-Contents $file - - $renamed = Get-NewFileName $file - - if ($file.FullName -ne $renamed) { - Write-Host git mv $file.FullName $renamed - & git mv $file.FullName $renamed - } - } - - $renamed = Get-NewDirectoryName $item - - if ($item.FullName -ne $renamed) { - Write-Host git mv $item.FullName $renamed - & git mv $item.FullName $renamed - } -} - -& git submodule deinit . -& git clean -xdf -Process-Files . diff --git a/src/Avalonia.Animation/IterationCount.cs b/src/Avalonia.Animation/IterationCount.cs index e9cd0686d89..9f57455639c 100644 --- a/src/Avalonia.Animation/IterationCount.cs +++ b/src/Avalonia.Animation/IterationCount.cs @@ -63,7 +63,7 @@ public IterationCount(ulong value, IterationType type) public IterationType RepeatType => _type; /// - /// Gets a value that indicates whether the is set to loop. + /// Gets a value that indicates whether the is set to Infinite. /// public bool IsInfinite => _type == IterationType.Infinite; diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index c3eec851b99..fbac2e02ec1 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -403,12 +403,12 @@ protected override void OnKeyDown(KeyEventArgs e) bool movement = false; bool selection = false; bool handled = false; - var modifiers = e.Modifiers; + var modifiers = e.KeyModifiers; var keymap = AvaloniaLocator.Current.GetService(); bool Match(List gestures) => gestures.Any(g => g.Matches(e)); - bool DetectSelection() => e.Modifiers.HasFlag(keymap.SelectionModifiers); + bool DetectSelection() => e.KeyModifiers.HasFlag(keymap.SelectionModifiers); if (Match(keymap.SelectAll)) { diff --git a/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs b/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs index a758a328bed..053f8947553 100644 --- a/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs +++ b/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs @@ -4,14 +4,14 @@ namespace Avalonia.Input.Platform { public class PlatformHotkeyConfiguration { - public PlatformHotkeyConfiguration() : this(InputModifiers.Control) + public PlatformHotkeyConfiguration() : this(KeyModifiers.Control) { } - public PlatformHotkeyConfiguration(InputModifiers commandModifiers, - InputModifiers selectionModifiers = InputModifiers.Shift, - InputModifiers wholeWordTextActionModifiers = InputModifiers.Control) + public PlatformHotkeyConfiguration(KeyModifiers commandModifiers, + KeyModifiers selectionModifiers = KeyModifiers.Shift, + KeyModifiers wholeWordTextActionModifiers = KeyModifiers.Control) { CommandModifiers = commandModifiers; SelectionModifiers = selectionModifiers; @@ -75,9 +75,9 @@ public PlatformHotkeyConfiguration() : this(InputModifiers.Control) }; } - public InputModifiers CommandModifiers { get; set; } - public InputModifiers WholeWordTextActionModifiers { get; set; } - public InputModifiers SelectionModifiers { get; set; } + public KeyModifiers CommandModifiers { get; set; } + public KeyModifiers WholeWordTextActionModifiers { get; set; } + public KeyModifiers SelectionModifiers { get; set; } public List Copy { get; set; } public List Cut { get; set; } public List Paste { get; set; } diff --git a/src/Avalonia.Native/AvaloniaNativePlatform.cs b/src/Avalonia.Native/AvaloniaNativePlatform.cs index 571475c7eab..756619fa9f2 100644 --- a/src/Avalonia.Native/AvaloniaNativePlatform.cs +++ b/src/Avalonia.Native/AvaloniaNativePlatform.cs @@ -101,7 +101,7 @@ void DoInitialize(AvaloniaNativePlatformOptions options) .Bind().ToConstant(new DefaultRenderTimer(60)) .Bind().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs())) .Bind().ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature())) - .Bind().ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Windows)) + .Bind().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Meta)) .Bind().ToConstant(new MacOSMountedVolumeInfoProvider()); } diff --git a/src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs b/src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs index 68d56eeedde..5914bcb1fe3 100644 --- a/src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs +++ b/src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs @@ -307,7 +307,9 @@ private void Render(DrawingContext context, IVisual visual, Rect clipRect) if (!child.ClipToBounds || clipRect.Intersects(childBounds)) { - var childClipRect = clipRect.Translate(-childBounds.Position); + var childClipRect = child.RenderTransform == null + ? clipRect.Translate(-childBounds.Position) + : clipRect; Render(context, child, childClipRect); } else diff --git a/src/Avalonia.X11/X11Platform.cs b/src/Avalonia.X11/X11Platform.cs index 6ba562bb694..8b531bd9c52 100644 --- a/src/Avalonia.X11/X11Platform.cs +++ b/src/Avalonia.X11/X11Platform.cs @@ -44,7 +44,7 @@ public void Initialize(X11PlatformOptions options) .Bind().ToConstant(new X11PlatformThreading(this)) .Bind().ToConstant(new DefaultRenderTimer(60)) .Bind().ToConstant(new RenderLoop()) - .Bind().ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Control)) + .Bind().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Control)) .Bind().ToFunc(() => KeyboardDevice) .Bind().ToConstant(new X11CursorFactory(Display)) .Bind().ToConstant(new X11Clipboard(this)) diff --git a/tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests.cs b/tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests.cs index 73e4a145390..69c3f124e02 100644 --- a/tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests.cs +++ b/tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests.cs @@ -178,5 +178,141 @@ public void Should_Render_Child_In_Parent_With_RenderTransform2() Assert.Equal(1, rendered); } + + [Fact] + public void Should_Not_Clip_Children_With_RenderTransform_When_In_Bounds() + { + const int RootWidth = 300; + const int RootHeight = 300; + + var rootGrid = new Grid + { + Width = RootWidth, + Height = RootHeight, + ClipToBounds = true + }; + + var stackPanel = new StackPanel + { + Orientation = Orientation.Horizontal, + VerticalAlignment = VerticalAlignment.Top, + HorizontalAlignment = HorizontalAlignment.Right, + Margin = new Thickness(0, 10, 0, 0), + RenderTransformOrigin = new RelativePoint(new Point(0, 0), RelativeUnit.Relative), + RenderTransform = new TransformGroup + { + Children = + { + new RotateTransform { Angle = 90 }, + new TranslateTransform { X = 240 } + } + } + }; + + rootGrid.Children.Add(stackPanel); + + TestControl CreateControl() + => new TestControl + { + Width = 80, + Height = 40, + Margin = new Thickness(0, 0, 5, 0), + ClipToBounds = true + }; + + var control1 = CreateControl(); + var control2 = CreateControl(); + var control3 = CreateControl(); + + stackPanel.Children.Add(control1); + stackPanel.Children.Add(control2); + stackPanel.Children.Add(control3); + + var root = new TestRoot(rootGrid); + root.Renderer = new ImmediateRenderer(root); + root.LayoutManager.ExecuteInitialLayoutPass(root); + + var rootSize = new Size(RootWidth, RootHeight); + root.Measure(rootSize); + root.Arrange(new Rect(rootSize)); + + root.Renderer.Paint(root.Bounds); + + Assert.True(control1.Rendered); + Assert.True(control2.Rendered); + Assert.True(control3.Rendered); + } + + [Fact] + public void Should_Not_Render_Clipped_Child_With_RenderTransform_When_Not_In_Bounds() + { + const int RootWidth = 300; + const int RootHeight = 300; + + var rootGrid = new Grid + { + Width = RootWidth, + Height = RootHeight, + ClipToBounds = true + }; + + var stackPanel = new StackPanel + { + Orientation = Orientation.Horizontal, + VerticalAlignment = VerticalAlignment.Top, + HorizontalAlignment = HorizontalAlignment.Right, + Margin = new Thickness(0, 10, 0, 0), + RenderTransformOrigin = new RelativePoint(new Point(0, 0), RelativeUnit.Relative), + RenderTransform = new TransformGroup + { + Children = + { + new RotateTransform { Angle = 90 }, + new TranslateTransform { X = 280 } + } + } + }; + + rootGrid.Children.Add(stackPanel); + + TestControl CreateControl() + => new TestControl + { + Width = 160, + Height = 40, + Margin = new Thickness(0, 0, 5, 0), + ClipToBounds = true + }; + + var control1 = CreateControl(); + var control2 = CreateControl(); + var control3 = CreateControl(); + + stackPanel.Children.Add(control1); + stackPanel.Children.Add(control2); + stackPanel.Children.Add(control3); + + var root = new TestRoot(rootGrid); + root.Renderer = new ImmediateRenderer(root); + root.LayoutManager.ExecuteInitialLayoutPass(root); + + var rootSize = new Size(RootWidth, RootHeight); + root.Measure(rootSize); + root.Arrange(new Rect(rootSize)); + + root.Renderer.Paint(root.Bounds); + + Assert.True(control1.Rendered); + Assert.True(control2.Rendered); + Assert.False(control3.Rendered); + } + + private class TestControl : Control + { + public bool Rendered { get; private set; } + + public override void Render(DrawingContext context) + => Rendered = true; + } } }