69 changed files with 2381 additions and 480 deletions
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -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)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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")] |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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 |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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 () |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,12 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Perspex.Gtk |
||||
|
{ |
||||
|
public class MyClass |
||||
|
{ |
||||
|
public MyClass () |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -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> |
||||
@ -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("")]
|
||||
|
|
||||
@ -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"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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> |
||||
@ -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 |
||||
@ -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> |
||||
@ -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; } |
||||
|
} |
||||
|
} |
||||
@ -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; } |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
@ -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)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; } |
||||
|
} |
||||
|
} |
||||
@ -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], |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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…
Reference in new issue