Browse Source

Merge remote-tracking branch 'origin/gtk'

pull/10/head
Steven Kirk 12 years ago
parent
commit
9f2ffe1f8b
  1. 5
      .gitignore
  2. 29
      Cairo/Perspex.Cairo/CairoExtensions.cs
  3. 81
      Cairo/Perspex.Cairo/CairoPlatform.cs
  4. 218
      Cairo/Perspex.Cairo/Media/DrawingContext.cs
  5. 42
      Cairo/Perspex.Cairo/Media/Imaging/BitmapImpl.cs
  6. 38
      Cairo/Perspex.Cairo/Media/StreamGeometryContextImpl.cs
  7. 38
      Cairo/Perspex.Cairo/Media/StreamGeometryImpl.cs
  8. 92
      Cairo/Perspex.Cairo/Media/TextService.cs
  9. 98
      Cairo/Perspex.Cairo/Perspex.Cairo.csproj
  10. 36
      Cairo/Perspex.Cairo/Properties/AssemblyInfo.cs
  11. 112
      Cairo/Perspex.Cairo/Renderer.cs
  12. 6
      Cairo/Perspex.Cairo/packages.config
  13. 15
      Docs/mono-build.md
  14. 18
      Gtk/Perspex.Gtk/GtkExtensions.cs
  15. 55
      Gtk/Perspex.Gtk/GtkPlatform.cs
  16. 59
      Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs
  17. 41
      Gtk/Perspex.Gtk/Input/GtkMouseDevice.cs
  18. 12
      Gtk/Perspex.Gtk/MyClass.cs
  19. 102
      Gtk/Perspex.Gtk/Perspex.Gtk.csproj
  20. 27
      Gtk/Perspex.Gtk/Properties/AssemblyInfo.cs
  21. 150
      Gtk/Perspex.Gtk/WindowImpl.cs
  22. 7
      Gtk/Perspex.Gtk/packages.config
  23. 27
      Perspex-Linux.userprefs
  24. 105
      Perspex-Mono.sln
  25. 29
      Perspex-Mono.userprefs
  26. 16
      Perspex.Application/Perspex.Application.csproj
  27. 4
      Perspex.Base/Perspex.Base.csproj
  28. 26
      Perspex.Base/Platform/IPlatformHandle.cs
  29. 7
      Perspex.Base/Platform/IPlatformThreadingInterface.cs
  30. 23
      Perspex.Base/Platform/PlatformHandle.cs
  31. 8
      Perspex.Base/Threading/MainLoop.cs
  32. 8
      Perspex.Controls/Grid.cs
  33. 16
      Perspex.Controls/Perspex.Controls.csproj
  34. 37
      Perspex.Controls/Platform/IWindowImpl.cs
  35. 177
      Perspex.Controls/Window.cs
  36. 16
      Perspex.Diagnostics/Perspex.Diagnostics.csproj
  37. 11
      Perspex.Input/Perspex.Input.csproj
  38. 5
      Perspex.Input/Raw/RawInputEventArgs.cs
  39. 1
      Perspex.Input/Raw/RawMouseEventArgs.cs
  40. 25
      Perspex.Input/Raw/RawSizeEventArgs.cs
  41. 8
      Perspex.Interactivity/Perspex.Interactivity.csproj
  42. 6
      Perspex.Layout/Perspex.Layout.csproj
  43. 2
      Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj
  44. 4
      Perspex.SceneGraph/Perspex.SceneGraph.csproj
  45. 2
      Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs
  46. 3
      Perspex.SceneGraph/Platform/IRenderer.cs
  47. 2
      Perspex.Styling.UnitTests/Perspex.Styling.UnitTests.csproj
  48. 6
      Perspex.Styling/Perspex.Styling.csproj
  49. 1
      Perspex.Themes.Default/DefaultTheme.cs
  50. 17
      Perspex.Themes.Default/Perspex.Themes.Default.csproj
  51. 43
      Perspex.Themes.Default/WindowStyle.cs
  52. 4
      Perspex.UnitTests/Perspex.UnitTests.csproj
  53. 24
      Perspex.sln
  54. 25
      TestApplication/App.cs
  55. 4
      TestApplication/Program.cs
  56. 147
      TestApplication/TestApplication-Mono.csproj
  57. 92
      TestApplication/TestApplication.csproj
  58. 2
      Windows/Perspex.Direct2D1.RenderTests/Perspex.Direct2D1.RenderTests.csproj
  59. 15
      Windows/Perspex.Direct2D1/Direct2D1Platform.cs
  60. 2
      Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs
  61. 34
      Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj
  62. 6
      Windows/Perspex.Direct2D1/Renderer.cs
  63. 1
      Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs
  64. 4
      Windows/Perspex.Win32/Input/WindowsMouseDevice.cs
  65. 21
      Windows/Perspex.Win32/Interop/UnmanagedMethods.cs
  66. 51
      Windows/Perspex.Win32/Perspex.Win32.csproj
  67. 8
      Windows/Perspex.Win32/Win32Platform.cs
  68. 293
      Windows/Perspex.Win32/Window.cs
  69. 212
      Windows/Perspex.Win32/WindowImpl.cs

5
.gitignore

@ -151,3 +151,8 @@ $RECYCLE.BIN/
# Mac crap
.DS_Store
#################
## Monodevelop
#################
*.userprefs

29
Cairo/Perspex.Cairo/CairoExtensions.cs

@ -0,0 +1,29 @@
// -----------------------------------------------------------------------
// <copyright file="CairoPlatform.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Cairo
{
using Cairo = global::Cairo;
public static class CairoExtensions
{
public static Cairo.Matrix ToCairo(this Matrix m)
{
return new Cairo.Matrix(m.M11, m.M12, m.M21, m.M22, m.OffsetX, m.OffsetY);
}
public static Cairo.PointD ToCairo(this Point p)
{
return new Cairo.PointD(p.X, p.Y);
}
public static Cairo.Rectangle ToCairo(this Rect rect)
{
return new Cairo.Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
}
}
}

81
Cairo/Perspex.Cairo/CairoPlatform.cs

@ -0,0 +1,81 @@
// -----------------------------------------------------------------------
// <copyright file="CairoPlatform.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Cairo
{
using System;
using global::Cairo;
using Perspex.Cairo.Media;
using Perspex.Cairo.Media.Imaging;
using Perspex.Platform;
using Perspex.Threading;
using Splat;
public class CairoPlatform : IPlatformRenderInterface
{
private static CairoPlatform instance = new CairoPlatform();
private static TextService textService = new TextService();
public static void Initialize()
{
var locator = Locator.CurrentMutable;
locator.Register(() => instance, typeof(IPlatformRenderInterface));
locator.Register(() => textService, typeof(ITextService));
}
public ITextService TextService
{
get { return textService; }
}
public IBitmapImpl CreateBitmap(int width, int height)
{
throw new NotImplementedException();
//return new BitmapImpl(imagingFactory, width, height);
}
public IRenderer CreateRenderer(IPlatformHandle handle, double width, double height)
{
if (textService.Context == null)
{
textService.Context = GetPangoContext(handle);
}
return new Renderer(handle, width, height);
}
public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height)
{
throw new NotImplementedException();
}
public IStreamGeometryImpl CreateStreamGeometry()
{
return new StreamGeometryImpl();
}
public IBitmapImpl LoadBitmap(string fileName)
{
ImageSurface result = new ImageSurface(fileName);
return new BitmapImpl(result);
}
private Pango.Context GetPangoContext(IPlatformHandle handle)
{
switch (handle.HandleDescriptor)
{
case "GtkWindow":
var window = GLib.Object.GetObject(handle.Handle) as Gtk.Window;
return window.PangoContext;
default:
throw new NotSupportedException(string.Format(
"Don't know how to get a Pango Context from a '{0}'.",
handle.HandleDescriptor));
}
}
}
}

218
Cairo/Perspex.Cairo/Media/DrawingContext.cs

@ -0,0 +1,218 @@
// -----------------------------------------------------------------------
// <copyright file="DrawingContext.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
using Perspex.Cairo.Media.Imaging;
namespace Perspex.Cairo.Media
{
using System;
using System.Reactive.Disposables;
using Perspex.Media;
using Perspex.Platform;
using Splat;
using Cairo = global::Cairo;
using IBitmap = Perspex.Media.Imaging.IBitmap;
/// <summary>
/// Draws using Direct2D1.
/// </summary>
public class DrawingContext : IDrawingContext, IDisposable
{
/// <summary>
/// The cairo context.
/// </summary>
private Cairo.Context context;
/// <summary>
/// The cairo surface.
/// </summary>
private Cairo.Surface surface;
/// <summary>
/// The text service.
/// </summary>
private TextService textService;
/// <summary>
/// Initializes a new instance of the <see cref="DrawingContext"/> class.
/// </summary>
/// <param name="surface">The target surface.</param>
public DrawingContext(Cairo.Surface surface)
{
this.surface = surface;
this.context = new Cairo.Context(surface);
this.textService = Locator.Current.GetService<TextService>() as TextService;
this.CurrentTransform = Matrix.Identity;
}
/// <summary>
/// Initializes a new instance of the <see cref="DrawingContext"/> class.
/// </summary>
/// <param name="surface">The GDK drawable.</param>
public DrawingContext(Gdk.Drawable drawable)
{
this.Drawable = drawable;
this.context = Gdk.CairoHelper.Create(drawable);
this.textService = Locator.Current.GetService<ITextService>() as TextService;
this.CurrentTransform = Matrix.Identity;
}
public Matrix CurrentTransform
{
get;
private set;
}
public Gdk.Drawable Drawable
{
get;
private set;
}
/// <summary>
/// Ends a draw operation.
/// </summary>
public void Dispose()
{
this.context.Dispose();
if (this.surface != null)
{
this.surface.Dispose();
}
}
public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect)
{
var impl = bitmap.PlatformImpl as BitmapImpl;
var size = new Size(impl.PixelWidth, impl.PixelHeight);
var scaleX = destRect.Size.Width / sourceRect.Size.Width;
var scaleY = destRect.Size.Height / sourceRect.Size.Height;
this.context.Save();
this.context.Scale(scaleX, scaleY);
this.context.SetSourceSurface(impl.Surface, (int)sourceRect.X, (int)sourceRect.Y);
this.context.Rectangle(destRect.ToCairo());
this.context.Fill();
this.context.Restore();
}
/// <summary>
/// Draws a line.
/// </summary>
/// <param name="pen">The stroke pen.</param>
/// <param name="p1">The first point of the line.</param>
/// <param name="p1">The second point of the line.</param>
public void DrawLine(Pen pen, Perspex.Point p1, Perspex.Point p2)
{
this.SetBrush(pen.Brush);
this.context.LineWidth = pen.Thickness;
this.context.MoveTo(p1.ToCairo());
this.context.LineTo(p2.ToCairo());
this.context.Stroke();
}
/// <summary>
/// Draws a geometry.
/// </summary>
/// <param name="brush">The fill brush.</param>
/// <param name="pen">The stroke pen.</param>
/// <param name="geometry">The geometry.</param>
public void DrawGeometry(Perspex.Media.Brush brush, Perspex.Media.Pen pen, Perspex.Media.Geometry geometry)
{
// TODO: Implement
}
/// <summary>
/// Draws the outline of a rectangle.
/// </summary>
/// <param name="pen">The pen.</param>
/// <param name="rect">The rectangle bounds.</param>
public void DrawRectange(Pen pen, Rect rect)
{
this.SetPen(pen);
this.context.Rectangle(rect.ToCairo());
this.context.Stroke();
}
/// <summary>
/// Draws text.
/// </summary>
/// <param name="foreground">The foreground brush.</param>
/// <param name="rect">The output rectangle.</param>
/// <param name="text">The text.</param>
public void DrawText(Perspex.Media.Brush foreground, Rect rect, FormattedText text)
{
var layout = this.textService.CreateLayout(text);
this.SetBrush(foreground);
this.context.MoveTo(rect.X, rect.Y);
Pango.CairoHelper.ShowLayout(this.context, layout);
}
/// <summary>
/// Draws a filled rectangle.
/// </summary>
/// <param name="brush">The brush.</param>
/// <param name="rect">The rectangle bounds.</param>
public void FillRectange(Perspex.Media.Brush brush, Rect rect)
{
this.SetBrush(brush);
this.context.Rectangle(rect.ToCairo());
this.context.Fill();
}
/// <summary>
/// Pushes a clip rectange.
/// </summary>
/// <param name="clip">The clip rectangle.</param>
/// <returns>A disposable used to undo the clip rectangle.</returns>
public IDisposable PushClip(Rect clip)
{
this.context.Save();
this.context.Rectangle(clip.ToCairo());
this.context.Clip();
return Disposable.Create(() => this.context.Restore());
}
/// <summary>
/// Pushes a matrix transformation.
/// </summary>
/// <param name="matrix">The matrix</param>
/// <returns>A disposable used to undo the transformation.</returns>
public IDisposable PushTransform(Matrix matrix)
{
this.context.Save();
this.context.Transform(matrix.ToCairo());
this.CurrentTransform *= matrix;
return Disposable.Create(() =>
{
this.context.Restore();
this.CurrentTransform *= matrix.Invert();
});
}
private void SetBrush(Brush brush)
{
var solid = brush as SolidColorBrush;
if (solid != null)
{
this.context.SetSourceRGBA(
solid.Color.R / 255.0,
solid.Color.G / 255.0,
solid.Color.B / 255.0,
solid.Color.A / 255.0);
}
}
private void SetPen(Pen pen)
{
this.SetBrush(pen.Brush);
this.context.LineWidth = pen.Thickness;
}
}
}

42
Cairo/Perspex.Cairo/Media/Imaging/BitmapImpl.cs

@ -0,0 +1,42 @@
// -----------------------------------------------------------------------
// <copyright file="BitmapImpl.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Cairo.Media.Imaging
{
using System;
using Perspex.Platform;
using Cairo = global::Cairo;
public class BitmapImpl : IBitmapImpl
{
public BitmapImpl(Cairo.ImageSurface surface)
{
this.Surface = surface;
}
public int PixelWidth
{
get { return this.Surface.Width; }
}
public int PixelHeight
{
get { return this.Surface.Height; }
}
public Cairo.ImageSurface Surface
{
get;
private set;
}
public void Save(string fileName)
{
throw new NotImplementedException();
}
}
}

38
Cairo/Perspex.Cairo/Media/StreamGeometryContextImpl.cs

@ -0,0 +1,38 @@
// -----------------------------------------------------------------------
// <copyright file="Direct2D1StreamGeometryContext.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Cairo.Media
{
using Perspex.Platform;
public class StreamGeometryContextImpl : IStreamGeometryContextImpl
{
public StreamGeometryContextImpl()
{
// TODO: Implement
}
public void BeginFigure(Point startPoint, bool isFilled)
{
// TODO: Implement
}
public void LineTo(Point point)
{
// TODO: Implement
}
public void EndFigure(bool isClosed)
{
// TODO: Implement
}
public void Dispose()
{
// TODO: Implement
}
}
}

38
Cairo/Perspex.Cairo/Media/StreamGeometryImpl.cs

@ -0,0 +1,38 @@
// -----------------------------------------------------------------------
// <copyright file="Direct2DStreamGeometry.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Cairo.Media
{
using System;
using Perspex.Media;
using Perspex.Platform;
using Splat;
public class StreamGeometryImpl : IStreamGeometryImpl
{
public StreamGeometryImpl()
{
// TODO: Implement
}
public Rect Bounds
{
get { return new Rect(); }
}
public Rect GetRenderBounds(double strokeThickness)
{
// TODO: Implement
return new Rect();
}
public IStreamGeometryContextImpl Open()
{
// TODO: Implement
return new StreamGeometryContextImpl();
}
}
}

92
Cairo/Perspex.Cairo/Media/TextService.cs

@ -0,0 +1,92 @@
// -----------------------------------------------------------------------
// <copyright file="TextService.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Cairo.Media
{
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Perspex.Media;
using Perspex.Platform;
public class TextService : ITextService
{
/// <summary>
/// Gets the pango context to be used by the service.
/// </summary>
/// <remarks>>
/// There seems to be no way in GtkSharp to create a new Pango Context, so this has to
/// be injected by CairoPlatform the first time a renderer is created.
/// </remarks>
public Pango.Context Context
{
get;
internal set;
}
public Pango.Layout CreateLayout(FormattedText text)
{
var layout = new Pango.Layout(this.Context)
{
FontDescription = new Pango.FontDescription
{
Family = text.FontFamilyName,
Size = Pango.Units.FromDouble(text.FontSize),
Style = (Pango.Style)text.FontStyle,
}
};
layout.SetText(text.Text);
return layout;
}
public int GetCaretIndex(FormattedText text, Point point, Size constraint)
{
var layout = this.CreateLayout(text);
int result;
int trailing;
return layout.XyToIndex(
Pango.Units.FromDouble(point.X),
Pango.Units.FromDouble(point.Y),
out result,
out trailing) ? result : text.Text.Length;
}
public Point GetCaretPosition(FormattedText text, int caretIndex, Size constraint)
{
// TODO: Rather than have this and GetLineHeights, might be best to just return
// the rect if that's also possible in Direct2D backend.
var layout = this.CreateLayout(text);
var rect = layout.IndexToPos(caretIndex);
return new Point(Pango.Units.ToDouble(rect.X), Pango.Units.ToDouble(rect.Y));
}
public double[] GetLineHeights(FormattedText text, Size constraint)
{
var layout = this.CreateLayout(text);
var lines = layout.Lines;
return lines.Select(x =>
{
var inkRect = new Pango.Rectangle();
var logicalRect = new Pango.Rectangle();
x.GetExtents(ref inkRect, ref logicalRect);
return (double)logicalRect.Height;
}).ToArray();
}
public Size Measure(FormattedText text, Size constraint)
{
var layout = this.CreateLayout(text);
Pango.Rectangle inkRect;
Pango.Rectangle logicalRect;
layout.GetExtents(out inkRect, out logicalRect);
return new Size(Pango.Units.ToDouble(logicalRect.Width), Pango.Units.ToDouble(logicalRect.Height));
}
}
}

98
Cairo/Perspex.Cairo/Perspex.Cairo.csproj

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FB05AC90-89BA-4F2F-A924-F37875FB547C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Perspex.Cairo</RootNamespace>
<AssemblyName>Perspex.Cairo</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL">
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL">
<Package>glib-sharp-2.0</Package>
</Reference>
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL">
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL">
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="Splat">
<HintPath>..\..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Mono.Cairo" />
<Reference Include="System.Reactive.Core">
<HintPath>..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Interfaces">
<HintPath>..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<Package>gtk-sharp-2.0</Package>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CairoPlatform.cs" />
<Compile Include="Media\DrawingContext.cs" />
<Compile Include="Media\Imaging\BitmapImpl.cs" />
<Compile Include="Media\TextService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Renderer.cs" />
<Compile Include="CairoExtensions.cs" />
<Compile Include="Media\StreamGeometryContextImpl.cs" />
<Compile Include="Media\StreamGeometryImpl.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Perspex.Base\Perspex.Base.csproj">
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

36
Cairo/Perspex.Cairo/Properties/AssemblyInfo.cs

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Perspex.Cairo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Perspex.Cairo")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f999ba8b-64e7-40cc-98a4-003f1852d2a3")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

112
Cairo/Perspex.Cairo/Renderer.cs

@ -0,0 +1,112 @@
// -----------------------------------------------------------------------
// <copyright file="Renderer.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Cairo
{
using System;
using System.Runtime.InteropServices;
using global::Cairo;
using Perspex.Cairo.Media;
using Perspex.Platform;
using Matrix = Perspex.Matrix;
/// <summary>
/// A cairo renderer.
/// </summary>
public class Renderer : IRenderer
{
/// <summary>
/// Initializes a new instance of the <see cref="Renderer"/> class.
/// </summary>
/// <param name="handle">The window handle.</param>
/// <param name="width">The width of the window.</param>
/// <param name="height">The height of the window.</param>
public Renderer(IPlatformHandle handle, double width, double height)
{
}
/// <summary>
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <param name="handle">A handle to the drawable.</param>
public void Render(IVisual visual, IPlatformHandle handle)
{
using (DrawingContext context = CreateContext(handle))
{
this.Render(visual, context);
}
}
/// <summary>
/// Resizes the renderer.
/// </summary>
/// <param name="width">The new width.</param>
/// <param name="height">The new height.</param>
public void Resize(int width, int height)
{
// Don't need to do anything here.
}
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd);
/// <summary>
/// Creates a cairo surface that targets a platform-specific resource.
/// </summary>
/// <param name="handle">The platform-specific handle.</param>
/// <returns>A surface.</returns>
private static DrawingContext CreateContext(IPlatformHandle handle)
{
switch (handle.HandleDescriptor)
{
case "HWND":
return new DrawingContext(new Win32Surface(GetDC(handle.Handle)));
case "HDC":
return new DrawingContext(new Win32Surface(handle.Handle));
case "GdkWindow":
return new DrawingContext(new Gdk.Window(handle.Handle));
default:
throw new NotSupportedException(string.Format(
"Don't know how to create a Cairo renderer from a '{0}' handle",
handle.HandleDescriptor));
}
}
/// <summary>
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
/// <param name="context">The drawing context.</param>
private void Render(IVisual visual, DrawingContext context)
{
if (visual.IsVisible && visual.Opacity > 0)
{
Matrix transform = Matrix.Identity;
if (visual.RenderTransform != null)
{
Matrix current = context.CurrentTransform;
Matrix offset = Matrix.Translation(visual.TransformOrigin.ToPixels(visual.Bounds.Size));
transform = -current * -offset * visual.RenderTransform.Value * offset * current;
}
transform *= Matrix.Translation(visual.Bounds.Position);
using (context.PushClip(visual.Bounds))
using (context.PushTransform(transform))
{
visual.Render(context);
foreach (var child in visual.VisualChildren)
{
this.Render(child, context);
}
}
}
}
}
}

6
Cairo/Perspex.Cairo/packages.config

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Rx-Core" version="2.2.5" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" />
<package id="Splat" version="1.5.1" targetFramework="net45" />
</packages>

15
Docs/mono-build.md

@ -0,0 +1,15 @@
Installing Portable Class Libraries
===================================
Microsoft's PCLs are here in an installer that needs to be run on a Windows
machine:
http://www.microsoft.com/en-us/download/details.aspx?id=40727
But someone has made available a .zip here:
https://www.dropbox.com/s/sf5fclzf2d1spfn/PortableReferenceAssemblies.zip?dl=0
Copy them to:
/usr/lib/mono/xbuild-frameworks/.NETPortable

18
Gtk/Perspex.Gtk/GtkExtensions.cs

@ -0,0 +1,18 @@
// -----------------------------------------------------------------------
// <copyright file="Window.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Gtk
{
using Gtk = global::Gtk;
public static class GtkExtensions
{
public static Rect ToPerspex(this Gdk.Rectangle rect)
{
return new Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
}
}

55
Gtk/Perspex.Gtk/GtkPlatform.cs

@ -0,0 +1,55 @@
// -----------------------------------------------------------------------
// <copyright file="IDescription.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Gtk
{
using System;
using System.Reactive.Disposables;
using Perspex.Input;
using Perspex.Platform;
using Splat;
using Gtk = global::Gtk;
public class GtkPlatform : IPlatformThreadingInterface
{
private static GtkPlatform instance = new GtkPlatform ();
public GtkPlatform ()
{
Gtk.Application.Init();
}
public static void Initialize()
{
var locator = Locator.CurrentMutable;
locator.Register(() => new WindowImpl(), typeof(IWindowImpl));
locator.Register(() => GtkKeyboardDevice.Instance, typeof(IKeyboardDevice));
locator.Register(() => instance, typeof(IPlatformThreadingInterface));
}
public void ProcessMessage ()
{
Gtk.Application.RunIteration();
}
public IDisposable StartTimer (TimeSpan interval, Action tick)
{
var result = true;
var handle = GLib.Timeout.Add((uint)interval.TotalMilliseconds, () =>
{
tick();
return result;
});
return Disposable.Create(() => result = false);
}
public void Wake ()
{
}
}
}

59
Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs

@ -0,0 +1,59 @@
// -----------------------------------------------------------------------
// <copyright file="GtkKeyboardDevice.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Gtk
{
using System;
using Perspex.Input;
public class GtkKeyboardDevice : KeyboardDevice
{
private static GtkKeyboardDevice instance;
static GtkKeyboardDevice()
{
instance = new GtkKeyboardDevice();
}
private GtkKeyboardDevice()
{
}
public static GtkKeyboardDevice Instance
{
get { return instance; }
}
public override ModifierKeys Modifiers
{
get { throw new System.NotImplementedException(); }
}
public static Perspex.Input.Key ConvertKey(Gdk.Key key)
{
// TODO: Don't use reflection for this! My eyes!!!
if (key == Gdk.Key.BackSpace)
{
return Perspex.Input.Key.Back;
}
else
{
var s = Enum.GetName(typeof(Gdk.Key), key);
Perspex.Input.Key result;
if (Enum.TryParse(s, true, out result))
{
return result;
}
else
{
return Perspex.Input.Key.None;
}
}
}
}
}

41
Gtk/Perspex.Gtk/Input/GtkMouseDevice.cs

@ -0,0 +1,41 @@
// -----------------------------------------------------------------------
// <copyright file="GtkMouseDevice.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Gtk
{
using Perspex.Input;
public class GtkMouseDevice : MouseDevice
{
private static GtkMouseDevice instance;
private Point clientPosition;
static GtkMouseDevice()
{
instance = new GtkMouseDevice();
}
private GtkMouseDevice()
{
}
public static GtkMouseDevice Instance
{
get { return instance; }
}
internal void SetClientPosition(Point p)
{
this.clientPosition = p;
}
protected override Point GetClientPosition()
{
return this.clientPosition;
}
}
}

12
Gtk/Perspex.Gtk/MyClass.cs

@ -0,0 +1,12 @@
using System;
namespace Perspex.Gtk
{
public class MyClass
{
public MyClass ()
{
}
}
}

102
Gtk/Perspex.Gtk/Perspex.Gtk.csproj

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{54F237D5-A70A-4752-9656-0C70B1A7B047}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Perspex.Gtk</RootNamespace>
<AssemblyName>Perspex.Gtk</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Splat">
<HintPath>..\..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="System.Reactive.Interfaces">
<HintPath>..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Core">
<HintPath>..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Linq">
<HintPath>..\..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath>
</Reference>
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<Package>glib-sharp-2.0</Package>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="GtkExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GtkPlatform.cs" />
<Compile Include="WindowImpl.cs" />
<Compile Include="Input\GtkKeyboardDevice.cs" />
<Compile Include="Input\GtkMouseDevice.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\..\Perspex.Base\Perspex.Base.csproj">
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Input\Perspex.Input.csproj">
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Perspex.Input</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Controls\Perspex.Controls.csproj">
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Perspex.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Styling\Perspex.Styling.csproj">
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Perspex.Styling</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Input\" />
</ItemGroup>
</Project>

27
Gtk/Perspex.Gtk/Properties/AssemblyInfo.cs

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle ("Perspex.Gtk")]
[assembly: AssemblyDescription ("")]
[assembly: AssemblyConfiguration ("")]
[assembly: AssemblyCompany ("")]
[assembly: AssemblyProduct ("")]
[assembly: AssemblyCopyright ("steven")]
[assembly: AssemblyTrademark ("")]
[assembly: AssemblyCulture ("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion ("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

150
Gtk/Perspex.Gtk/WindowImpl.cs

@ -0,0 +1,150 @@
// -----------------------------------------------------------------------
// <copyright file="Window.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Gtk
{
using System;
using Perspex.Controls;
using Perspex.Input.Raw;
using Perspex.Platform;
using Gtk = global::Gtk;
public class WindowImpl : Gtk.Window, IWindowImpl
{
private Window owner;
private IPlatformHandle windowHandle;
private Size clientSize;
public WindowImpl()
: base(Gtk.WindowType.Toplevel)
{
this.DefaultSize = new Gdk.Size(640, 480);
this.Events = Gdk.EventMask.PointerMotionMask |
Gdk.EventMask.ButtonPressMask |
Gdk.EventMask.ButtonReleaseMask;
this.windowHandle = new PlatformHandle(this.Handle, "GtkWindow");
}
public Size ClientSize
{
get { return this.clientSize; }
}
IPlatformHandle IWindowImpl.Handle
{
get { return this.windowHandle; }
}
public Action Activated { get; set; }
public Action Closed { get; set; }
public Action<RawInputEventArgs> Input { get; set; }
public Action<Rect, IPlatformHandle> Paint { get; set; }
public Action<Size> Resized { get; set; }
public void Invalidate(Rect rect)
{
this.QueueDraw();
}
public void SetOwner(Window window)
{
this.owner = window;
}
public void SetTitle(string title)
{
this.Title = title;
}
protected override bool OnButtonPressEvent(Gdk.EventButton evnt)
{
var e = new RawMouseEventArgs(
GtkMouseDevice.Instance,
this.owner,
RawMouseEventType.LeftButtonDown,
new Point(evnt.X, evnt.Y));
this.Input(e);
return true;
}
protected override bool OnButtonReleaseEvent(Gdk.EventButton evnt)
{
var e = new RawMouseEventArgs(
GtkMouseDevice.Instance,
this.owner,
RawMouseEventType.LeftButtonUp,
new Point(evnt.X, evnt.Y));
this.Input(e);
return true;
}
protected override bool OnConfigureEvent(Gdk.EventConfigure evnt)
{
var newSize = new Size(evnt.Width, evnt.Height);
if (newSize != this.clientSize)
{
this.clientSize = newSize;
this.Resized(clientSize);
}
return true;
}
protected override void OnDestroyed()
{
this.Closed();
}
protected override bool OnKeyPressEvent(Gdk.EventKey evnt)
{
var e = new RawKeyEventArgs(
GtkKeyboardDevice.Instance,
RawKeyEventType.KeyDown,
GtkKeyboardDevice.ConvertKey(evnt.Key),
new string((char)Gdk.Keyval.ToUnicode((uint)evnt.Key), 1));
this.Input(e);
return true;
}
protected override bool OnExposeEvent(Gdk.EventExpose evnt)
{
this.Paint(evnt.Area.ToPerspex(), GetHandle(evnt.Window));
return true;
}
protected override void OnFocusActivated()
{
this.Activated();
}
protected override bool OnMotionNotifyEvent(Gdk.EventMotion evnt)
{
var position = new Point(evnt.X, evnt.Y);
GtkMouseDevice.Instance.SetClientPosition(position);
var e = new RawMouseEventArgs(
GtkMouseDevice.Instance,
this.owner,
RawMouseEventType.Move,
position);
this.Input(e);
return true;
}
private IPlatformHandle GetHandle(Gdk.Window window)
{
return new PlatformHandle(window.Handle, "GdkWindow");
}
}
}

7
Gtk/Perspex.Gtk/packages.config

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Rx-Core" version="2.2.5" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" />
<package id="Rx-Linq" version="2.2.5" targetFramework="net45" />
<package id="Splat" version="1.5.1" targetFramework="net45" />
</packages>

27
Perspex-Linux.userprefs

@ -0,0 +1,27 @@
<Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
<MonoDevelop.Ide.Workbench ActiveDocument="Gtk/Perspex.Gtk/GtkPlatform.cs">
<Files>
<File FileName="TestApplication/App.cs" Line="4" Column="4" />
<File FileName="TestApplication/Program.cs" Line="20" Column="20" />
<File FileName="Gtk/Perspex.Gtk/Window.cs" Line="21" Column="21" />
<File FileName="Gtk/Perspex.Gtk/GtkPlatform.cs" Line="22" Column="22" />
</Files>
<Pads>
<Pad Id="ProjectPad">
<State expanded="True">
<Node name="Gtk" expanded="True">
<Node name="Perspex.Gtk" expanded="True">
<Node name="GtkPlatform.cs" selected="True" />
</Node>
</Node>
<Node name="Perspex.Controls" expanded="True" />
</State>
</Pad>
</Pads>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>
<BreakpointStore />
</MonoDevelop.Ide.DebuggingService.Breakpoints>
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
</Properties>

105
Perspex-Mono.sln

@ -0,0 +1,105 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Base", "Perspex.Base\Perspex.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.SceneGraph", "Perspex.SceneGraph\Perspex.SceneGraph.csproj", "{EB582467-6ABB-43A1-B052-E981BA910E3A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Layout", "Perspex.Layout\Perspex.Layout.csproj", "{42472427-4774-4C81-8AFF-9F27B8E31721}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Input", "Perspex.Input\Perspex.Input.csproj", "{62024B2D-53EB-4638-B26B-85EEAA54866E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Interactivity", "Perspex.Interactivity\Perspex.Interactivity.csproj", "{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Controls", "Perspex.Controls\Perspex.Controls.csproj", "{D2221C82-4A25-4583-9B43-D791E3F6820C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Styling", "Perspex.Styling\Perspex.Styling.csproj", "{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Themes.Default", "Perspex.Themes.Default\Perspex.Themes.Default.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Application", "Perspex.Application\Perspex.Application.csproj", "{799A7BB5-3C2C-48B6-85A7-406A12C420DA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Diagnostics", "Perspex.Diagnostics\Perspex.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cairo", "Cairo", "{1D577B69-F23B-4C4F-8605-97704DAC75A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Cairo", "Cairo\Perspex.Cairo\Perspex.Cairo.csproj", "{FB05AC90-89BA-4F2F-A924-F37875FB547C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gtk", "Gtk", "{B8DA33FB-7ED2-4F4C-9647-D49492B1D07C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Gtk", "Gtk\Perspex.Gtk\Perspex.Gtk.csproj", "{54F237D5-A70A-4752-9656-0C70B1A7B047}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApplication-Mono", "TestApplication\TestApplication-Mono.csproj", "{E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}.Release|Any CPU.Build.0 = Release|Any CPU
{42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42472427-4774-4C81-8AFF-9F27B8E31721}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42472427-4774-4C81-8AFF-9F27B8E31721}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42472427-4774-4C81-8AFF-9F27B8E31721}.Release|Any CPU.Build.0 = Release|Any CPU
{54F237D5-A70A-4752-9656-0C70B1A7B047}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54F237D5-A70A-4752-9656-0C70B1A7B047}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54F237D5-A70A-4752-9656-0C70B1A7B047}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54F237D5-A70A-4752-9656-0C70B1A7B047}.Release|Any CPU.Build.0 = Release|Any CPU
{62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62024B2D-53EB-4638-B26B-85EEAA54866E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62024B2D-53EB-4638-B26B-85EEAA54866E}.Release|Any CPU.Build.0 = Release|Any CPU
{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}.Release|Any CPU.Build.0 = Release|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.Build.0 = Release|Any CPU
{799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{799A7BB5-3C2C-48B6-85A7-406A12C420DA}.Release|Any CPU.Build.0 = Release|Any CPU
{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B09B78D8-9B26-48B0-9149-D64A2F120F3F}.Release|Any CPU.Build.0 = Release|Any CPU
{D2221C82-4A25-4583-9B43-D791E3F6820C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2221C82-4A25-4583-9B43-D791E3F6820C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2221C82-4A25-4583-9B43-D791E3F6820C}.Release|Any CPU.Build.0 = Release|Any CPU
{E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}.Release|Any CPU.Build.0 = Release|Any CPU
{EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB582467-6ABB-43A1-B052-E981BA910E3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB582467-6ABB-43A1-B052-E981BA910E3A}.Release|Any CPU.Build.0 = Release|Any CPU
{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}.Release|Any CPU.Build.0 = Release|Any CPU
{FB05AC90-89BA-4F2F-A924-F37875FB547C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FB05AC90-89BA-4F2F-A924-F37875FB547C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB05AC90-89BA-4F2F-A924-F37875FB547C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB05AC90-89BA-4F2F-A924-F37875FB547C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{FB05AC90-89BA-4F2F-A924-F37875FB547C} = {1D577B69-F23B-4C4F-8605-97704DAC75A9}
{54F237D5-A70A-4752-9656-0C70B1A7B047} = {B8DA33FB-7ED2-4F4C-9647-D49492B1D07C}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = TestApplication\TestApplication-Mono.csproj
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

29
Perspex-Mono.userprefs

@ -0,0 +1,29 @@
<Properties GitUserInfo="UsingGIT">
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
<MonoDevelop.Ide.Workbench>
<Pads>
<Pad Id="ProjectPad">
<State expanded="True">
<Node name="Gtk" expanded="True">
<Node name="Perspex.Gtk" expanded="True">
<Node name="Input" expanded="True" />
<Node name="WindowImpl.cs" selected="True" />
</Node>
</Node>
<Node name="Perspex.Base" expanded="True" />
<Node name="Perspex.Input" expanded="True">
<Node name="Raw" expanded="True" />
</Node>
<Node name="TestApplication-Mono" expanded="True" />
</State>
</Pad>
</Pads>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>
<BreakpointStore>
<Breakpoint file="/home/steven/projects/Perspex/Gtk/Perspex.Gtk/Window.cs" line="56" column="1" />
<Catchpoint exceptionName="System.Exception" includeSubclasses="True" />
</BreakpointStore>
</MonoDevelop.Ide.DebuggingService.Breakpoints>
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
</Properties>

16
Perspex.Application/Perspex.Application.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -37,31 +37,31 @@
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Controls\Perspex.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Perspex.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Input\Perspex.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Perspex.Input</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Styling\Perspex.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Perspex.Styling</Name>
</ProjectReference>
</ItemGroup>

4
Perspex.Base/Perspex.Base.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -45,7 +45,9 @@
<Compile Include="PerspexObject.cs" />
<Compile Include="PerspexProperty.cs" />
<Compile Include="PerspexPropertyChangedEventArgs.cs" />
<Compile Include="Platform\IPlatformHandle.cs" />
<Compile Include="Platform\IPlatformThreadingInterface.cs" />
<Compile Include="Platform\PlatformHandle.cs" />
<Compile Include="PriorityValue.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Threading\Dispatcher.cs" />

26
Perspex.Base/Platform/IPlatformHandle.cs

@ -0,0 +1,26 @@
// -----------------------------------------------------------------------
// <copyright file="Window.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Platform
{
using System;
/// <summary>
/// Represents a platform-specific handle.
/// </summary>
public interface IPlatformHandle
{
/// <summary>
/// Gets the handle.
/// </summary>
IntPtr Handle { get; }
/// <summary>
/// Gets an optional string that describes what <see cref="Handle"/> represents.
/// </summary>
string HandleDescriptor { get; }
}
}

7
Perspex.Base/Platform/IPlatformThreadingInterface.cs

@ -11,6 +11,9 @@ namespace Perspex.Platform
using System.Threading.Tasks;
using Perspex.Threading;
/// <summary>
/// Provides platform-specific services relating to threading.
/// </summary>
public interface IPlatformThreadingInterface
{
/// <summary>
@ -22,9 +25,9 @@ namespace Perspex.Platform
/// Starts a timer.
/// </summary>
/// <param name="interval">The interval.</param>
/// <param name="internalTick">The action to call on each tick.</param>
/// <param name="tick">The action to call on each tick.</param>
/// <returns>An <see cref="IDisposable"/> used to stop the timer.</returns>
IDisposable StartTimer(TimeSpan interval, Action internalTick);
IDisposable StartTimer(TimeSpan interval, Action tick);
/// <summary>
/// Sends a message that causes <see cref="ProcessMessage"/> to exit.

23
Perspex.Base/Platform/PlatformHandle.cs

@ -0,0 +1,23 @@
// -----------------------------------------------------------------------
// <copyright file="PlatformHandle.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Platform
{
using System;
public class PlatformHandle : IPlatformHandle
{
public PlatformHandle(IntPtr handle, string descriptor)
{
this.Handle = handle;
this.HandleDescriptor = descriptor;
}
public IntPtr Handle { get; private set; }
public string HandleDescriptor { get; private set; }
}
}

8
Perspex.Base/Threading/MainLoop.cs

@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="Application.cs" company="Steven Kirk">
// <copyright file="MainLoop.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -33,11 +33,11 @@ namespace Perspex.Win32.Threading
Job job;
// TODO: Dispatch windows messages in preference to lower priority jobs.
while (queue.Count > 0)
while (this.queue.Count > 0)
{
lock (this.queue)
{
job = queue.Dequeue();
job = this.queue.Dequeue();
}
try
@ -59,7 +59,7 @@ namespace Perspex.Win32.Threading
{
var job = new Job(action);
lock (queue)
lock (this.queue)
{
this.queue.Add(job, priority);
}

8
Perspex.Controls/Grid.cs

@ -605,10 +605,10 @@ namespace Perspex.Controls
// we need to count the number of stars instead.
for (int i = start; i <= end; i++)
{
double segmentSize = desiredSize ? matrix[i, i].DesiredSize : matrix[i, i].OfferedSize;
double segmentSize = desiredSize ? (matrix[i, i].DesiredSize) : matrix[i, i].OfferedSize;
if (segmentSize < matrix[i, i].Max)
{
count += type == GridUnitType.Star ? matrix[i, i].Stars : 1;
count += type == GridUnitType.Star ? (matrix[i, i].Stars) : 1;
}
}
@ -620,7 +620,7 @@ namespace Perspex.Controls
for (int i = start; i <= end; i++)
{
double segmentSize = desiredSize ? matrix[i, i].DesiredSize : matrix[i, i].OfferedSize;
double segmentSize = desiredSize ? (matrix[i, i].DesiredSize) : matrix[i, i].OfferedSize;
if (!(matrix[i, i].Type == type && segmentSize < matrix[i, i].Max))
{
@ -628,7 +628,7 @@ namespace Perspex.Controls
}
double newsize = segmentSize;
newsize += contribution * (type == GridUnitType.Star ? matrix[i, i].Stars : 1);
newsize += contribution * (type == GridUnitType.Star ? (matrix[i, i].Stars) : 1);
newsize = Math.Min(newsize, matrix[i, i].Max);
assigned |= newsize > segmentSize;
size -= newsize - segmentSize;

16
Perspex.Controls/Perspex.Controls.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -41,6 +41,7 @@
<Compile Include="ColumnDefinitions.cs" />
<Compile Include="ContentControl.cs" />
<Compile Include="GridSplitter.cs" />
<Compile Include="Platform\IWindowImpl.cs" />
<Compile Include="Presenters\ScrollContentPresenter.cs" />
<Compile Include="Presenters\ContentPresenter.cs" />
<Compile Include="Control.cs" />
@ -69,6 +70,7 @@
<Compile Include="Panel.cs" />
<Compile Include="Primitives\Track.cs" />
<Compile Include="Primitives\Thumb.cs" />
<Compile Include="Window.cs" />
<Compile Include="RowDefinition.cs" />
<Compile Include="RowDefinitions.cs" />
<Compile Include="Primitives\SelectingItemsControl.cs" />
@ -114,27 +116,27 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Input\Perspex.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Perspex.Input</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Styling\Perspex.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Perspex.Styling</Name>
</ProjectReference>
</ItemGroup>

37
Perspex.Controls/Platform/IWindowImpl.cs

@ -0,0 +1,37 @@
// -----------------------------------------------------------------------
// <copyright file="IWindowImpl.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Platform
{
using System;
using Perspex.Controls;
using Perspex.Input.Raw;
public interface IWindowImpl
{
Size ClientSize { get; }
IPlatformHandle Handle { get; }
Action Activated { get; set; }
Action Closed { get; set; }
Action<RawInputEventArgs> Input { get; set; }
Action<Rect, IPlatformHandle> Paint { get; set; }
Action<Size> Resized { get; set; }
void Invalidate(Rect rect);
void SetTitle(string title);
void SetOwner(Window window);
void Show();
}
}

177
Perspex.Controls/Window.cs

@ -0,0 +1,177 @@
// -----------------------------------------------------------------------
// <copyright file="Window.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls
{
using System;
using System.Reactive.Linq;
using Perspex.Input;
using Perspex.Input.Raw;
using Perspex.Layout;
using Perspex.Media;
using Perspex.Platform;
using Perspex.Rendering;
using Perspex.Styling;
using Perspex.Threading;
using Splat;
public class Window : ContentControl, ILayoutRoot, IRenderRoot, ICloseable
{
public static readonly PerspexProperty<Size> ClientSizeProperty =
PerspexProperty.Register<Window, Size>("ClientSize");
public static readonly PerspexProperty<string> TitleProperty =
PerspexProperty.Register<Window, string>("Title", "Window");
private IWindowImpl impl;
private Dispatcher dispatcher;
private IRenderer renderer;
private IInputManager inputManager;
public event EventHandler Activated;
public event EventHandler Closed;
static Window()
{
BackgroundProperty.OverrideDefaultValue(typeof(Window), Brushes.White);
}
public Window()
{
IPlatformRenderInterface renderInterface = Locator.Current.GetService<IPlatformRenderInterface>();
this.impl = Locator.Current.GetService<IWindowImpl>();
this.inputManager = Locator.Current.GetService<IInputManager>();
if (this.impl == null)
{
throw new InvalidOperationException(
"Could not create window implementation: maybe no windowing subsystem was initialized?");
}
if (this.inputManager == null)
{
throw new InvalidOperationException(
"Could not create input manager: maybe Application.RegisterServices() wasn't called?");
}
this.impl.SetOwner(this);
this.impl.Activated = this.HandleActivated;
this.impl.Closed = this.HandleClosed;
this.impl.Input = this.HandleInput;
this.impl.Paint = this.HandlePaint;
this.impl.Resized = this.HandleResized;
Size clientSize = this.ClientSize = this.impl.ClientSize;
this.dispatcher = Dispatcher.UIThread;
this.renderer = renderInterface.CreateRenderer(this.impl.Handle, clientSize.Width, clientSize.Height);
this.LayoutManager = new LayoutManager(this);
this.LayoutManager.LayoutNeeded.Subscribe(_ => this.HandleLayoutNeeded());
this.RenderManager = new RenderManager();
this.RenderManager.RenderNeeded.Subscribe(_ => this.HandleRenderNeeded());
this.GetObservable(TitleProperty).Subscribe(s => this.impl.SetTitle(s));
IStyler styler = Locator.Current.GetService<IStyler>();
styler.ApplyStyles(this);
}
public Size ClientSize
{
get { return this.GetValue(ClientSizeProperty); }
set { this.SetValue(ClientSizeProperty, value); }
}
public string Title
{
get { return this.GetValue(TitleProperty); }
set { this.SetValue(TitleProperty, value); }
}
public ILayoutManager LayoutManager
{
get;
private set;
}
public IRenderManager RenderManager
{
get;
private set;
}
public void Show()
{
this.impl.Show();
this.LayoutPass();
}
private void HandleActivated()
{
if (this.Activated != null)
{
this.Activated(this, EventArgs.Empty);
}
}
private void HandleClosed()
{
if (this.Closed != null)
{
this.Closed(this, EventArgs.Empty);
}
}
private void HandleInput(RawInputEventArgs e)
{
this.inputManager.Process(e);
}
private void HandleLayoutNeeded()
{
this.dispatcher.InvokeAsync(this.LayoutPass, DispatcherPriority.Render);
}
private void HandleRenderNeeded()
{
this.dispatcher.InvokeAsync(this.RenderVisualTree, DispatcherPriority.Render);
}
private void HandlePaint(Rect rect, IPlatformHandle handle)
{
this.renderer.Render(this, handle);
this.RenderManager.RenderFinished();
}
private void HandleResized(Size size)
{
this.ClientSize = size;
this.renderer.Resize((int)size.Width, (int)size.Height);
this.LayoutManager.ExecuteLayoutPass();
this.impl.Invalidate(new Rect(this.ClientSize));
}
private void LayoutPass()
{
this.LayoutManager.ExecuteLayoutPass();
this.impl.Invalidate(new Rect(this.ClientSize));
}
private void RenderVisualTree()
{
if (!this.LayoutManager.LayoutQueued)
{
this.impl.Invalidate(new Rect(this.ClientSize));
}
}
}
}

16
Perspex.Diagnostics/Perspex.Diagnostics.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -36,31 +36,31 @@
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Controls\Perspex.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Perspex.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Input\Perspex.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Perspex.Input</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Styling\Perspex.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Perspex.Styling</Name>
</ProjectReference>
</ItemGroup>

11
Perspex.Input/Perspex.Input.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -36,19 +36,19 @@
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
</ItemGroup>
@ -66,6 +66,7 @@
<Compile Include="IPointerDevice.cs" />
<Compile Include="Key.cs" />
<Compile Include="KeyboardDevice.cs" />
<Compile Include="Raw\RawSizeEventArgs.cs" />
<Compile Include="VectorEventArgs.cs" />
<Compile Include="KeyEventArgs.cs" />
<Compile Include="MouseDevice.cs" />

5
Perspex.Input/Raw/RawInputEventArgs.cs

@ -7,11 +7,6 @@
namespace Perspex.Input.Raw
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Perspex.Layout;
public class RawInputEventArgs : EventArgs
{

1
Perspex.Input/Raw/RawMouseEventArgs.cs

@ -33,6 +33,7 @@ namespace Perspex.Input.Raw
this.Type = type;
}
//TODO: This should probably be IInputRoot or something.
public ILayoutRoot Root { get; private set; }
public Point Position { get; private set; }

25
Perspex.Input/Raw/RawSizeEventArgs.cs

@ -0,0 +1,25 @@
// -----------------------------------------------------------------------
// <copyright file="RawInputEventArgs.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input.Raw
{
using System;
public class RawSizeEventArgs : EventArgs
{
public RawSizeEventArgs(Size size)
{
this.Size = size;
}
public RawSizeEventArgs(double width, double height)
{
this.Size = new Size(width, height);
}
public Size Size { get; private set; }
}
}

8
Perspex.Interactivity/Perspex.Interactivity.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -36,15 +36,15 @@
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
</ItemGroup>

6
Perspex.Layout/Perspex.Layout.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -36,11 +36,11 @@
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
</ItemGroup>

2
Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

4
Perspex.SceneGraph/Perspex.SceneGraph.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -36,7 +36,7 @@
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
</ItemGroup>

2
Perspex.SceneGraph/Platform/IPlatformRenderInterface.cs

@ -17,7 +17,7 @@ namespace Perspex.Platform
IStreamGeometryImpl CreateStreamGeometry();
IRenderer CreateRenderer(IntPtr handle, double width, double height);
IRenderer CreateRenderer(IPlatformHandle handle, double width, double height);
IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height);

3
Perspex.SceneGraph/Platform/IRenderer.cs

@ -14,7 +14,8 @@ namespace Perspex.Platform
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
void Render(IVisual visual);
/// <param name="handle">An optional platform-specific handle.</param>
void Render(IVisual visual, IPlatformHandle handle);
/// <summary>
/// Resizes the rendered viewport.

2
Perspex.Styling.UnitTests/Perspex.Styling.UnitTests.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

6
Perspex.Styling/Perspex.Styling.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -75,11 +75,11 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
</ItemGroup>

1
Perspex.Themes.Default/DefaultTheme.cs

@ -25,6 +25,7 @@ namespace Perspex.Themes.Default
this.Add(new TextBoxStyle());
this.Add(new TreeViewStyle());
this.Add(new TreeViewItemStyle());
this.Add(new WindowStyle());
}
}
}

17
Perspex.Themes.Default/Perspex.Themes.Default.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
@ -37,35 +37,36 @@
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Controls\Perspex.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Perspex.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Input\Perspex.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Perspex.Input</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Styling\Perspex.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Perspex.Styling</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="WindowStyle.cs" />
<Compile Include="ScrollViewerStyle.cs" />
<Compile Include="ScrollBarStyle.cs" />
<Compile Include="GridSplitterStyle.cs" />

43
Perspex.Themes.Default/WindowStyle.cs

@ -0,0 +1,43 @@
// -----------------------------------------------------------------------
// <copyright file="WindowStyle.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Themes.Default
{
using System.Linq;
using Perspex.Controls;
using Perspex.Controls.Presenters;
using Perspex.Media;
using Perspex.Styling;
public class WindowStyle : Styles
{
public WindowStyle()
{
this.AddRange(new[]
{
new Style(x => x.OfType<Window>())
{
Setters = new[]
{
new Setter(Window.TemplateProperty, ControlTemplate.Create<Window>(this.Template)),
},
},
});
}
private Control Template(Window control)
{
return new Border
{
[~Border.BackgroundProperty] = control[~Window.BackgroundProperty],
Content = new ContentPresenter
{
[~ContentPresenter.ContentProperty] = control[~Window.ContentProperty],
}
};
}
}
}

4
Perspex.UnitTests/Perspex.UnitTests.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -70,10 +70,10 @@
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="PriorityValueTests.cs" />
<Compile Include="PerspexPropertyTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PerspexObjectTests.cs" />
<Compile Include="PriorityValueTEsts.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

24
Perspex.sln

@ -41,6 +41,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Application", "Pers
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Diagnostics", "Perspex.Diagnostics\Perspex.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cairo", "Cairo", "{1D577B69-F23B-4C4F-8605-97704DAC75A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Cairo", "Cairo\Perspex.Cairo\Perspex.Cairo.csproj", "{FB05AC90-89BA-4F2F-A924-F37875FB547C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gtk", "Gtk", "{554AF661-FE23-4647-930E-48B617E68F9D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Gtk", "Gtk\Perspex.Gtk\Perspex.Gtk.csproj", "{54F237D5-A70A-4752-9656-0C70B1A7B047}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApplication-Mono", "TestApplication\TestApplication-Mono.csproj", "{B6FDF644-8EE5-4A6B-8ECC-C2C2E4DAF116}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -119,6 +129,18 @@ Global
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.Build.0 = Release|Any CPU
{FB05AC90-89BA-4F2F-A924-F37875FB547C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FB05AC90-89BA-4F2F-A924-F37875FB547C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB05AC90-89BA-4F2F-A924-F37875FB547C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB05AC90-89BA-4F2F-A924-F37875FB547C}.Release|Any CPU.Build.0 = Release|Any CPU
{54F237D5-A70A-4752-9656-0C70B1A7B047}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54F237D5-A70A-4752-9656-0C70B1A7B047}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54F237D5-A70A-4752-9656-0C70B1A7B047}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54F237D5-A70A-4752-9656-0C70B1A7B047}.Release|Any CPU.Build.0 = Release|Any CPU
{B6FDF644-8EE5-4A6B-8ECC-C2C2E4DAF116}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6FDF644-8EE5-4A6B-8ECC-C2C2E4DAF116}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6FDF644-8EE5-4A6B-8ECC-C2C2E4DAF116}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6FDF644-8EE5-4A6B-8ECC-C2C2E4DAF116}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -127,5 +149,7 @@ Global
{811A76CF-1CF6-440F-963B-BBE31BD72A82} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{3E908F67-5543-4879-A1DC-08EACE79B3CD} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{DABFD304-D6A4-4752-8123-C2CCF7AC7831} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{FB05AC90-89BA-4F2F-A924-F37875FB547C} = {1D577B69-F23B-4C4F-8605-97704DAC75A9}
{54F237D5-A70A-4752-9656-0C70B1A7B047} = {554AF661-FE23-4647-930E-48B617E68F9D}
EndGlobalSection
EndGlobal

25
TestApplication/App.cs

@ -1,9 +1,19 @@
namespace TestApplication
{
using Perspex;
using Perspex.Direct2D1;
using Perspex.Themes.Default;
using Perspex.Themes.Default;
#if PERSPEX_CAIRO
using Perspex.Cairo;
#else
using Perspex.Direct2D1;
#endif
#if PERSPEX_GTK
using Perspex.Gtk;
#else
using Perspex.Win32;
#endif
public class App : Application
{
@ -11,8 +21,17 @@
: base(new DefaultTheme())
{
this.RegisterServices();
#if PERSPEX_CAIRO
CairoPlatform.Initialize();
#else
Direct2D1Platform.Initialize();
Win32Platform.Initialize();
#endif
#if PERSPEX_GTK
GtkPlatform.Initialize();
#else
Win32Platform.Initialize();
#endif
}
}
}

4
TestApplication/Program.cs

@ -6,7 +6,11 @@ using Perspex.Diagnostics;
using Perspex.Layout;
using Perspex.Media;
using Perspex.Media.Imaging;
#if PERSPEX_GTK
using Perspex.Gtk;
#else
using Perspex.Win32;
#endif
using Splat;
namespace TestApplication

147
TestApplication/TestApplication-Mono.csproj

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B6FDF644-8EE5-4A6B-8ECC-C2C2E4DAF116}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TestApplication</RootNamespace>
<AssemblyName>TestApplication</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>caf18def</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug-Mono\</OutputPath>
<DefineConstants>TRACE;DEBUG;PERSPEX_CAIRO;PERSPEX_GTK</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release-Mono\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Reactive.Windows.Threading">
<HintPath>..\packages\Rx-Xaml.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="ReactiveUI">
<HintPath>..\packages\reactiveui-core.6.2.1.1\lib\Net45\ReactiveUI.dll</HintPath>
</Reference>
<Reference Include="Splat">
<HintPath>..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Core">
<HintPath>..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Interfaces">
<HintPath>..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Linq">
<HintPath>..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.PlatformServices">
<HintPath>..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="App.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Cairo\Perspex.Cairo\Perspex.Cairo.csproj">
<Project>{FB05AC90-89BA-4F2F-A924-F37875FB547C}</Project>
<Name>Perspex.Cairo</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Application\Perspex.Application.csproj">
<Project>{799A7BB5-3C2C-48B6-85A7-406A12C420DA}</Project>
<Name>Perspex.Application</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Controls\Perspex.Controls.csproj">
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Perspex.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Diagnostics\Perspex.Diagnostics.csproj">
<Project>{7062AE20-5DCC-4442-9645-8195BDECE63E}</Project>
<Name>Perspex.Diagnostics</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Input\Perspex.Input.csproj">
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Perspex.Input</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Styling\Perspex.Styling.csproj">
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Perspex.Styling</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Themes.Default\Perspex.Themes.Default.csproj">
<Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
<Name>Perspex.Themes.Default</Name>
</ProjectReference>
<ProjectReference Include="..\Gtk\Perspex.Gtk\Perspex.Gtk.csproj">
<Project>{54F237D5-A70A-4752-9656-0C70B1A7B047}</Project>
<Name>Perspex.Gtk</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="github_icon.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\SharpDX.2.6.3\build\SharpDX.targets" Condition="Exists('..\packages\SharpDX.2.6.3\build\SharpDX.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\SharpDX.2.6.3\build\SharpDX.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SharpDX.2.6.3\build\SharpDX.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

92
TestApplication/TestApplication.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -19,9 +19,10 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -32,51 +33,12 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="ReactiveUI, Version=6.2.1.1, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\reactiveui-core.6.2.1.1\lib\Net45\ReactiveUI.dll</HintPath>
</Reference>
<Reference Include="SharpDX, Version=2.6.3.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SharpDXPackageBinDir)\SharpDX.dll</HintPath>
</Reference>
<Reference Include="SharpDX.Direct2D1, Version=2.6.3.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SharpDXPackageBinDir)\SharpDX.Direct2D1.dll</HintPath>
</Reference>
<Reference Include="SharpDX.DXGI, Version=2.6.3.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SharpDXPackageBinDir)\SharpDX.DXGI.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Windows.Threading">
<HintPath>..\packages\Rx-XAML.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
<HintPath>..\packages\Rx-Xaml.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
@ -85,6 +47,24 @@
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="ReactiveUI">
<HintPath>..\packages\reactiveui-core.6.2.1.1\lib\Net45\ReactiveUI.dll</HintPath>
</Reference>
<Reference Include="Splat">
<HintPath>..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Core">
<HintPath>..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Interfaces">
<HintPath>..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Linq">
<HintPath>..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.PlatformServices">
<HintPath>..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="App.cs" />
@ -97,49 +77,49 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Perspex.Application\Perspex.Application.csproj">
<Project>{799a7bb5-3c2c-48b6-85a7-406a12c420da}</Project>
<Project>{799A7BB5-3C2C-48B6-85A7-406A12C420DA}</Project>
<Name>Perspex.Application</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Controls\Perspex.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Perspex.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Diagnostics\Perspex.Diagnostics.csproj">
<Project>{7062ae20-5dcc-4442-9645-8195bdece63e}</Project>
<Project>{7062AE20-5DCC-4442-9645-8195BDECE63E}</Project>
<Name>Perspex.Diagnostics</Name>
</ProjectReference>
<ProjectReference Include="..\Windows\Perspex.Direct2D1\Perspex.Direct2D1.csproj">
<Project>{3e908f67-5543-4879-a1dc-08eace79b3cd}</Project>
<Name>Perspex.Direct2D1</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Input\Perspex.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Perspex.Input</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Styling\Perspex.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Perspex.Styling</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Themes.Default\Perspex.Themes.Default.csproj">
<Project>{3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f}</Project>
<Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
<Name>Perspex.Themes.Default</Name>
</ProjectReference>
<ProjectReference Include="..\Windows\Perspex.Direct2D1\Perspex.Direct2D1.csproj">
<Project>{3e908f67-5543-4879-a1dc-08eace79b3cd}</Project>
<Name>Perspex.Direct2D1</Name>
</ProjectReference>
<ProjectReference Include="..\Windows\Perspex.Win32\Perspex.Win32.csproj">
<Project>{811a76cf-1cf6-440f-963b-bbe31bd72a82}</Project>
<Name>Perspex.Win32</Name>

2
Windows/Perspex.Direct2D1.RenderTests/Perspex.Direct2D1.RenderTests.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

15
Windows/Perspex.Direct2D1/Direct2D1Platform.cs

@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="Direct2D1Initialize.cs" company="Steven Kirk">
// <copyright file="Direct2D1Platform.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -44,9 +44,18 @@ namespace Perspex.Direct2D1
return new BitmapImpl(imagingFactory, width, height);
}
public IRenderer CreateRenderer(IntPtr handle, double width, double height)
public IRenderer CreateRenderer(IPlatformHandle handle, double width, double height)
{
return new Renderer(handle, width, height);
if (handle.HandleDescriptor == "HWND")
{
return new Renderer(handle.Handle, width, height);
}
else
{
throw new NotSupportedException(string.Format(
"Don't know how to create a Direct2D1 renderer from a '{0}' handle",
handle.HandleDescriptor));
}
}
public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height)

2
Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs

@ -35,7 +35,7 @@ namespace Perspex.Direct2D1.Media
public void Render(IVisual visual)
{
Renderer renderer = new Renderer(this.target);
renderer.Render(visual);
renderer.Render(visual, null);
}
}
}

34
Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -43,31 +43,27 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SharpDXPackageBinDir)\SharpDX.DXGI.dll</HintPath>
</Reference>
<Reference Include="Splat, Version=1.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Splat">
<HintPath>..\..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Core">
<HintPath>..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Interfaces">
<HintPath>..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.PlatformServices">
<HintPath>..\..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Direct2D1Platform.cs" />
@ -88,11 +84,11 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
</ItemGroup>

6
Windows/Perspex.Direct2D1/Renderer.cs

@ -18,9 +18,6 @@ namespace Perspex.Direct2D1
using Matrix = Perspex.Matrix;
using Point = Perspex.Point;
/// <summary>
/// Renders a <see cref="Canvas"/>.
/// </summary>
public class Renderer : IRenderer
{
/// <summary>
@ -88,7 +85,8 @@ namespace Perspex.Direct2D1
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
public void Render(IVisual visual)
/// <param name="handle">Unused.</param>
public void Render(IVisual visual, IPlatformHandle handle)
{
using (DrawingContext context = new DrawingContext(this.renderTarget, this.DirectWriteFactory))
{

1
Windows/Perspex.Win32/Input/WindowsKeyboardDevice.cs

@ -7,6 +7,7 @@
namespace Perspex.Win32.Input
{
using System.Text;
using Perspex.Controls;
using Perspex.Input;
using Perspex.Win32.Interop;

4
Windows/Perspex.Win32/Input/WindowsMouseDevice.cs

@ -19,7 +19,7 @@ namespace Perspex.Win32.Input
get { return instance; }
}
public Window CurrentWindow
public WindowImpl CurrentWindow
{
get;
set;
@ -35,7 +35,7 @@ namespace Perspex.Win32.Input
{
UnmanagedMethods.POINT p;
UnmanagedMethods.GetCursorPos(out p);
UnmanagedMethods.ScreenToClient(this.CurrentWindow.Handle, ref p);
UnmanagedMethods.ScreenToClient(this.CurrentWindow.Handle.Handle, ref p);
return new Point(p.X, p.Y);
}
}

21
Windows/Perspex.Win32/Interop/UnmanagedMethods.cs

@ -42,6 +42,18 @@ namespace Perspex.Win32.Interop
IDC_HELP = 32651
}
[StructLayout(LayoutKind.Sequential)]
public struct PAINTSTRUCT
{
public IntPtr hdc;
public bool fErase;
public RECT rcPaint;
public bool fRestore;
public bool fIncUpdate;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] rgbReserved;
}
[Flags]
public enum SetWindowPosFlags : uint
{
@ -350,6 +362,9 @@ namespace Perspex.Win32.Interop
WM_DISPATCH_WORK_ITEM = WM_USER,
}
[DllImport("user32.dll")]
public static extern IntPtr BeginPaint(IntPtr hwnd, out PAINTSTRUCT lpPaint);
[DllImport("user32.dll")]
public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);
@ -383,6 +398,12 @@ namespace Perspex.Win32.Interop
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern bool GetUpdateRect(IntPtr hwnd, out RECT lpRect, bool bErase);
[DllImport("user32.dll")]
public static extern bool InvalidateRect(IntPtr hWnd, ref RECT lpRect, bool bErase);
[DllImport("user32.dll")]
public static extern bool KillTimer(IntPtr hWnd, IntPtr uIDEvent);

51
Windows/Perspex.Win32/Perspex.Win32.csproj

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -30,42 +30,37 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Splat, Version=1.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Splat">
<HintPath>..\..\packages\Splat.1.5.1\lib\Net45\Splat.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Core">
<HintPath>..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<Reference Include="System.Reactive.Interfaces">
<HintPath>..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<Reference Include="System.Reactive.Linq">
<HintPath>..\..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<Reference Include="System.Reactive.PlatformServices">
<HintPath>..\..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Input\KeyInterop.cs" />
<Compile Include="Input\WindowsKeyboardDevice.cs" />
<Compile Include="Input\WindowsMouseDevice.cs" />
<Compile Include="Interop\UnmanagedMethods.cs" />
<Compile Include="Window.cs" />
<Compile Include="WindowImpl.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Win32Platform.cs" />
</ItemGroup>
@ -75,35 +70,35 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Perspex.Base\Perspex.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Perspex.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Controls\Perspex.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Perspex.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Diagnostics\Perspex.Diagnostics.csproj">
<Project>{7062ae20-5dcc-4442-9645-8195bdece63e}</Project>
<Project>{7062AE20-5DCC-4442-9645-8195BDECE63E}</Project>
<Name>Perspex.Diagnostics</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Input\Perspex.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Perspex.Input</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Interactivity\Perspex.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
<Name>Perspex.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Layout\Perspex.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
<Name>Perspex.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.SceneGraph\Perspex.SceneGraph.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
<Name>Perspex.SceneGraph</Name>
</ProjectReference>
<ProjectReference Include="..\..\Perspex.Styling\Perspex.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Perspex.Styling</Name>
</ProjectReference>
</ItemGroup>

8
Windows/Perspex.Win32/Win32Platform.cs

@ -7,6 +7,7 @@
namespace Perspex.Win32
{
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Threading;
using System.Threading.Tasks;
@ -21,9 +22,12 @@ namespace Perspex.Win32
{
private static Win32Platform instance = new Win32Platform();
private List<Delegate> delegates = new List<Delegate>();
public static void Initialize()
{
var locator = Locator.CurrentMutable;
locator.Register(() => new WindowImpl(), typeof(IWindowImpl));
locator.Register(() => WindowsKeyboardDevice.Instance, typeof(IKeyboardDevice));
locator.Register(() => instance, typeof(IPlatformThreadingInterface));
}
@ -47,8 +51,12 @@ namespace Perspex.Win32
(uint)interval.TotalMilliseconds,
timerDelegate);
// Prevent timerDelegate being garbage collected.
this.delegates.Add(timerDelegate);
return Disposable.Create(() =>
{
this.delegates.Remove(timerDelegate);
UnmanagedMethods.KillTimer(IntPtr.Zero, handle);
});
}

293
Windows/Perspex.Win32/Window.cs

@ -1,293 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="Window.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Win32
{
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Reactive.Linq;
using System.Runtime.InteropServices;
using Perspex.Controls;
using Perspex.Controls.Presenters;
using Perspex.Diagnostics;
using Perspex.Input;
using Perspex.Input.Raw;
using Perspex.Layout;
using Perspex.Platform;
using Perspex.Rendering;
using Perspex.Threading;
using Perspex.Win32.Input;
using Perspex.Win32.Interop;
using Splat;
public class Window : ContentControl, ILayoutRoot, IRenderRoot, ICloseable
{
public static readonly PerspexProperty<string> TitleProperty = PerspexProperty.Register<Window, string>("Title");
private UnmanagedMethods.WndProc wndProcDelegate;
private string className;
private Dispatcher dispatcher;
private IRenderer renderer;
private IInputManager inputManager;
public Window()
{
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>();
this.CreateWindow();
Size clientSize = this.ClientSize;
this.dispatcher = Dispatcher.UIThread;
this.LayoutManager = new LayoutManager(this);
this.RenderManager = new RenderManager();
this.renderer = factory.CreateRenderer(this.Handle, (int)clientSize.Width, (int)clientSize.Height);
this.inputManager = Locator.Current.GetService<IInputManager>();
this.Template = ControlTemplate.Create<Window>(this.DefaultTemplate);
this.LayoutManager.LayoutNeeded.Subscribe(x =>
{
this.dispatcher.InvokeAsync(
() =>
{
this.LayoutManager.ExecuteLayoutPass();
this.renderer.Render(this);
this.RenderManager.RenderFinished();
},
DispatcherPriority.Render);
});
this.GetObservable(TitleProperty).Subscribe(s => UnmanagedMethods.SetWindowText(Handle, s));
this.RenderManager.RenderNeeded
.Where(_ => !this.LayoutManager.LayoutQueued)
.Subscribe(x =>
{
this.dispatcher.InvokeAsync(
() =>
{
if (!this.LayoutManager.LayoutQueued)
{
this.renderer.Render(this);
this.RenderManager.RenderFinished();
}
},
DispatcherPriority.Render);
});
}
public event EventHandler Activated;
public event EventHandler Closed;
public string Title
{
get { return this.GetValue(TitleProperty); }
set { this.SetValue(TitleProperty, value); }
}
public Size ClientSize
{
get
{
UnmanagedMethods.RECT rect;
UnmanagedMethods.GetClientRect(this.Handle, out rect);
return new Size(rect.right, rect.bottom);
}
}
public IntPtr Handle
{
get;
private set;
}
public ILayoutManager LayoutManager
{
get;
private set;
}
public IRenderManager RenderManager
{
get;
private set;
}
public void Show()
{
UnmanagedMethods.ShowWindow(this.Handle, 1);
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
if (e.Key == Key.F12)
{
Window window = new Window
{
Content = new DevTools
{
Root = this,
},
};
window.Show();
}
}
private Control DefaultTemplate(Window c)
{
Border border = new Border();
border.Background = new Perspex.Media.SolidColorBrush(0xffffffff);
ContentPresenter contentPresenter = new ContentPresenter();
contentPresenter.Bind(
ContentPresenter.ContentProperty,
this.GetObservable(Window.ContentProperty),
BindingPriority.Style);
border.Content = contentPresenter;
return border;
}
private void CreateWindow()
{
// Ensure that the delegate doesn't get garbage collected by storing it as a field.
this.wndProcDelegate = new UnmanagedMethods.WndProc(this.WndProc);
this.className = Guid.NewGuid().ToString();
UnmanagedMethods.WNDCLASSEX wndClassEx = new UnmanagedMethods.WNDCLASSEX
{
cbSize = Marshal.SizeOf(typeof(UnmanagedMethods.WNDCLASSEX)),
style = 0,
lpfnWndProc = this.wndProcDelegate,
hInstance = Marshal.GetHINSTANCE(this.GetType().Module),
hCursor = UnmanagedMethods.LoadCursor(IntPtr.Zero, (int)UnmanagedMethods.Cursor.IDC_ARROW),
hbrBackground = (IntPtr)5,
lpszClassName = this.className,
};
System.Diagnostics.Debug.WriteLine("Registered class " + this.className);
ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx);
if (atom == 0)
{
throw new Win32Exception();
}
this.Handle = UnmanagedMethods.CreateWindowEx(
0,
atom,
null,
(int)UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW,
UnmanagedMethods.CW_USEDEFAULT,
UnmanagedMethods.CW_USEDEFAULT,
UnmanagedMethods.CW_USEDEFAULT,
UnmanagedMethods.CW_USEDEFAULT,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
if (this.Handle == IntPtr.Zero)
{
throw new Win32Exception();
}
}
private void OnActivated()
{
WindowsKeyboardDevice.Instance.WindowActivated(this);
if (this.Activated != null)
{
this.Activated(this, EventArgs.Empty);
}
}
private void OnResized(int width, int height)
{
this.renderer.Resize(width, height);
this.LayoutManager.ExecuteLayoutPass();
this.renderer.Render(this);
this.RenderManager.RenderFinished();
}
private void OnClosed()
{
if (this.Closed != null)
{
this.Closed(this, EventArgs.Empty);
}
}
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Using Win32 naming for consistency.")]
private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
RawInputEventArgs e = null;
WindowsMouseDevice.Instance.CurrentWindow = this;
switch ((UnmanagedMethods.WindowsMessage)msg)
{
case UnmanagedMethods.WindowsMessage.WM_ACTIVATE:
this.OnActivated();
break;
case UnmanagedMethods.WindowsMessage.WM_DESTROY:
this.OnClosed();
break;
case UnmanagedMethods.WindowsMessage.WM_KEYDOWN:
WindowsKeyboardDevice.Instance.UpdateKeyStates();
e = new RawKeyEventArgs(
WindowsKeyboardDevice.Instance,
RawKeyEventType.KeyDown,
KeyInterop.KeyFromVirtualKey((int)wParam),
WindowsKeyboardDevice.Instance.StringFromVirtualKey((uint)wParam));
break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN:
e = new RawMouseEventArgs(
WindowsMouseDevice.Instance,
this,
RawMouseEventType.LeftButtonDown,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP:
e = new RawMouseEventArgs(
WindowsMouseDevice.Instance,
this,
RawMouseEventType.LeftButtonUp,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break;
case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE:
e = new RawMouseEventArgs(
WindowsMouseDevice.Instance,
this,
RawMouseEventType.Move,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break;
case UnmanagedMethods.WindowsMessage.WM_SIZE:
this.OnResized((int)lParam & 0xffff, (int)lParam >> 16);
return IntPtr.Zero;
}
if (e != null)
{
this.inputManager.Process(e);
}
return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam);
}
}
}

212
Windows/Perspex.Win32/WindowImpl.cs

@ -0,0 +1,212 @@
// -----------------------------------------------------------------------
// <copyright file="WindowImpl.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Win32
{
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Perspex.Controls;
using Perspex.Input.Raw;
using Perspex.Platform;
using Perspex.Win32.Input;
using Perspex.Win32.Interop;
public class WindowImpl : IWindowImpl
{
private UnmanagedMethods.WndProc wndProcDelegate;
private string className;
private IntPtr hwnd;
private Window owner;
public WindowImpl()
{
this.CreateWindow();
}
public Action Activated { get; set; }
public Action Closed { get; set; }
public Action<RawInputEventArgs> Input { get; set; }
public Action<Rect, IPlatformHandle> Paint { get; set; }
public Action<Size> Resized { get; set; }
public Size ClientSize
{
get
{
UnmanagedMethods.RECT rect;
UnmanagedMethods.GetClientRect(this.hwnd, out rect);
return new Size(rect.right, rect.bottom);
}
}
public IPlatformHandle Handle
{
get;
private set;
}
public void Invalidate(Rect rect)
{
this.Paint(rect, this.Handle);
//var r = new UnmanagedMethods.RECT
//{
// left = (int)rect.X,
// top = (int)rect.Y,
// right = (int)rect.Right,
// bottom = (int)rect.Bottom,
//};
//UnmanagedMethods.InvalidateRect(this.hwnd, ref r, false);
}
public void SetOwner(Window owner)
{
this.owner = owner;
}
public void SetTitle(string title)
{
UnmanagedMethods.SetWindowText(this.hwnd, title);
}
public void Show()
{
UnmanagedMethods.ShowWindow(this.hwnd, 1);
}
private void CreateWindow()
{
// Ensure that the delegate doesn't get garbage collected by storing it as a field.
this.wndProcDelegate = new UnmanagedMethods.WndProc(this.WndProc);
this.className = Guid.NewGuid().ToString();
UnmanagedMethods.WNDCLASSEX wndClassEx = new UnmanagedMethods.WNDCLASSEX
{
cbSize = Marshal.SizeOf(typeof(UnmanagedMethods.WNDCLASSEX)),
style = 0,
lpfnWndProc = this.wndProcDelegate,
hInstance = Marshal.GetHINSTANCE(this.GetType().Module),
hCursor = UnmanagedMethods.LoadCursor(IntPtr.Zero, (int)UnmanagedMethods.Cursor.IDC_ARROW),
hbrBackground = (IntPtr)5,
lpszClassName = this.className,
};
System.Diagnostics.Debug.WriteLine("Registered class " + this.className);
ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx);
if (atom == 0)
{
throw new Win32Exception();
}
this.hwnd = UnmanagedMethods.CreateWindowEx(
0,
atom,
null,
(int)UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW,
UnmanagedMethods.CW_USEDEFAULT,
UnmanagedMethods.CW_USEDEFAULT,
UnmanagedMethods.CW_USEDEFAULT,
UnmanagedMethods.CW_USEDEFAULT,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
if (this.hwnd == IntPtr.Zero)
{
throw new Win32Exception();
}
this.Handle = new PlatformHandle(this.hwnd, "HWND");
}
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Using Win32 naming for consistency.")]
private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
RawInputEventArgs e = null;
WindowsMouseDevice.Instance.CurrentWindow = this;
switch ((UnmanagedMethods.WindowsMessage)msg)
{
case UnmanagedMethods.WindowsMessage.WM_ACTIVATE:
this.Activated();
break;
case UnmanagedMethods.WindowsMessage.WM_DESTROY:
this.Closed();
break;
case UnmanagedMethods.WindowsMessage.WM_KEYDOWN:
WindowsKeyboardDevice.Instance.UpdateKeyStates();
e = new RawKeyEventArgs(
WindowsKeyboardDevice.Instance,
RawKeyEventType.KeyDown,
KeyInterop.KeyFromVirtualKey((int)wParam),
WindowsKeyboardDevice.Instance.StringFromVirtualKey((uint)wParam));
break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN:
e = new RawMouseEventArgs(
WindowsMouseDevice.Instance,
this.owner,
RawMouseEventType.LeftButtonDown,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP:
e = new RawMouseEventArgs(
WindowsMouseDevice.Instance,
this.owner,
RawMouseEventType.LeftButtonUp,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break;
case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE:
e = new RawMouseEventArgs(
WindowsMouseDevice.Instance,
this.owner,
RawMouseEventType.Move,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break;
// TODO: For some reason WM_PAINT getting called continuously - investigate.
//case UnmanagedMethods.WindowsMessage.WM_PAINT:
// UnmanagedMethods.RECT r;
// UnmanagedMethods.GetUpdateRect(this.hwnd, out r, false);
// this.Paint(new Rect(r.left, r.top, r.right - r.left, r.bottom - r.top));
// return IntPtr.Zero;
case UnmanagedMethods.WindowsMessage.WM_SIZE:
if (this.Resized != null)
{
this.Resized(new Size((int)lParam & 0xffff, (int)lParam >> 16));
}
return IntPtr.Zero;
}
if (e != null && this.Input != null)
{
this.Input(e);
}
return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam);
}
}
}
Loading…
Cancel
Save