Browse Source

Merge branch 'master' into wpf-integration

Conflicts:
	src/Avalonia.Layout/LayoutManager.cs
Nikita Tsukanov 8 years ago
parent
commit
d63c074bd3

+ 1 - 1
build/SkiaSharp.props

@@ -1,6 +1,6 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <PackageReference Include="SkiaSharp" Version="1.57.1" />
-    <PackageReference Condition="$(TargetFramework.Trim('.').ToLower().StartsWith('netframework'))" Include="Avalonia.Skia.Linux.Natives" Version="1.57.1.3" />
+    <PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="Avalonia.Skia.Linux.Natives" Version="1.57.1.3" />
   </ItemGroup>
 </Project>

+ 8 - 1
src/Avalonia.Controls/WindowBase.cs

@@ -29,6 +29,7 @@ namespace Avalonia.Controls
         public static readonly DirectProperty<WindowBase, bool> IsActiveProperty =
             AvaloniaProperty.RegisterDirect<WindowBase, bool>(nameof(IsActive), o => o.IsActive);
 
+        private bool _hasExecutedInitialLayoutPass;
         private bool _isActive;
         private bool _ignoreVisibilityChange;
 
@@ -136,7 +137,13 @@ namespace Avalonia.Controls
             {
                 EnsureInitialized();
                 IsVisible = true;
-                LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+
+                if (!_hasExecutedInitialLayoutPass)
+                {
+                    LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+                    _hasExecutedInitialLayoutPass = true;
+                }
+
                 PlatformImpl?.Show();
             }
             finally

+ 5 - 1
src/Avalonia.Layout/LayoutManager.cs

@@ -190,8 +190,12 @@ namespace Avalonia.Layout
                     control.Arrange(new Rect(embeddedRoot.AllocatedSize));
                 else if (control is ILayoutRoot root)
                     control.Arrange(new Rect(root.DesiredSize));
-                else
+                else if (control.PreviousArrange != null)
+                {
+                    // Has been observed that PreviousArrange sometimes is null, probably a bug somewhere else.
+                    // Condition observed: control.VisualParent is Scrollbar, control is Border.
                     control.Arrange(control.PreviousArrange.Value);
+                }
             }
         }
 

+ 18 - 0
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@@ -500,6 +500,24 @@ namespace Avalonia.Gtk3.Interop
         public gdouble delta_y;
     }
 
+    [StructLayout(LayoutKind.Sequential)]
+    unsafe  struct GdkEventCrossing 
+    {
+        public GdkEventType type;
+        public IntPtr window;
+        public gint8 send_event;
+        public IntPtr subwindow;
+        public guint32 time;
+        public gdouble x;
+        public gdouble y;
+        public gdouble x_root;
+        public gdouble y_root;
+        public int mode;
+        public int detail;
+        public bool focus;
+        public GdkModifierType state;
+    };
+    
     [StructLayout(LayoutKind.Sequential)]
     unsafe struct GdkEventWindowState
     {

+ 13 - 0
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@@ -45,6 +45,7 @@ namespace Avalonia.Gtk3
             ConnectEvent("window-state-event", OnStateChanged);
             ConnectEvent("key-press-event", OnKeyEvent);
             ConnectEvent("key-release-event", OnKeyEvent);
+            ConnectEvent("leave-notify-event", OnLeaveNotifyEvent);
             Connect<Native.D.signal_generic>("destroy", OnDestroy);
             Native.GtkWidgetRealize(gtkWidget);
             _lastSize = ClientSize;
@@ -194,6 +195,18 @@ namespace Avalonia.Gtk3
             return true;
         }
 
+        private unsafe bool OnLeaveNotifyEvent(IntPtr w, IntPtr pev, IntPtr userData)
+        {
+            var evnt = (GdkEventCrossing*) pev;
+            var position = new Point(evnt->x, evnt->y);
+            Input(new RawMouseEventArgs(Gtk3Platform.Mouse,
+                evnt->time,
+                _inputRoot,
+                RawMouseEventType.Move,
+                position, GetModifierKeys(evnt->state)));
+            return true;
+        }
+
         private unsafe bool OnCommit(IntPtr gtkwidget, IntPtr utf8string, IntPtr userdata)
         {
             Input(new RawTextInputEventArgs(Gtk3Platform.Keyboard, _lastKbdEvent, Utf8Buffer.StringFromPtr(utf8string)));

+ 2 - 1
src/Skia/Avalonia.Skia.Desktop.NetStandard/Avalonia.Skia.Desktop.NetStandard.csproj

@@ -5,6 +5,7 @@
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <RootNamespace>Avalonia.Skia.Desktop</RootNamespace>
     <AssemblyName>Avalonia.Skia.Desktop</AssemblyName>
+    <IncludeLinuxSkia>true</IncludeLinuxSkia>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <DebugSymbols>true</DebugSymbols>
@@ -42,4 +43,4 @@
   <Import Project="..\..\..\build\SkiaSharp.props" />
   <Import Project="..\Avalonia.Skia\Avalonia.Skia.projitems" Label="Shared" />
   <Import Project="..\..\Shared\RenderHelpers\RenderHelpers.projitems" Label="Shared" />
-</Project>
+</Project>

+ 4 - 1
src/Skia/Avalonia.Skia.Desktop/Avalonia.Skia.Desktop.csproj

@@ -54,6 +54,9 @@
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
+  <PropertyGroup>
+    <IncludeLinuxSkia>true</IncludeLinuxSkia>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
     <Reference Include="System.Core" />
@@ -107,4 +110,4 @@
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\..\build\SkiaSharp.props" />
   <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
-</Project>
+</Project>

+ 76 - 0
tests/Avalonia.RenderTests/Media/ImageBrushTests.cs

@@ -28,6 +28,82 @@ namespace Avalonia.Direct2D1.RenderTests.Media
             get { return System.IO.Path.Combine(OutputPath, "github_icon.png"); }
         }
 
+        private string SmallBitmapPath
+        {
+            get { return System.IO.Path.Combine(OutputPath, "github_icon_small.png"); }
+        }
+
+        [Fact]
+        public void ImageBrush_Tile_Fill()
+        {
+            Decorator target = new Decorator
+            {
+                Width = 200,
+                Height = 200,
+                Child = new Rectangle
+                {
+                    Margin = new Thickness(8),
+                    Fill = new ImageBrush
+                    {
+                        Stretch = Stretch.Fill,
+                        TileMode = TileMode.Tile,
+                        DestinationRect = new RelativeRect(0, 0, 25, 30, RelativeUnit.Absolute),
+                        Source = new Bitmap(BitmapPath),
+                    }
+                }
+            };
+
+            RenderToFile(target);
+            CompareImages();
+        }
+
+        [Fact]
+        public void ImageBrush_Tile_UniformToFill()
+        {
+            Decorator target = new Decorator
+            {
+                Width = 200,
+                Height = 200,
+                Child = new Rectangle
+                {
+                    Margin = new Thickness(8),
+                    Fill = new ImageBrush
+                    {
+                        Stretch = Stretch.Uniform,
+                        TileMode = TileMode.Tile,
+                        DestinationRect = new RelativeRect(0, 0, 25, 30, RelativeUnit.Absolute),
+                        Source = new Bitmap(BitmapPath),
+                    }
+                }
+            };
+
+            RenderToFile(target);
+            CompareImages();
+        }
+
+        [Fact]
+        public void ImageBrush_Tile_Small_Image()
+        {
+            Decorator target = new Decorator
+            {
+                Width = 200,
+                Height = 200,
+                Child = new Rectangle
+                {
+                    Margin = new Thickness(8),
+                    Fill = new ImageBrush
+                    {
+                        Stretch = Stretch.None,
+                        TileMode = TileMode.Tile,
+                        Source = new Bitmap(SmallBitmapPath),
+                    }
+                }
+            };
+
+            RenderToFile(target);
+            CompareImages();
+        }
+
         [Fact]
         public void ImageBrush_NoStretch_NoTile_Alignment_TopLeft()
         {

BIN
tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Tile_Fill.expected.png


BIN
tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Tile_Small_Image.expected.png


BIN
tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Tile_UniformToFill.expected.png


BIN
tests/TestFiles/Cairo/Media/ImageBrush/github_icon_small.png


BIN
tests/TestFiles/Direct2D1/Media/ImageBrush/ImageBrush_Tile_Fill.expected.png


BIN
tests/TestFiles/Direct2D1/Media/ImageBrush/ImageBrush_Tile_Small_Image.expected.png


BIN
tests/TestFiles/Direct2D1/Media/ImageBrush/ImageBrush_Tile_UniformToFill.expected.png


BIN
tests/TestFiles/Direct2D1/Media/ImageBrush/github_icon_small.png


BIN
tests/TestFiles/Skia/Media/ImageBrush/ImageBrush_Tile_Fill.expected.png


BIN
tests/TestFiles/Skia/Media/ImageBrush/ImageBrush_Tile_Small_Image.expected.png


BIN
tests/TestFiles/Skia/Media/ImageBrush/ImageBrush_Tile_UniformToFill.expected.png


BIN
tests/TestFiles/Skia/Media/ImageBrush/github_icon_small.png