Browse Source

Getting something drawn now.

pull/10/head
Steven Kirk 12 years ago
parent
commit
cbbef72f9b
  1. 27
      Cairo/Perspex.Cairo/Media/DrawingContext.cs
  2. 3
      Cairo/Perspex.Cairo/Perspex.Cairo.csproj
  3. 22
      Cairo/Perspex.Cairo/Renderer.cs
  4. 18
      Gtk/Perspex.Gtk/GtkExtensions.cs
  5. 1
      Gtk/Perspex.Gtk/Perspex.Gtk.csproj
  6. 30
      Gtk/Perspex.Gtk/WindowImpl.cs
  7. 16
      Perspex.Controls/Platform/IWindowImpl.cs
  8. 35
      Perspex.Controls/Window.cs
  9. 3
      Perspex.SceneGraph/Platform/IRenderer.cs
  10. 4
      TestApplication/TestApplication-Mono.csproj
  11. 2
      Windows/Perspex.Direct2D1/Media/Imaging/RenderTargetBitmapImpl.cs
  12. 3
      Windows/Perspex.Direct2D1/Renderer.cs
  13. 6
      Windows/Perspex.Win32/Interop/UnmanagedMethods.cs
  14. 54
      Windows/Perspex.Win32/WindowImpl.cs

27
Cairo/Perspex.Cairo/Media/DrawingContext.cs

@ -24,27 +24,54 @@ namespace Perspex.Cairo.Media
/// </summary>
private Context context;
/// <summary>
/// The cairo surface.
/// </summary>
private Surface surface;
/// <summary>
/// Initializes a new instance of the <see cref="DrawingContext"/> class.
/// </summary>
/// <param name="surface">The target surface.</param>
public DrawingContext(Surface surface)
{
this.surface = surface;
this.context = new Context(surface);
}
/// <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);
}
public Matrix CurrentTransform
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
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)

3
Cairo/Perspex.Cairo/Perspex.Cairo.csproj

@ -30,6 +30,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL" />
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL" />
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL" />
<Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL">
<Package>gtk-sharp-2.0</Package>
</Reference>

22
Cairo/Perspex.Cairo/Renderer.cs

@ -18,11 +18,6 @@ namespace Perspex.Cairo
/// </summary>
public class Renderer : IRenderer
{
/// <summary>
/// The handle of the window to draw to.
/// </summary>
private IPlatformHandle handle;
/// <summary>
/// Initializes a new instance of the <see cref="Renderer"/> class.
/// </summary>
@ -31,17 +26,16 @@ namespace Perspex.Cairo
/// <param name="height">The height of the window.</param>
public Renderer(IPlatformHandle handle, double width, double height)
{
this.handle = handle;
}
/// <summary>
/// Renders the specified visual.
/// </summary>
/// <param name="visual">The visual to render.</param>
public void Render(IVisual visual)
/// <param name="handle">A handle to the drawable.</param>
public void Render(IVisual visual, IPlatformHandle handle)
{
using (var surface = CreateSurface(this.handle))
using (DrawingContext context = new DrawingContext(surface))
using (DrawingContext context = CreateContext(handle))
{
this.Render(visual, context);
}
@ -54,7 +48,7 @@ namespace Perspex.Cairo
/// <param name="height">The new height.</param>
public void Resize(int width, int height)
{
// Don't need to do anything here as we create a new Win32Surface on each render.
// Don't need to do anything here.
}
[DllImport("user32.dll")]
@ -65,14 +59,16 @@ namespace Perspex.Cairo
/// </summary>
/// <param name="handle">The platform-specific handle.</param>
/// <returns>A surface.</returns>
private static Surface CreateSurface(IPlatformHandle handle)
private static DrawingContext CreateContext(IPlatformHandle handle)
{
switch (handle.HandleDescriptor)
{
case "HWND":
return new Win32Surface(GetDC(handle.Handle));
return new DrawingContext(new Win32Surface(GetDC(handle.Handle)));
case "HDC":
return new Win32Surface(handle.Handle);
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",

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);
}
}
}

1
Gtk/Perspex.Gtk/Perspex.Gtk.csproj

@ -55,6 +55,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="GtkExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GtkPlatform.cs" />
<Compile Include="WindowImpl.cs" />

30
Gtk/Perspex.Gtk/WindowImpl.cs

@ -21,11 +21,11 @@ namespace Perspex.Gtk
public WindowImpl ()
{
this.inner = new Gtk.Window(Gtk.WindowType.Toplevel);
// TODO: Use ?. operator on these when it's available.
this.inner.FocusActivated += (s, a) => this.Activated.Invoke(this, EventArgs.Empty);
this.inner.Destroyed += (s, a) => this.Closed.Invoke(this, EventArgs.Empty);
this.inner.ConfigureEvent += (s, a) => this.Resized.Invoke(this, new RawSizeEventArgs(a.Event.Width, a.Event.Height));
this.inner.DefaultSize = new Gdk.Size(640, 480);
this.inner.FocusActivated += (s, a) => this.Activated();
this.inner.Destroyed += (s, a) => this.Closed();
this.inner.ConfigureEvent += (s, a) => this.Resized(new Size(a.Event.Width, a.Event.Height));
this.inner.ExposeEvent += (s, a) => this.Paint(a.Event.Area.ToPerspex(), GetHandle(a.Event.Window));
this.Handle = new PlatformHandle(this.inner.Handle, "GtkWindow");
}
@ -47,13 +47,20 @@ namespace Perspex.Gtk
private set;
}
public event EventHandler Activated;
public Action Activated { get; set; }
public Action Closed { get; set; }
public event EventHandler Closed;
public Action<RawInputEventArgs> Input { get; set; }
public event EventHandler<RawInputEventArgs> Input;
public Action<Rect, IPlatformHandle> Paint { get; set; }
public event EventHandler<RawSizeEventArgs> Resized;
public Action<Size> Resized { get; set; }
public void Invalidate(Rect rect)
{
this.inner.QueueDraw();
}
public void SetOwner(Window window)
{
@ -69,5 +76,10 @@ namespace Perspex.Gtk
{
this.inner.Show();
}
private IPlatformHandle GetHandle(Gdk.Window window)
{
return new PlatformHandle(window.Handle, "GdkWindow");
}
}
}

16
Perspex.Controls/Platform/IWindowImpl.cs

@ -12,17 +12,21 @@ namespace Perspex.Platform
public interface IWindowImpl
{
event EventHandler Activated;
Size ClientSize { get; }
event EventHandler Closed;
IPlatformHandle Handle { get; }
event EventHandler<RawInputEventArgs> Input;
Action Activated { get; set; }
event EventHandler<RawSizeEventArgs> Resized;
Action Closed { get; set; }
Size ClientSize { get; }
Action<RawInputEventArgs> Input { get; set; }
IPlatformHandle Handle { get; }
Action<Rect, IPlatformHandle> Paint { get; set; }
Action<Size> Resized { get; set; }
void Invalidate(Rect rect);
void SetTitle(string title);

35
Perspex.Controls/Window.cs

@ -63,10 +63,11 @@ namespace Perspex.Controls
}
this.impl.SetOwner(this);
this.impl.Activated += this.HandleActivated;
this.impl.Closed += this.HandleClosed;
this.impl.Input += this.HandleInput;
this.impl.Resized += this.HandleResized;
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;
@ -114,7 +115,7 @@ namespace Perspex.Controls
this.LayoutPass();
}
private void HandleActivated(object sender, EventArgs e)
private void HandleActivated()
{
if (this.Activated != null)
{
@ -122,7 +123,7 @@ namespace Perspex.Controls
}
}
private void HandleClosed(object sender, EventArgs e)
private void HandleClosed()
{
if (this.Closed != null)
{
@ -130,7 +131,7 @@ namespace Perspex.Controls
}
}
private void HandleInput(object sender, RawInputEventArgs e)
private void HandleInput(RawInputEventArgs e)
{
this.inputManager.Process(e);
}
@ -145,27 +146,31 @@ namespace Perspex.Controls
this.dispatcher.InvokeAsync(this.RenderVisualTree, DispatcherPriority.Render);
}
private void HandleResized(object sender, RawSizeEventArgs e)
private void HandlePaint(Rect rect, IPlatformHandle handle)
{
this.ClientSize = e.Size;
this.renderer.Resize((int)e.Size.Width, (int)e.Size.Height);
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.RenderVisualTree();
this.impl.Invalidate(new Rect(this.ClientSize));
}
private void LayoutPass()
{
this.LayoutManager.ExecuteLayoutPass();
this.renderer.Render(this);
this.RenderManager.RenderFinished();
this.impl.Invalidate(new Rect(this.ClientSize));
}
private void RenderVisualTree()
{
if (!this.LayoutManager.LayoutQueued)
{
this.renderer.Render(this);
this.RenderManager.RenderFinished();
this.impl.Invalidate(new Rect(this.ClientSize));
}
}
}

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.

4
TestApplication/TestApplication-Mono.csproj

@ -17,7 +17,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<OutputPath>bin\Debug-Mono\</OutputPath>
<DefineConstants>TRACE;DEBUG;PERSPEX_CAIRO;PERSPEX_GTK</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@ -27,7 +27,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<OutputPath>bin\Release-Mono\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>

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);
}
}
}

3
Windows/Perspex.Direct2D1/Renderer.cs

@ -85,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))
{

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

@ -398,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);

54
Windows/Perspex.Win32/WindowImpl.cs

@ -9,20 +9,12 @@ 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 WindowImpl : IWindowImpl
{
@ -39,13 +31,15 @@ namespace Perspex.Win32
this.CreateWindow();
}
public event EventHandler Activated;
public Action Activated { get; set; }
public event EventHandler Closed;
public Action Closed { get; set; }
public event EventHandler<RawInputEventArgs> Input;
public Action<RawInputEventArgs> Input { get; set; }
public event EventHandler<RawSizeEventArgs> Resized;
public Action<Rect, IPlatformHandle> Paint { get; set; }
public Action<Size> Resized { get; set; }
public Size ClientSize
{
@ -63,6 +57,20 @@ namespace Perspex.Win32
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;
@ -137,17 +145,11 @@ namespace Perspex.Win32
switch ((UnmanagedMethods.WindowsMessage)msg)
{
case UnmanagedMethods.WindowsMessage.WM_ACTIVATE:
if (this.Activated != null)
{
this.Activated(this, EventArgs.Empty);
}
this.Activated();
break;
case UnmanagedMethods.WindowsMessage.WM_DESTROY:
if (this.Closed != null)
{
this.Closed(this, EventArgs.Empty);
}
this.Closed();
break;
case UnmanagedMethods.WindowsMessage.WM_KEYDOWN:
@ -183,17 +185,25 @@ namespace Perspex.Win32
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(this, new RawSizeEventArgs((int)lParam & 0xffff, (int)lParam >> 16));
this.Resized(new Size((int)lParam & 0xffff, (int)lParam >> 16));
}
return IntPtr.Zero;
}
if (e != null && this.Input != null)
{
this.Input(this, e);
this.Input(e);
}
return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam);

Loading…
Cancel
Save