committed by
GitHub
183 changed files with 10261 additions and 588 deletions
@ -0,0 +1,5 @@ |
|||||
|
<ProjectConfiguration> |
||||
|
<Settings> |
||||
|
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
||||
|
</Settings> |
||||
|
</ProjectConfiguration> |
||||
@ -0,0 +1,5 @@ |
|||||
|
<ProjectConfiguration> |
||||
|
<Settings> |
||||
|
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
||||
|
</Settings> |
||||
|
</ProjectConfiguration> |
||||
@ -0,0 +1,8 @@ |
|||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<Import Project="$(MSBuildThisFileDirectory)/NetFX.props" /> |
||||
|
<ItemGroup Condition="$(TargetFramework.StartsWith('net4'))"> |
||||
|
<Content Include="$(MSBuildThisFileDirectory)/xunit.runner.mono.json" Link="xunit.runner.json" > |
||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
||||
|
</Content> |
||||
|
</ItemGroup> |
||||
|
</Project> |
||||
@ -0,0 +1 @@ |
|||||
|
{ "appDomain": "denied" } |
||||
@ -1,7 +1,7 @@ |
|||||
{ |
{ |
||||
"msbuild-sdks": { |
"msbuild-sdks": { |
||||
"Microsoft.Build.Traversal": "1.0.43", |
"Microsoft.Build.Traversal": "1.0.43", |
||||
"MSBuild.Sdk.Extras": "1.6.46", |
"MSBuild.Sdk.Extras": "1.6.65", |
||||
"AggregatePackage.NuGet.Sdk" : "0.1.12" |
"AggregatePackage.NuGet.Sdk" : "0.1.12" |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,6 @@ |
|||||
|
<Application xmlns="https://github.com/avaloniaui"> |
||||
|
<Application.Styles> |
||||
|
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/> |
||||
|
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/> |
||||
|
</Application.Styles> |
||||
|
</Application> |
||||
@ -0,0 +1,13 @@ |
|||||
|
using Avalonia; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
|
||||
|
namespace PlatformSanityChecks |
||||
|
{ |
||||
|
public class App : Application |
||||
|
{ |
||||
|
public override void Initialize() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<OutputType>Exe</OutputType> |
||||
|
<TargetFramework>netcoreapp2.0</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Desktop\Avalonia.Desktop.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.X11\Avalonia.X11.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,132 @@ |
|||||
|
using System; |
||||
|
using System.Diagnostics; |
||||
|
using System.Reactive.Disposables; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Threading; |
||||
|
using Avalonia; |
||||
|
using Avalonia.Platform; |
||||
|
using Avalonia.Threading; |
||||
|
using Avalonia.X11; |
||||
|
|
||||
|
namespace PlatformSanityChecks |
||||
|
{ |
||||
|
public class Program |
||||
|
{ |
||||
|
static Thread UiThread; |
||||
|
|
||||
|
static void Main(string[] args) |
||||
|
{ |
||||
|
UiThread = Thread.CurrentThread; |
||||
|
AppBuilder.Configure<App>().RuntimePlatformServicesInitializer(); |
||||
|
var app = new App(); |
||||
|
|
||||
|
AvaloniaX11PlatformExtensions.InitializeX11Platform(); |
||||
|
|
||||
|
CheckPlatformThreading(); |
||||
|
} |
||||
|
|
||||
|
static bool CheckAccess() => UiThread == Thread.CurrentThread; |
||||
|
|
||||
|
static void VerifyAccess() |
||||
|
{ |
||||
|
if (!CheckAccess()) |
||||
|
Die("Call from invalid thread"); |
||||
|
} |
||||
|
|
||||
|
static Exception Die(string error) |
||||
|
{ |
||||
|
Console.Error.WriteLine(error); |
||||
|
Console.Error.WriteLine(Environment.StackTrace); |
||||
|
Process.GetCurrentProcess().Kill(); |
||||
|
throw new Exception(error); |
||||
|
} |
||||
|
|
||||
|
static IDisposable Enter([CallerMemberName] string caller = null) |
||||
|
{ |
||||
|
Console.WriteLine("Entering " + caller); |
||||
|
return Disposable.Create(() => { Console.WriteLine("Leaving " + caller); }); |
||||
|
} |
||||
|
|
||||
|
static void EnterLoop(Action<CancellationTokenSource> cb, [CallerMemberName] string caller = null) |
||||
|
{ |
||||
|
using (Enter(caller)) |
||||
|
{ |
||||
|
var cts = new CancellationTokenSource(); |
||||
|
cb(cts); |
||||
|
Dispatcher.UIThread.MainLoop(cts.Token); |
||||
|
if (!cts.IsCancellationRequested) |
||||
|
Die("Unexpected loop exit"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static void CheckTimerOrdering() => EnterLoop(cts => |
||||
|
{ |
||||
|
bool firstFired = false, secondFired = false; |
||||
|
DispatcherTimer.Run(() => |
||||
|
{ |
||||
|
Console.WriteLine("Second tick"); |
||||
|
VerifyAccess(); |
||||
|
if (!firstFired) |
||||
|
throw Die("Invalid timer ordering"); |
||||
|
if (secondFired) |
||||
|
throw Die("Invocation of finished timer"); |
||||
|
secondFired = true; |
||||
|
cts.Cancel(); |
||||
|
return false; |
||||
|
}, TimeSpan.FromSeconds(2)); |
||||
|
DispatcherTimer.Run(() => |
||||
|
{ |
||||
|
Console.WriteLine("First tick"); |
||||
|
VerifyAccess(); |
||||
|
if (secondFired) |
||||
|
throw Die("Invalid timer ordering"); |
||||
|
if (firstFired) |
||||
|
throw Die("Invocation of finished timer"); |
||||
|
firstFired = true; |
||||
|
return false; |
||||
|
}, TimeSpan.FromSeconds(1)); |
||||
|
}); |
||||
|
|
||||
|
static void CheckTimerTicking() => EnterLoop(cts => |
||||
|
{ |
||||
|
int ticks = 0; |
||||
|
var st = Stopwatch.StartNew(); |
||||
|
DispatcherTimer.Run(() => |
||||
|
{ |
||||
|
ticks++; |
||||
|
Console.WriteLine($"Tick {ticks} at {st.Elapsed}"); |
||||
|
if (ticks == 5) |
||||
|
{ |
||||
|
if (st.Elapsed.TotalSeconds < 4.5) |
||||
|
Die("Timer is too fast"); |
||||
|
if (st.Elapsed.TotalSeconds > 6) |
||||
|
Die("Timer is too slow"); |
||||
|
cts.Cancel(); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
}, TimeSpan.FromSeconds(1)); |
||||
|
}); |
||||
|
|
||||
|
static void CheckSignaling() => EnterLoop(cts => |
||||
|
{ |
||||
|
ThreadPool.QueueUserWorkItem(_ => |
||||
|
{ |
||||
|
Thread.Sleep(100); |
||||
|
Dispatcher.UIThread.Post(() => |
||||
|
{ |
||||
|
VerifyAccess(); |
||||
|
cts.Cancel(); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
static void CheckPlatformThreading() |
||||
|
{ |
||||
|
CheckSignaling(); |
||||
|
CheckTimerOrdering(); |
||||
|
CheckTimerTicking(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.Controls |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides <see cref="PixelPoint"/> data for events.
|
||||
|
/// </summary>
|
||||
|
public class PixelPointEventArgs : EventArgs |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PixelPointEventArgs"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="point">The <see cref=PixelPoint"/> data.</param>
|
||||
|
public PixelPointEventArgs(PixelPoint point) |
||||
|
{ |
||||
|
Point = point; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="PixelPoint"/> data.
|
||||
|
/// </summary>
|
||||
|
public PixelPoint Point { get; } |
||||
|
} |
||||
|
} |
||||
@ -1,27 +0,0 @@ |
|||||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|
||||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
namespace Avalonia.Controls |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides <see cref="Point"/> data for events.
|
|
||||
/// </summary>
|
|
||||
public class PointEventArgs : EventArgs |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="PointEventArgs"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The <see cref="Point"/> data.</param>
|
|
||||
public PointEventArgs(Point point) |
|
||||
{ |
|
||||
Point = point; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the <see cref="Point"/> data.
|
|
||||
/// </summary>
|
|
||||
public Point Point { get; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,14 +1,14 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
<Project Sdk="Microsoft.NET.Sdk"> |
||||
<PropertyGroup> |
<PropertyGroup> |
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks> |
<TargetFramework>netstandard2.0</TargetFramework> |
||||
</PropertyGroup> |
</PropertyGroup> |
||||
|
|
||||
<ItemGroup> |
<ItemGroup> |
||||
<ProjectReference Include="../../src/Windows/Avalonia.Win32/Avalonia.Win32.csproj" /> |
<ProjectReference Include="../../src/Windows/Avalonia.Win32/Avalonia.Win32.csproj" /> |
||||
<ProjectReference Include="../../src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj" /> |
<ProjectReference Include="../../src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj" /> |
||||
<ProjectReference Include="../../src/Skia/Avalonia.Skia/Avalonia.Skia.csproj" /> |
<ProjectReference Include="../../src/Skia/Avalonia.Skia/Avalonia.Skia.csproj" /> |
||||
<ProjectReference Include="../../src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj" /> |
|
||||
<ProjectReference Include="../../src/Avalonia.Native/Avalonia.Native.csproj" /> |
<ProjectReference Include="../../src/Avalonia.Native/Avalonia.Native.csproj" /> |
||||
<ProjectReference Include="../../packages/Avalonia/Avalonia.csproj" /> |
<ProjectReference Include="../../packages/Avalonia/Avalonia.csproj" /> |
||||
|
<ProjectReference Include="../Avalonia.X11/Avalonia.X11.csproj" /> |
||||
</ItemGroup> |
</ItemGroup> |
||||
</Project> |
</Project> |
||||
|
|||||
@ -0,0 +1,21 @@ |
|||||
|
namespace Avalonia.OpenGL |
||||
|
{ |
||||
|
public enum EglErrors |
||||
|
{ |
||||
|
EGL_SUCCESS = EglConsts.EGL_SUCCESS, |
||||
|
EGL_NOT_INITIALIZED = EglConsts.EGL_NOT_INITIALIZED, |
||||
|
EGL_BAD_ACCESS = EglConsts.EGL_BAD_ACCESS, |
||||
|
EGL_BAD_ALLOC = EglConsts.EGL_BAD_ALLOC, |
||||
|
EGL_BAD_ATTRIBUTE = EglConsts.EGL_BAD_ATTRIBUTE, |
||||
|
EGL_BAD_CONTEXT = EglConsts.EGL_BAD_CONTEXT, |
||||
|
EGL_BAD_CONFIG = EglConsts.EGL_BAD_CONFIG, |
||||
|
EGL_BAD_CURRENT_SURFACE = EglConsts.EGL_BAD_CURRENT_SURFACE, |
||||
|
EGL_BAD_DISPLAY = EglConsts.EGL_BAD_DISPLAY, |
||||
|
EGL_BAD_SURFACE = EglConsts.EGL_BAD_SURFACE, |
||||
|
EGL_BAD_MATCH = EglConsts.EGL_BAD_MATCH, |
||||
|
EGL_BAD_PARAMETER = EglConsts.EGL_BAD_PARAMETER, |
||||
|
EGL_BAD_NATIVE_PIXMAP = EglConsts.EGL_BAD_NATIVE_PIXMAP, |
||||
|
EGL_BAD_NATIVE_WINDOW = EglConsts.EGL_BAD_NATIVE_WINDOW, |
||||
|
EGL_CONTEXT_LOST = EglConsts.EGL_CONTEXT_LOST |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
namespace Avalonia.OpenGL |
||||
|
{ |
||||
|
public enum GlErrors |
||||
|
{ |
||||
|
GL_NO_ERROR = GlConsts.GL_NO_ERROR, |
||||
|
GL_INVALID_ENUM = GlConsts.GL_INVALID_ENUM, |
||||
|
GL_INVALID_VALUE = GlConsts.GL_INVALID_VALUE, |
||||
|
GL_INVALID_OPERATION = GlConsts.GL_INVALID_OPERATION, |
||||
|
GL_INVALID_FRAMEBUFFER_OPERATION = GlConsts.GL_INVALID_FRAMEBUFFER_OPERATION, |
||||
|
GL_STACK_OVERFLOW = GlConsts.GL_STACK_OVERFLOW, |
||||
|
GL_STACK_UNDERFLOW = GlConsts.GL_STACK_UNDERFLOW, |
||||
|
GL_OUT_OF_MEMORY = GlConsts.GL_OUT_OF_MEMORY, |
||||
|
GL_CONTEXT_LOST = GlConsts.GL_CONTEXT_LOST |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,201 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
using Avalonia.Utilities; |
||||
|
|
||||
|
namespace Avalonia |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a point in device pixels.
|
||||
|
/// </summary>
|
||||
|
public readonly struct PixelPoint |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A point representing 0,0.
|
||||
|
/// </summary>
|
||||
|
public static readonly PixelPoint Origin = new PixelPoint(0, 0); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PixelPoint"/> structure.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The X co-ordinate.</param>
|
||||
|
/// <param name="y">The Y co-ordinate.</param>
|
||||
|
public PixelPoint(int x, int y) |
||||
|
{ |
||||
|
X = x; |
||||
|
Y = y; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the X co-ordinate.
|
||||
|
/// </summary>
|
||||
|
public int X { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the Y co-ordinate.
|
||||
|
/// </summary>
|
||||
|
public int Y { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks for equality between two <see cref="PixelPoint"/>s.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The first point.</param>
|
||||
|
/// <param name="right">The second point.</param>
|
||||
|
/// <returns>True if the points are equal; otherwise false.</returns>
|
||||
|
public static bool operator ==(PixelPoint left, PixelPoint right) |
||||
|
{ |
||||
|
return left.X == right.X && left.Y == right.Y; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks for inequality between two <see cref="PixelPoint"/>s.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The first point.</param>
|
||||
|
/// <param name="right">The second point.</param>
|
||||
|
/// <returns>True if the points are unequal; otherwise false.</returns>
|
||||
|
public static bool operator !=(PixelPoint left, PixelPoint right) |
||||
|
{ |
||||
|
return !(left == right); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Parses a <see cref="PixelPoint"/> string.
|
||||
|
/// </summary>
|
||||
|
/// <param name="s">The string.</param>
|
||||
|
/// <returns>The <see cref="PixelPoint"/>.</returns>
|
||||
|
public static PixelPoint Parse(string s) |
||||
|
{ |
||||
|
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelPoint")) |
||||
|
{ |
||||
|
return new PixelPoint( |
||||
|
tokenizer.ReadInt32(), |
||||
|
tokenizer.ReadInt32()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks for equality between a point and an object.
|
||||
|
/// </summary>
|
||||
|
/// <param name="obj">The object.</param>
|
||||
|
/// <returns>
|
||||
|
/// True if <paramref name="obj"/> is a point that equals the current point.
|
||||
|
/// </returns>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (obj is PixelPoint other) |
||||
|
{ |
||||
|
return this == other; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a hash code for a <see cref="PixelPoint"/>.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The hash code.</returns>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
unchecked |
||||
|
{ |
||||
|
int hash = 17; |
||||
|
hash = (hash * 23) + X.GetHashCode(); |
||||
|
hash = (hash * 23) + Y.GetHashCode(); |
||||
|
return hash; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a new <see cref="PixelPoint"/> with the same Y co-ordinate and the specified X co-ordinate.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The X co-ordinate.</param>
|
||||
|
/// <returns>The new <see cref="PixelPoint"/>.</returns>
|
||||
|
public PixelPoint WithX(int x) => new PixelPoint(x, Y); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a new <see cref="PixelPoint"/> with the same X co-ordinate and the specified Y co-ordinate.
|
||||
|
/// </summary>
|
||||
|
/// <param name="y">The Y co-ordinate.</param>
|
||||
|
/// <returns>The new <see cref="PixelPoint"/>.</returns>
|
||||
|
public PixelPoint WithY(int y) => new PixelPoint(X, y); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the <see cref="PixelPoint"/> to a device-independent <see cref="Point"/> using the
|
||||
|
/// specified scaling factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="scale">The scaling factor.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public Point ToPoint(double scale) => new Point(X / scale, Y / scale); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the <see cref="PixelPoint"/> to a device-independent <see cref="Point"/> using the
|
||||
|
/// specified scaling factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="scale">The scaling factor.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public Point ToPoint(Vector scale) => new Point(X / scale.X, Y / scale.Y); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the <see cref="PixelPoint"/> to a device-independent <see cref="Point"/> using the
|
||||
|
/// specified dots per inch (DPI).
|
||||
|
/// </summary>
|
||||
|
/// <param name="dpi">The dots per inch of the device.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public Point ToPointWithDpi(double dpi) => ToPoint(dpi / 96); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the <see cref="PixelPoint"/> to a device-independent <see cref="Point"/> using the
|
||||
|
/// specified dots per inch (DPI).
|
||||
|
/// </summary>
|
||||
|
/// <param name="dpi">The dots per inch of the device.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public Point ToPointWithDpi(Vector dpi) => ToPoint(new Vector(dpi.X / 96, dpi.Y / 96)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Point"/> to device pixels using the specified scaling factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="point">The point.</param>
|
||||
|
/// <param name="scale">The scaling factor.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public static PixelPoint FromPoint(Point point, double scale) => new PixelPoint( |
||||
|
(int)(point.X * scale), |
||||
|
(int)(point.Y * scale)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Point"/> to device pixels using the specified scaling factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="point">The point.</param>
|
||||
|
/// <param name="scale">The scaling factor.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public static PixelPoint FromPoint(Point point, Vector scale) => new PixelPoint( |
||||
|
(int)(point.X * scale.X), |
||||
|
(int)(point.Y * scale.Y)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Point"/> to device pixels using the specified dots per inch (DPI).
|
||||
|
/// </summary>
|
||||
|
/// <param name="point">The point.</param>
|
||||
|
/// <param name="dpi">The dots per inch of the device.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public static PixelPoint FromPointWithDpi(Point point, double dpi) => FromPoint(point, dpi / 96); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Point"/> to device pixels using the specified dots per inch (DPI).
|
||||
|
/// </summary>
|
||||
|
/// <param name="point">The point.</param>
|
||||
|
/// <param name="dpi">The dots per inch of the device.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public static PixelPoint FromPointWithDpi(Point point, Vector dpi) => FromPoint(point, new Vector(dpi.X / 96, dpi.Y / 96)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the string representation of the point.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The string representation of the point.</returns>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, "{0}, {1}", X, Y); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,436 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
using Avalonia.Utilities; |
||||
|
|
||||
|
namespace Avalonia |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a rectangle in device pixels.
|
||||
|
/// </summary>
|
||||
|
public readonly struct PixelRect |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// An empty rectangle.
|
||||
|
/// </summary>
|
||||
|
public static readonly PixelRect Empty = default; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PixelRect"/> structure.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The X position.</param>
|
||||
|
/// <param name="y">The Y position.</param>
|
||||
|
/// <param name="width">The width.</param>
|
||||
|
/// <param name="height">The height.</param>
|
||||
|
public PixelRect(int x, int y, int width, int height) |
||||
|
{ |
||||
|
X = x; |
||||
|
Y = y; |
||||
|
Width = width; |
||||
|
Height = height; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PixelRect"/> structure.
|
||||
|
/// </summary>
|
||||
|
/// <param name="size">The size of the rectangle.</param>
|
||||
|
public PixelRect(PixelSize size) |
||||
|
{ |
||||
|
X = 0; |
||||
|
Y = 0; |
||||
|
Width = size.Width; |
||||
|
Height = size.Height; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PixelRect"/> structure.
|
||||
|
/// </summary>
|
||||
|
/// <param name="position">The position of the rectangle.</param>
|
||||
|
/// <param name="size">The size of the rectangle.</param>
|
||||
|
public PixelRect(PixelPoint position, PixelSize size) |
||||
|
{ |
||||
|
X = position.X; |
||||
|
Y = position.Y; |
||||
|
Width = size.Width; |
||||
|
Height = size.Height; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PixelRect"/> structure.
|
||||
|
/// </summary>
|
||||
|
/// <param name="topLeft">The top left position of the rectangle.</param>
|
||||
|
/// <param name="bottomRight">The bottom right position of the rectangle.</param>
|
||||
|
public PixelRect(PixelPoint topLeft, PixelPoint bottomRight) |
||||
|
{ |
||||
|
X = topLeft.X; |
||||
|
Y = topLeft.Y; |
||||
|
Width = bottomRight.X - topLeft.X; |
||||
|
Height = bottomRight.Y - topLeft.Y; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the X position.
|
||||
|
/// </summary>
|
||||
|
public int X { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the Y position.
|
||||
|
/// </summary>
|
||||
|
public int Y { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the width.
|
||||
|
/// </summary>
|
||||
|
public int Width { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the height.
|
||||
|
/// </summary>
|
||||
|
public int Height { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the position of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public PixelPoint Position => new PixelPoint(X, Y); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the size of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public PixelSize Size => new PixelSize(Width, Height); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the right position of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public int Right => X + Width; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the bottom position of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public int Bottom => Y + Height; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the top left point of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public PixelPoint TopLeft => new PixelPoint(X, Y); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the top right point of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public PixelPoint TopRight => new PixelPoint(Right, Y); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the bottom left point of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public PixelPoint BottomLeft => new PixelPoint(X, Bottom); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the bottom right point of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public PixelPoint BottomRight => new PixelPoint(Right, Bottom); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the center point of the rectangle.
|
||||
|
/// </summary>
|
||||
|
public PixelPoint Center => new PixelPoint(X + (Width / 2), Y + (Height / 2)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a value that indicates whether the rectangle is empty.
|
||||
|
/// </summary>
|
||||
|
public bool IsEmpty => Width == 0 && Height == 0; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks for equality between two <see cref="PixelRect"/>s.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The first rect.</param>
|
||||
|
/// <param name="right">The second rect.</param>
|
||||
|
/// <returns>True if the rects are equal; otherwise false.</returns>
|
||||
|
public static bool operator ==(PixelRect left, PixelRect right) |
||||
|
{ |
||||
|
return left.Position == right.Position && left.Size == right.Size; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks for inequality between two <see cref="PixelRect"/>s.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The first rect.</param>
|
||||
|
/// <param name="right">The second rect.</param>
|
||||
|
/// <returns>True if the rects are unequal; otherwise false.</returns>
|
||||
|
public static bool operator !=(PixelRect left, PixelRect right) |
||||
|
{ |
||||
|
return !(left == right); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Determines whether a point in in the bounds of the rectangle.
|
||||
|
/// </summary>
|
||||
|
/// <param name="p">The point.</param>
|
||||
|
/// <returns>true if the point is in the bounds of the rectangle; otherwise false.</returns>
|
||||
|
public bool Contains(PixelPoint p) |
||||
|
{ |
||||
|
return p.X >= X && p.X <= Right && p.Y >= Y && p.Y <= Bottom; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Determines whether the rectangle fully contains another rectangle.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r">The rectangle.</param>
|
||||
|
/// <returns>true if the rectangle is fully contained; otherwise false.</returns>
|
||||
|
public bool Contains(PixelRect r) |
||||
|
{ |
||||
|
return Contains(r.TopLeft) && Contains(r.BottomRight); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Centers another rectangle in this rectangle.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rect">The rectangle to center.</param>
|
||||
|
/// <returns>The centered rectangle.</returns>
|
||||
|
public PixelRect CenterRect(PixelRect rect) |
||||
|
{ |
||||
|
return new PixelRect( |
||||
|
X + ((Width - rect.Width) / 2), |
||||
|
Y + ((Height - rect.Height) / 2), |
||||
|
rect.Width, |
||||
|
rect.Height); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a boolean indicating whether the given object is equal to this rectangle.
|
||||
|
/// </summary>
|
||||
|
/// <param name="obj">The object to compare against.</param>
|
||||
|
/// <returns>True if the object is equal to this rectangle; false otherwise.</returns>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (obj is PixelRect other) |
||||
|
{ |
||||
|
return this == other; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the hash code for this instance.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The hash code.</returns>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
unchecked |
||||
|
{ |
||||
|
int hash = 17; |
||||
|
hash = (hash * 23) + X.GetHashCode(); |
||||
|
hash = (hash * 23) + Y.GetHashCode(); |
||||
|
hash = (hash * 23) + Width.GetHashCode(); |
||||
|
hash = (hash * 23) + Height.GetHashCode(); |
||||
|
return hash; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the intersection of two rectangles.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rect">The other rectangle.</param>
|
||||
|
/// <returns>The intersection.</returns>
|
||||
|
public PixelRect Intersect(PixelRect rect) |
||||
|
{ |
||||
|
var newLeft = (rect.X > X) ? rect.X : X; |
||||
|
var newTop = (rect.Y > Y) ? rect.Y : Y; |
||||
|
var newRight = (rect.Right < Right) ? rect.Right : Right; |
||||
|
var newBottom = (rect.Bottom < Bottom) ? rect.Bottom : Bottom; |
||||
|
|
||||
|
if ((newRight > newLeft) && (newBottom > newTop)) |
||||
|
{ |
||||
|
return new PixelRect(newLeft, newTop, newRight - newLeft, newBottom - newTop); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return Empty; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Determines whether a rectangle intersects with this rectangle.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rect">The other rectangle.</param>
|
||||
|
/// <returns>
|
||||
|
/// True if the specified rectangle intersects with this one; otherwise false.
|
||||
|
/// </returns>
|
||||
|
public bool Intersects(PixelRect rect) |
||||
|
{ |
||||
|
return (rect.X < Right) && (X < rect.Right) && (rect.Y < Bottom) && (Y < rect.Bottom); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the union of two rectangles.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rect">The other rectangle.</param>
|
||||
|
/// <returns>The union.</returns>
|
||||
|
public PixelRect Union(PixelRect rect) |
||||
|
{ |
||||
|
if (IsEmpty) |
||||
|
{ |
||||
|
return rect; |
||||
|
} |
||||
|
else if (rect.IsEmpty) |
||||
|
{ |
||||
|
return this; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var x1 = Math.Min(X, rect.X); |
||||
|
var x2 = Math.Max(Right, rect.Right); |
||||
|
var y1 = Math.Min(Y, rect.Y); |
||||
|
var y2 = Math.Max(Bottom, rect.Bottom); |
||||
|
|
||||
|
return new PixelRect(new PixelPoint(x1, y1), new PixelPoint(x2, y2)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a new <see cref="PixelRect"/> with the specified X position.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The x position.</param>
|
||||
|
/// <returns>The new <see cref="PixelRect"/>.</returns>
|
||||
|
public PixelRect WithX(int x) |
||||
|
{ |
||||
|
return new PixelRect(x, Y, Width, Height); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a new <see cref="PixelRect"/> with the specified Y position.
|
||||
|
/// </summary>
|
||||
|
/// <param name="y">The y position.</param>
|
||||
|
/// <returns>The new <see cref="PixelRect"/>.</returns>
|
||||
|
public PixelRect WithY(int y) |
||||
|
{ |
||||
|
return new PixelRect(X, y, Width, Height); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a new <see cref="PixelRect"/> with the specified width.
|
||||
|
/// </summary>
|
||||
|
/// <param name="width">The width.</param>
|
||||
|
/// <returns>The new <see cref="PixelRect"/>.</returns>
|
||||
|
public PixelRect WithWidth(int width) |
||||
|
{ |
||||
|
return new PixelRect(X, Y, width, Height); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a new <see cref="PixelRect"/> with the specified height.
|
||||
|
/// </summary>
|
||||
|
/// <param name="height">The height.</param>
|
||||
|
/// <returns>The new <see cref="PixelRect"/>.</returns>
|
||||
|
public PixelRect WithHeight(int height) |
||||
|
{ |
||||
|
return new PixelRect(X, Y, Width, Height); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the <see cref="PixelRect"/> to a device-independent <see cref="Rect"/> using the
|
||||
|
/// specified scaling factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="scale">The scaling factor.</param>
|
||||
|
/// <returns>The device-independent rect.</returns>
|
||||
|
public Rect ToRect(double scale) => new Rect(Position.ToPoint(scale), Size.ToSize(scale)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the <see cref="PixelRect"/> to a device-independent <see cref="Rect"/> using the
|
||||
|
/// specified scaling factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="scale">The scaling factor.</param>
|
||||
|
/// <returns>The device-independent rect.</returns>
|
||||
|
public Rect ToRect(Vector scale) => new Rect(Position.ToPoint(scale), Size.ToSize(scale)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the <see cref="PixelRect"/> to a device-independent <see cref="Rect"/> using the
|
||||
|
/// specified dots per inch (DPI).
|
||||
|
/// </summary>
|
||||
|
/// <param name="dpi">The dots per inch of the device.</param>
|
||||
|
/// <returns>The device-independent rect.</returns>
|
||||
|
public Rect ToRectWithDpi(double dpi) => new Rect(Position.ToPointWithDpi(dpi), Size.ToSizeWithDpi(dpi)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the <see cref="PixelRect"/> to a device-independent <see cref="Rect"/> using the
|
||||
|
/// specified dots per inch (DPI).
|
||||
|
/// </summary>
|
||||
|
/// <param name="dpi">The dots per inch of the device.</param>
|
||||
|
/// <returns>The device-independent rect.</returns>
|
||||
|
public Rect ToRectWithDpi(Vector dpi) => new Rect(Position.ToPointWithDpi(dpi), Size.ToSizeWithDpi(dpi)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Rect"/> to device pixels using the specified scaling factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rect">The rect.</param>
|
||||
|
/// <param name="scale">The scaling factor.</param>
|
||||
|
/// <returns>The device-independent rect.</returns>
|
||||
|
public static PixelRect FromRect(Rect rect, double scale) => new PixelRect( |
||||
|
PixelPoint.FromPoint(rect.Position, scale), |
||||
|
PixelSize.FromSize(rect.Size, scale)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Rect"/> to device pixels using the specified scaling factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rect">The rect.</param>
|
||||
|
/// <param name="scale">The scaling factor.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public static PixelRect FromRect(Rect rect, Vector scale) => new PixelRect( |
||||
|
PixelPoint.FromPoint(rect.Position, scale), |
||||
|
PixelSize.FromSize(rect.Size, scale)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Rect"/> to device pixels using the specified dots per inch (DPI).
|
||||
|
/// </summary>
|
||||
|
/// <param name="rect">The rect.</param>
|
||||
|
/// <param name="dpi">The dots per inch of the device.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public static PixelRect FromRectWithDpi(Rect rect, double dpi) => new PixelRect( |
||||
|
PixelPoint.FromPointWithDpi(rect.Position, dpi), |
||||
|
PixelSize.FromSizeWithDpi(rect.Size, dpi)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Rect"/> to device pixels using the specified dots per inch (DPI).
|
||||
|
/// </summary>
|
||||
|
/// <param name="rect">The rect.</param>
|
||||
|
/// <param name="dpi">The dots per inch of the device.</param>
|
||||
|
/// <returns>The device-independent point.</returns>
|
||||
|
public static PixelRect FromRectWithDpi(Rect rect, Vector dpi) => new PixelRect( |
||||
|
PixelPoint.FromPointWithDpi(rect.Position, dpi), |
||||
|
PixelSize.FromSizeWithDpi(rect.Size, dpi)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the string representation of the rectangle.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The string representation of the rectangle.</returns>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return string.Format( |
||||
|
CultureInfo.InvariantCulture, |
||||
|
"{0}, {1}, {2}, {3}", |
||||
|
X, |
||||
|
Y, |
||||
|
Width, |
||||
|
Height); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Parses a <see cref="PixelRect"/> string.
|
||||
|
/// </summary>
|
||||
|
/// <param name="s">The string.</param>
|
||||
|
/// <returns>The parsed <see cref="PixelRect"/>.</returns>
|
||||
|
public static PixelRect Parse(string s) |
||||
|
{ |
||||
|
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelRect")) |
||||
|
{ |
||||
|
return new PixelRect( |
||||
|
tokenizer.ReadInt32(), |
||||
|
tokenizer.ReadInt32(), |
||||
|
tokenizer.ReadInt32(), |
||||
|
tokenizer.ReadInt32() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" /> |
||||
|
<ProjectReference Include="..\Gtk\Avalonia.Gtk3\Avalonia.Gtk3.csproj" /> |
||||
|
<ProjectReference Include="..\Skia\Avalonia.Skia\Avalonia.Skia.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
File diff suppressed because it is too large
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.IO; |
||||
|
using System.Threading.Tasks; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Controls.Platform; |
||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Input.Platform; |
||||
|
using Avalonia.Platform; |
||||
|
|
||||
|
namespace Avalonia.X11 |
||||
|
{ |
||||
|
class PlatformSettingsStub : IPlatformSettings |
||||
|
{ |
||||
|
public Size DoubleClickSize { get; } = new Size(2, 2); |
||||
|
public TimeSpan DoubleClickTime { get; } = TimeSpan.FromMilliseconds(500); |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue